Merge branch 'master' into multi-context-windows-merge-master

This commit is contained in:
Doug Binks 2024-10-09 18:03:07 +02:00
commit 587025f9cb
34 changed files with 512 additions and 274 deletions

View File

@ -54,7 +54,7 @@ jobs:
timeout-minutes: 4 timeout-minutes: 4
env: env:
CFLAGS: -Werror CFLAGS: -Werror
MACOSX_DEPLOYMENT_TARGET: 10.8 MACOSX_DEPLOYMENT_TARGET: 10.11
CMAKE_OSX_ARCHITECTURES: x86_64;arm64 CMAKE_OSX_ARCHITECTURES: x86_64;arm64
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@ -33,6 +33,7 @@ video tutorials.
- Nicolas Caramelli - Nicolas Caramelli
- David Carlier - David Carlier
- Arturo Castro - Arturo Castro
- Jose Luis Cercós Pita
- Chi-kwan Chan - Chi-kwan Chan
- Victor Chernyakin - Victor Chernyakin
- TheChocolateOre - TheChocolateOre
@ -48,6 +49,7 @@ video tutorials.
- Andrew Corrigan - Andrew Corrigan
- Bailey Cosier - Bailey Cosier
- Noel Cower - Noel Cower
- James Cowgill
- CuriouserThing - CuriouserThing
- Bill Currie - Bill Currie
- Jason Daly - Jason Daly

View File

@ -79,7 +79,7 @@ more information.
## System requirements ## System requirements
GLFW supports Windows XP and later and macOS 10.8 and later. Linux and other GLFW supports Windows XP and later and macOS 10.11 and later. Linux and other
Unix-like systems running the X Window System are supported even without Unix-like systems running the X Window System are supported even without
a desktop environment or modern extensions, although some features require a desktop environment or modern extensions, although some features require
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3. a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
@ -124,6 +124,17 @@ information on what to include when reporting a bug.
- Added OpenGL and OpenGL ES user contexts for multiple window contexts via - Added OpenGL and OpenGL ES user contexts for multiple window contexts via
`GLFWusercontext`, `glfwCreateUserContext`, `glfwDestroyUserContext`, `GLFWusercontext`, `glfwCreateUserContext`, `glfwDestroyUserContext`,
`glfwMakeUserContextCurrent`, `glfwGetCurrentUserContext` (#1687,#1870) `glfwMakeUserContextCurrent`, `glfwGetCurrentUserContext` (#1687,#1870)
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
the limit of the mouse button tokens to be reported (#2423)
- [Cocoa] Added `QuartzCore` framework as link-time dependency
- [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506)
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed
- [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517)
- [Wayland] Bugfix: A drag entering a non-GLFW surface could cause a segfault
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
`GLFW_NATIVE_CONTEXT_API` (#2518)
## Contact ## Contact

View File

@ -390,8 +390,8 @@ If you are using the dynamic library version of GLFW, add it to the project
dependencies. dependencies.
If you are using the static library version of GLFW, add it and the Cocoa, If you are using the static library version of GLFW, add it and the Cocoa,
OpenGL and IOKit frameworks to the project as dependencies. They can all be OpenGL, IOKit and QuartzCore frameworks to the project as dependencies. They
found in `/System/Library/Frameworks`. can all be found in `/System/Library/Frameworks`.
### With command-line or makefile on macOS {#build_link_osx} ### With command-line or makefile on macOS {#build_link_osx}
@ -405,7 +405,7 @@ command-line yourself using the `-l` and `-framework` switches.
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do: If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
```sh ```sh
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework QuartzCore
``` ```
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3` If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`

View File

@ -242,24 +242,27 @@ extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
## OpenGL on macOS {#compat_osx} ## OpenGL on macOS {#compat_osx}
Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then macOS (as of version 14) still provides OpenGL but it has been deprecated by
only forward-compatible, core profile contexts are supported. Support for Apple. While the API is still available, it is poorly maintained and frequently
OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible, develops new issues. On modern systems, OpenGL is implemented on top of Metal
core profile contexts. There is also still no mechanism for requesting debug and is not fully thread-safe.
contexts or no-error contexts. Versions of Mac OS X earlier than 10.7 support
at most OpenGL version 2.1.
Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and macOS does not support OpenGL stereo rendering. If the `GLFW_STEREO` hint is
`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if set to true, OpenGL context creation will always fail.
given version 3.0 or 3.1. The `GLFW_OPENGL_PROFILE` hint must be set to
`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The
`GLFW_CONTEXT_DEBUG` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and macOS only supports OpenGL core profile contexts that are forward-compatible,
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, but the `GLFW_OPENGL_FORWARD_COMPAT` hint is ignored since GLFW 3.4. Even if
setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to this hint is set to false (the default), a forward-compatible context will be
a non-default value will cause @ref glfwCreateWindow to fail and the returned if available.
`GLFW_CONTEXT_DEBUG` hint is ignored.
macOS does not support OpenGL debug contexts, no-error contexts or robustness.
The `GLFW_CONTEXT_DEBUG`, `GLFW_CONTEXT_NO_ERROR` and `GLFW_CONTEXT_ROBUSTNESS`
hints will be ignored and a context without these features will be returned.
macOS does not flush OpenGL contexts when they are made non-current. The
`GLFW_CONTEXT_RELEASE_BEHAVIOR` hint is ignored and the release behavior will
always be the equivalent of `GLFW_RELEASE_BEHAVIOR_NONE`. If you need a context
to be flushed, call `glFlush` before making it non-current.
## Vulkan loader and API {#compat_vulkan} ## Vulkan loader and API {#compat_vulkan}

View File

@ -492,6 +492,20 @@ a mouse button callback.
glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetMouseButtonCallback(window, mouse_button_callback);
``` ```
@anchor GLFW_UNLIMITED_MOUSE_BUTTONS
To handle all mouse buttons in the callback, instead of only ones with associated
[button tokens](@ref buttons), set the @ref GLFW_UNLIMITED_MOUSE_BUTTONS
input mode.
```c
glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
```
When this input mode is enabled, GLFW doesn't limit the reported mouse buttons
to only those that have an associated button token, for compatibility with
earlier versions of GLFW, which never reported any buttons over
@ref GLFW_MOUSE_BUTTON_LAST, on which users could have relied on.
The callback function receives the [mouse button](@ref buttons), button action The callback function receives the [mouse button](@ref buttons), button action
and [modifier bits](@ref mods). and [modifier bits](@ref mods).
@ -503,11 +517,16 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
} }
``` ```
The mouse button is an integer that can be one of the
[mouse button tokens](@ref buttons) or, if the
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set, any other positive value.
The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
The last reported state for every [supported mouse button](@ref buttons) is also The last reported state for every [mouse button token](@ref buttons) is also
saved in per-window state arrays that can be polled with @ref saved in per-window state arrays that can be polled with @ref
glfwGetMouseButton. glfwGetMouseButton. This is not effected by the @ref GLFW_UNLIMITED_MOUSE_BUTTONS
input mode.
```c ```c
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
@ -540,7 +559,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
otherwise it will remain `GLFW_PRESS`. otherwise it will remain `GLFW_PRESS`.
The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
[supported mouse button](@ref buttons). [mouse button token](@ref buttons).
### Scroll input {#scrolling} ### Scroll input {#scrolling}

View File

@ -14,6 +14,15 @@ destroyed using @ref glfwDestroyUserContext, and managed with
@ref glfwMakeUserContextCurrent and @ref glfwGetCurrentUserContext. @ref glfwMakeUserContextCurrent and @ref glfwGetCurrentUserContext.
For more information see the [user context](@ref context_user) documentation. For more information see the [user context](@ref context_user) documentation.
### Unlimited mouse buttons {#unlimited_mouse_buttons}
GLFW now has an input mode which allows an unlimited number of mouse buttons to
be reported by the mouse buttton callback, rather than just the associated
[mouse button tokens](@ref buttons). This allows using mouse buttons with
values over 8. For compatibility with older versions, the
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of
this.
## Caveats {#caveats} ## Caveats {#caveats}
## Deprecations {#deprecations} ## Deprecations {#deprecations}
@ -28,6 +37,8 @@ For more information see the [user context](@ref context_user) documentation.
### New constants {#new_constants} ### New constants {#new_constants}
- @ref GLFW_UNLIMITED_MOUSE_BUTTONS
## Release notes for earlier versions {#news_archive} ## Release notes for earlier versions {#news_archive}
- [Release notes for 3.4](https://www.glfw.org/docs/3.4/news.html) - [Release notes for 3.4](https://www.glfw.org/docs/3.4/news.html)

View File

@ -1154,6 +1154,7 @@ extern "C" {
#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
#define GLFW_LOCK_KEY_MODS 0x00033004 #define GLFW_LOCK_KEY_MODS 0x00033004
#define GLFW_RAW_MOUSE_MOTION 0x00033005 #define GLFW_RAW_MOUSE_MOTION 0x00033005
#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006
#define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_NORMAL 0x00034001
#define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_HIDDEN 0x00034002
@ -3194,8 +3195,8 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* *
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
* *
* @remark @macos On OS X 10.10 and later the window frame will not be rendered * @remark @macos The window frame will not be rendered at full resolution on
* at full resolution on Retina displays unless the * Retina displays unless the
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
* application bundle's `Info.plist`. For more information, see * application bundle's `Info.plist`. For more information, see
@ -4688,8 +4689,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* *
* This function sets an input mode option for the specified window. The mode * This function sets an input mode option for the specified window. The mode
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS
* @ref GLFW_RAW_MOUSE_MOTION. * @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS.
* *
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
* modes: * modes:
@ -4729,6 +4730,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref
* glfwRawMouseMotionSupported to check for support. * glfwRawMouseMotionSupported to check for support.
* *
* If the mode is `GLFW_UNLIMITED_MOUSE_BUTTONS`, the value must be either
* `GLFW_TRUE` to disable the mouse button limit when calling the mouse button
* callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback
* to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`.
*
* @param[in] window The window whose input mode to set. * @param[in] window The window whose input mode to set.
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
* `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
@ -4923,8 +4929,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* returns `GLFW_PRESS` the first time you call it for a mouse button that was * returns `GLFW_PRESS` the first time you call it for a mouse button that was
* pressed, even if that mouse button has already been released. * pressed, even if that mouse button has already been released.
* *
* The @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode does not effect the
* limit on buttons which can be polled with this function.
*
* @param[in] window The desired window. * @param[in] window The desired window.
* @param[in] button The desired [mouse button](@ref buttons). * @param[in] button The desired [mouse button token](@ref buttons).
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@ -5300,10 +5309,15 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
* is called when a mouse button is pressed or released. * is called when a mouse button is pressed or released.
* *
* When a window loses input focus, it will generate synthetic mouse button * When a window loses input focus, it will generate synthetic mouse button
* release events for all pressed mouse buttons. You can tell these events * release events for all pressed mouse buttons with associated button tokens.
* from user-generated events by the fact that the synthetic ones are generated * You can tell these events from user-generated events by the fact that the
* after the focus loss event has been processed, i.e. after the * synthetic ones are generated after the focus loss event has been processed,
* [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * i.e. after the [window focus callback](@ref glfwSetWindowFocusCallback) has
* been called.
*
* The reported `button` value can be higher than `GLFW_MOUSE_BUTTON_LAST` if
* the button does not have an associated [button token](@ref buttons) and the
* @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode is set.
* *
* @param[in] window The window whose callback to set. * @param[in] window The window whose callback to set.
* @param[in] callback The new callback, or `NULL` to remove the currently set * @param[in] callback The new callback, or `NULL` to remove the currently set

View File

@ -151,10 +151,11 @@ endif()
if (GLFW_BUILD_COCOA) if (GLFW_BUILD_COCOA)
target_link_libraries(glfw PRIVATE "-framework Cocoa" target_link_libraries(glfw PRIVATE "-framework Cocoa"
"-framework IOKit" "-framework IOKit"
"-framework CoreFoundation") "-framework CoreFoundation"
"-framework QuartzCore")
set(glfw_PKG_DEPS "") set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation") set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework QuartzCore")
endif() endif()
if (GLFW_BUILD_WAYLAND) if (GLFW_BUILD_WAYLAND)

View File

@ -32,6 +32,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <assert.h>
#include <IOKit/graphics/IOGraphicsLib.h> #include <IOKit/graphics/IOGraphicsLib.h>
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
@ -136,7 +137,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
if (flags & kDisplayModeStretchedFlag) if (flags & kDisplayModeStretchedFlag)
return GLFW_FALSE; return GLFW_FALSE;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 #if MAC_OS_X_VERSION_MAX_ALLOWED == 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
@ -163,7 +164,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
if (result.refreshRate == 0) if (result.refreshRate == 0)
result.refreshRate = (int) round(fallbackRefreshRate); result.refreshRate = (int) round(fallbackRefreshRate);
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 #if MAC_OS_X_VERSION_MAX_ALLOWED == 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
{ {
@ -179,7 +180,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
result.blueBits = 8; result.blueBits = 8;
} }
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100 #if MAC_OS_X_VERSION_MAX_ALLOWED == 101100
CFRelease(format); CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return result; return result;
@ -627,7 +628,6 @@ void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle) GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay); _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -636,6 +636,9 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
return kCGNullDirectDisplay; return kCGNullDirectDisplay;
} }
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->ns.displayID; return monitor->ns.displayID;
} }

View File

@ -28,8 +28,11 @@
#if defined(_GLFW_COCOA) #if defined(_GLFW_COCOA)
#import <QuartzCore/CAMetalLayer.h>
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
#include <assert.h>
// HACK: This enum value is missing from framework headers on OS X 10.11 despite // HACK: This enum value is missing from framework headers on OS X 10.11 despite
// having been (according to documentation) added in Mac OS X 10.7 // having been (according to documentation) added in Mac OS X 10.7
@ -309,7 +312,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidChangeOcclusionState:(NSNotification* )notification - (void)windowDidChangeOcclusionState:(NSNotification* )notification
{ {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
if ([window->ns.object respondsToSelector:@selector(occlusionState)]) if ([window->ns.object respondsToSelector:@selector(occlusionState)])
{ {
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
@ -317,7 +319,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
else else
window->ns.occluded = GLFW_TRUE; window->ns.occluded = GLFW_TRUE;
} }
#endif
} }
@end @end
@ -1949,19 +1950,8 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
{ {
@autoreleasepool { @autoreleasepool {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
// HACK: Dynamically load Core Animation to avoid adding an extra
// dependency for the majority who don't use MoltenVK
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
if (!bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find QuartzCore.framework");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
// NOTE: Create the layer here as makeBackingLayer should not return nil // NOTE: Create the layer here as makeBackingLayer should not return nil
window->ns.layer = [[bundle classNamed:@"CAMetalLayer"] layer]; window->ns.layer = [CAMetalLayer layer];
if (!window->ns.layer) if (!window->ns.layer)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -2026,9 +2016,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
} }
return err; return err;
#else
return VK_ERROR_EXTENSION_NOT_PRESENT;
#endif
} // autoreleasepool } // autoreleasepool
} }
@ -2059,7 +2046,6 @@ _GLFWusercontext* _glfwCreateUserContextCocoa(_GLFWwindow* window)
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle) GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil); _GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -2069,12 +2055,14 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
return nil; return nil;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->ns.object; return window->ns.object;
} }
GLFWAPI id glfwGetCocoaView(GLFWwindow* handle) GLFWAPI id glfwGetCocoaView(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil); _GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -2084,6 +2072,9 @@ GLFWAPI id glfwGetCocoaView(GLFWwindow* handle)
return nil; return nil;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->ns.view; return window->ns.view;
} }

View File

@ -615,11 +615,11 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous; _GLFWwindow* previous;
_GLFW_REQUIRE_INIT();
_glfwPlatformSetTls(&_glfw.usercontextSlot, NULL); _glfwPlatformSetTls(&_glfw.usercontextSlot, NULL);
previous = _glfwPlatformGetTls(&_glfw.contextSlot); previous = _glfwPlatformGetTls(&_glfw.contextSlot);
@ -648,11 +648,11 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle) GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->context.client == GLFW_NO_API) if (window->context.client == GLFW_NO_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, _glfwInputError(GLFW_NO_WINDOW_CONTEXT,

View File

@ -92,7 +92,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
EGLConfig* nativeConfigs; EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount, apiBit; int i, nativeCount, usableCount, apiBit, surfaceTypeBit;
GLFWbool wrongApiAvailable = GLFW_FALSE; GLFWbool wrongApiAvailable = GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
@ -105,6 +105,11 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
else else
apiBit = EGL_OPENGL_BIT; apiBit = EGL_OPENGL_BIT;
if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
surfaceTypeBit = EGL_PBUFFER_BIT;
else
surfaceTypeBit = EGL_WINDOW_BIT;
if (fbconfig->stereo) if (fbconfig->stereo)
{ {
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported"); _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
@ -133,8 +138,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER) if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue; continue;
// Only consider window EGLConfigs if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & surfaceTypeBit))
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue; continue;
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
@ -420,6 +424,8 @@ GLFWbool _glfwInitEGL(void)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface) _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.CreatePbufferSurface = (PFN_eglCreatePbufferSurface)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreatePbufferSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent) _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers) _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
@ -446,6 +452,7 @@ GLFWbool _glfwInitEGL(void)
!_glfw.egl.DestroySurface || !_glfw.egl.DestroySurface ||
!_glfw.egl.DestroyContext || !_glfw.egl.DestroyContext ||
!_glfw.egl.CreateWindowSurface || !_glfw.egl.CreateWindowSurface ||
!_glfw.egl.CreatePbufferSurface ||
!_glfw.egl.MakeCurrent || !_glfw.egl.MakeCurrent ||
!_glfw.egl.SwapBuffers || !_glfw.egl.SwapBuffers ||
!_glfw.egl.SwapInterval || !_glfw.egl.SwapInterval ||
@ -483,6 +490,8 @@ GLFWbool _glfwInitEGL(void)
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions); _glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
_glfw.egl.ANGLE_platform_angle_metal = _glfw.egl.ANGLE_platform_angle_metal =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions); _glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
_glfw.egl.MESA_platform_surfaceless =
_glfwStringInExtensionString("EGL_MESA_platform_surfaceless", extensions);
} }
if (_glfw.egl.EXT_platform_base) if (_glfw.egl.EXT_platform_base)
@ -731,20 +740,36 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
} }
if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
{
int width, height;
_glfw.platform.getFramebufferSize(window, &width, &height);
SET_ATTRIB(EGL_WIDTH, width);
SET_ATTRIB(EGL_HEIGHT, height);
}
SET_ATTRIB(EGL_NONE, EGL_NONE); SET_ATTRIB(EGL_NONE, EGL_NONE);
native = _glfw.platform.getEGLNativeWindow(window); native = _glfw.platform.getEGLNativeWindow(window);
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT if (!_glfw.egl.platform || _glfw.egl.platform == EGL_PLATFORM_ANGLE_ANGLE)
// despite reporting EGL_EXT_platform_base
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
{ {
// HACK: Also use non-platform function for ANGLE, as it does not
// implement eglCreatePlatformWindowSurfaceEXT despite reporting
// support for EGL_EXT_platform_base
window->context.egl.surface = window->context.egl.surface =
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, window->context.egl.config, native, attribs); eglCreateWindowSurface(_glfw.egl.display, window->context.egl.config, native, attribs);
}
else if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
{
// HACK: Use a pbuffer surface as the default framebuffer
window->context.egl.surface =
eglCreatePbufferSurface(_glfw.egl.display, window->context.egl.config, attribs);
} }
else else
{ {
window->context.egl.surface = window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display, window->context.egl.config, native, attribs); eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, window->context.egl.config, native, attribs);
} }
if (window->context.egl.surface == EGL_NO_SURFACE) if (window->context.egl.surface == EGL_NO_SURFACE)
@ -992,27 +1017,39 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_EGL_CONTEXT_API) if (window->context.source != GLFW_EGL_CONTEXT_API)
{
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT; return EGL_NO_CONTEXT;
} }
}
return window->context.egl.handle; return window->context.egl.handle;
} }
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_EGL_CONTEXT_API) if (window->context.source != GLFW_EGL_CONTEXT_API)
{
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE; return EGL_NO_CONTEXT;
}
} }
return window->context.egl.surface; return window->context.egl.surface;

View File

@ -734,7 +734,6 @@ _GLFWusercontext* _glfwCreateUserContextGLX(_GLFWwindow* window)
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -743,6 +742,9 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
return NULL; return NULL;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API) if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -754,7 +756,6 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None); _GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -763,6 +764,9 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return None; return None;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API) if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View File

@ -348,20 +348,22 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
{ {
assert(window != NULL); assert(window != NULL);
assert(button >= 0); assert(button >= 0);
assert(button <= GLFW_MOUSE_BUTTON_LAST);
assert(action == GLFW_PRESS || action == GLFW_RELEASE); assert(action == GLFW_PRESS || action == GLFW_RELEASE);
assert(mods == (mods & GLFW_MOD_MASK)); assert(mods == (mods & GLFW_MOD_MASK));
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) if (button < 0 || (!window->disableMouseButtonLimit && button > GLFW_MOUSE_BUTTON_LAST))
return; return;
if (!window->lockKeyMods) if (!window->lockKeyMods)
mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK); mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
if (button <= GLFW_MOUSE_BUTTON_LAST)
{
if (action == GLFW_RELEASE && window->stickyMouseButtons) if (action == GLFW_RELEASE && window->stickyMouseButtons)
window->mouseButtons[button] = _GLFW_STICK; window->mouseButtons[button] = _GLFW_STICK;
else else
window->mouseButtons[button] = (char) action; window->mouseButtons[button] = (char) action;
}
if (window->callbacks.mouseButton) if (window->callbacks.mouseButton)
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
@ -559,11 +561,11 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
switch (mode) switch (mode)
{ {
case GLFW_CURSOR: case GLFW_CURSOR:
@ -576,6 +578,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->lockKeyMods; return window->lockKeyMods;
case GLFW_RAW_MOUSE_MOTION: case GLFW_RAW_MOUSE_MOTION:
return window->rawMouseMotion; return window->rawMouseMotion;
case GLFW_UNLIMITED_MOUSE_BUTTONS:
return window->disableMouseButtonLimit;
} }
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
@ -584,11 +588,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
switch (mode) switch (mode)
{ {
case GLFW_CURSOR: case GLFW_CURSOR:
@ -683,6 +687,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_glfw.platform.setRawMouseMotion(window, value); _glfw.platform.setRawMouseMotion(window, value);
return; return;
} }
case GLFW_UNLIMITED_MOUSE_BUTTONS:
{
window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
} }
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
@ -734,11 +744,11 @@ GLFWAPI int glfwGetKeyScancode(int key)
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
@ -757,11 +767,11 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button) GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST) if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button); _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);
@ -780,9 +790,6 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos) GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
if (ypos) if (ypos)
@ -790,6 +797,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
if (xpos) if (xpos)
@ -803,11 +813,11 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX || if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX) ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
{ {
@ -897,10 +907,10 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
GLFWAPI void glfwDestroyCursor(GLFWcursor* handle) GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
{ {
_GLFWcursor* cursor = (_GLFWcursor*) handle;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWcursor* cursor = (_GLFWcursor*) handle;
if (cursor == NULL) if (cursor == NULL)
return; return;
@ -932,12 +942,12 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) windowHandle; _GLFWwindow* window = (_GLFWwindow*) windowHandle;
_GLFWcursor* cursor = (_GLFWcursor*) cursorHandle; _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
window->cursor = cursor; window->cursor = cursor;
_glfw.platform.setCursor(window, cursor); _glfw.platform.setCursor(window, cursor);
@ -945,30 +955,33 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun); _GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun);
return cbfun; return cbfun;
} }
GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun); _GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun);
return cbfun; return cbfun;
} }
GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun) GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun); _GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun);
return cbfun; return cbfun;
} }
@ -976,10 +989,11 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
GLFWmousebuttonfun cbfun) GLFWmousebuttonfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun); _GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun);
return cbfun; return cbfun;
} }
@ -987,10 +1001,11 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
GLFWcursorposfun cbfun) GLFWcursorposfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun); _GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun);
return cbfun; return cbfun;
} }
@ -998,10 +1013,11 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
GLFWcursorenterfun cbfun) GLFWcursorenterfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun); _GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun);
return cbfun; return cbfun;
} }
@ -1009,20 +1025,22 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
GLFWscrollfun cbfun) GLFWscrollfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun); _GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun);
return cbfun; return cbfun;
} }
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun); _GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun);
return cbfun; return cbfun;
} }

View File

@ -48,6 +48,8 @@
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
#include "../include/GLFW/glfw3.h" #include "../include/GLFW/glfw3.h"
#include <stdbool.h>
#define _GLFW_INSERT_FIRST 0 #define _GLFW_INSERT_FIRST 0
#define _GLFW_INSERT_LAST 1 #define _GLFW_INSERT_LAST 1
@ -152,8 +154,8 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#define EGL_NO_CONTEXT ((EGLContext) 0) #define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0) #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_PBUFFER_BIT 0x0001 #define EGL_PBUFFER_BIT 0x0001
#define EGL_HEIGHT 0x3056
#define EGL_WIDTH 0x3057 #define EGL_WIDTH 0x3057
#define EGL_HEIGHT 0x3056
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 #define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 #define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
@ -185,6 +187,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450 #define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489 #define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f #define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
#define EGL_PLATFORM_SURFACELESS_MESA 0x31dd
typedef int EGLint; typedef int EGLint;
typedef unsigned int EGLBoolean; typedef unsigned int EGLBoolean;
@ -209,12 +212,12 @@ typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLCon
typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface); typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext); typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLSurface (APIENTRY * PFN_eglCreatePbufferSurface)(EGLDisplay,EGLContext,const EGLint*);
typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (APIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); typedef const char* (APIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*); typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*);
typedef EGLSurface (APIENTRY * PFN_eglCreatePbufferSurface)(EGLDisplay,EGLConfig,const EGLint*);
typedef EGLBoolean (APIENTRY * PFN_eglChooseConfig)(EGLDisplay,EGLint const*,EGLConfig*,EGLint,EGLint*); typedef EGLBoolean (APIENTRY * PFN_eglChooseConfig)(EGLDisplay,EGLint const*,EGLConfig*,EGLint,EGLint*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs #define eglGetConfigs _glfw.egl.GetConfigs
@ -227,6 +230,7 @@ typedef EGLBoolean (APIENTRY * PFN_eglChooseConfig)(EGLDisplay,EGLint const*,EGL
#define eglDestroySurface _glfw.egl.DestroySurface #define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext #define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface #define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglCreatePbufferSurface _glfw.egl.CreatePbufferSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent #define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers #define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval #define eglSwapInterval _glfw.egl.SwapInterval
@ -285,6 +289,7 @@ typedef enum VkStructureType
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType; } VkStructureType;
@ -575,6 +580,7 @@ struct _GLFWwindow
GLFWbool stickyKeys; GLFWbool stickyKeys;
GLFWbool stickyMouseButtons; GLFWbool stickyMouseButtons;
GLFWbool lockKeyMods; GLFWbool lockKeyMods;
GLFWbool disableMouseButtonLimit;
int cursorMode; int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
char keys[GLFW_KEY_LAST + 1]; char keys[GLFW_KEY_LAST + 1];
@ -844,6 +850,7 @@ struct _GLFWlibrary
GLFWbool ANGLE_platform_angle_d3d; GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan; GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal; GLFWbool ANGLE_platform_angle_metal;
GLFWbool MESA_platform_surfaceless;
void* handle; void* handle;
@ -858,12 +865,12 @@ struct _GLFWlibrary
PFN_eglDestroySurface DestroySurface; PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext; PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface; PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglCreatePbufferSurface CreatePbufferSurface;
PFN_eglMakeCurrent MakeCurrent; PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers; PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval; PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString; PFN_eglQueryString QueryString;
PFN_eglGetProcAddress GetProcAddress; PFN_eglGetProcAddress GetProcAddress;
PFN_eglCreatePbufferSurface CreatePbufferSurface;
PFN_eglChooseConfig ChooseConfig; PFN_eglChooseConfig ChooseConfig;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT; PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
@ -895,6 +902,7 @@ struct _GLFWlibrary
GLFWbool KHR_xlib_surface; GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface; GLFWbool KHR_xcb_surface;
GLFWbool KHR_wayland_surface; GLFWbool KHR_wayland_surface;
GLFWbool EXT_headless_surface;
} vk; } vk;
struct { struct {

View File

@ -325,9 +325,6 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
if (ypos) if (ypos)
@ -335,6 +332,9 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_glfw.platform.getMonitorPos(monitor, xpos, ypos); _glfw.platform.getMonitorPos(monitor, xpos, ypos);
} }
@ -342,9 +342,6 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
if (ypos) if (ypos)
@ -356,14 +353,14 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height); _glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height);
} }
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (widthMM) if (widthMM)
*widthMM = 0; *widthMM = 0;
if (heightMM) if (heightMM)
@ -371,6 +368,9 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int*
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (widthMM) if (widthMM)
*widthMM = monitor->widthMM; *widthMM = monitor->widthMM;
if (heightMM) if (heightMM)
@ -380,42 +380,46 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int*
GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle, GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xscale) if (xscale)
*xscale = 0.f; *xscale = 0.f;
if (yscale) if (yscale)
*yscale = 0.f; *yscale = 0.f;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_glfw.platform.getMonitorContentScale(monitor, xscale, yscale); _glfw.platform.getMonitorContentScale(monitor, xscale, yscale);
} }
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->name; return monitor->name;
} }
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer) GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
{ {
_GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
_GLFW_REQUIRE_INIT();
monitor->userPointer = pointer; monitor->userPointer = pointer;
} }
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle) GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->userPointer; return monitor->userPointer;
} }
@ -428,14 +432,15 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(count != NULL); assert(count != NULL);
*count = 0; *count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (!refreshVideoModes(monitor)) if (!refreshVideoModes(monitor))
return NULL; return NULL;
@ -445,11 +450,11 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode)) if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode))
return NULL; return NULL;
@ -462,12 +467,13 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
unsigned short* values; unsigned short* values;
GLFWgammaramp ramp; GLFWgammaramp ramp;
const GLFWgammaramp* original; const GLFWgammaramp* original;
assert(handle != NULL);
assert(gamma > 0.f); assert(gamma > 0.f);
assert(gamma <= FLT_MAX); assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
assert(handle != NULL);
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX) if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma); _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
@ -505,11 +511,11 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp); _glfwFreeGammaArrays(&monitor->currentRamp);
if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp)) if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp))
return NULL; return NULL;
@ -519,8 +525,6 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(ramp != NULL); assert(ramp != NULL);
assert(ramp->size > 0); assert(ramp->size > 0);
assert(ramp->red != NULL); assert(ramp->red != NULL);
@ -529,6 +533,9 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (ramp->size <= 0) if (ramp->size <= 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,

View File

@ -30,6 +30,7 @@
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <math.h>
#include <assert.h>
static void makeContextCurrentNSGL(_GLFWwindow* window) static void makeContextCurrentNSGL(_GLFWwindow* window)
{ {
@ -182,16 +183,16 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
// Context robustness modes (GL_KHR_robustness) are not yet supported by // Context robustness modes (GL_KHR_robustness) are not supported by
// macOS but are not a hard constraint, so ignore and continue // macOS but are not a hard constraint, so ignore and continue
// Context release behaviors (GL_KHR_context_flush_control) are not yet // Context release behaviors (GL_KHR_context_flush_control) are not
// supported by macOS but are not a hard constraint, so ignore and continue // supported by macOS but are not a hard constraint, so ignore and continue
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not // Debug contexts (GL_KHR_debug) are not supported by macOS but are not
// a hard constraint, so ignore and continue // a hard constraint, so ignore and continue
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but // No-error contexts (GL_KHR_no_error) are not supported by macOS but
// are not a hard constraint, so ignore and continue // are not a hard constraint, so ignore and continue
#define ADD_ATTRIB(a) \ #define ADD_ATTRIB(a) \
@ -217,14 +218,11 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching); ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
} }
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4) if (ctxconfig->major >= 4)
{ {
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
} }
else else if (ctxconfig->major >= 3)
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3)
{ {
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
} }
@ -406,7 +404,6 @@ _GLFWusercontext* _glfwCreateUserContextNSGL(_GLFWwindow* window)
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil); _GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA) if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
@ -416,6 +413,9 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
return nil; return nil;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API) if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View File

@ -157,6 +157,17 @@
#define GLFW_NULL_SC_MENU 120 #define GLFW_NULL_SC_MENU 120
#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU #define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU
typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT;
typedef struct VkHeadlessSurfaceCreateInfoEXT
{
VkStructureType sType;
const void* pNext;
VkHeadlessSurfaceCreateFlagsEXT flags;
} VkHeadlessSurfaceCreateInfoEXT;
typedef VkResult (APIENTRY *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance,const VkHeadlessSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
// Null-specific per-window data // Null-specific per-window data
// //
typedef struct _GLFWwindowNull typedef struct _GLFWwindowNull

View File

@ -28,6 +28,7 @@
#include "internal.h" #include "internal.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
static void applySizeLimits(_GLFWwindow* window, int* width, int* height) static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
{ {
@ -552,12 +553,15 @@ const char* _glfwGetClipboardStringNull(void)
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs) EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
{ {
if (_glfw.egl.EXT_platform_base && _glfw.egl.MESA_platform_surfaceless)
return EGL_PLATFORM_SURFACELESS_MESA;
else
return 0; return 0;
} }
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void) EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
{ {
return 0; return EGL_DEFAULT_DISPLAY;
} }
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window) EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
@ -699,13 +703,18 @@ int _glfwGetKeyScancodeNull(int key)
void _glfwGetRequiredInstanceExtensionsNull(char** extensions) void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
{ {
if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_headless_surface)
return;
extensions[0] = "VK_KHR_surface";
extensions[1] = "VK_EXT_headless_surface";
} }
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance,
VkPhysicalDevice device, VkPhysicalDevice device,
uint32_t queuefamily) uint32_t queuefamily)
{ {
return GLFW_FALSE; return GLFW_TRUE;
} }
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
@ -713,8 +722,29 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
const VkAllocationCallbacks* allocator, const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface) VkSurfaceKHR* surface)
{ {
// This seems like the most appropriate error to return here PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT =
(PFN_vkCreateHeadlessSurfaceEXT)
vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT");
if (!vkCreateHeadlessSurfaceEXT)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Null: Vulkan instance missing VK_EXT_headless_surface extension");
return VK_ERROR_EXTENSION_NOT_PRESENT; return VK_ERROR_EXTENSION_NOT_PRESENT;
}
VkHeadlessSurfaceCreateInfoEXT sci;
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
const VkResult err = vkCreateHeadlessSurfaceEXT(instance, &sci, allocator, surface);
if (err)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Null: Failed to create Vulkan surface: %s",
_glfwGetVulkanResultString(err));
}
return err;
} }
_GLFWusercontext* _glfwCreateUserContextNull(_GLFWwindow* window) _GLFWusercontext* _glfwCreateUserContextNull(_GLFWwindow* window)

View File

@ -361,11 +361,12 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
{ {
void* mesaBuffer; void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaFormat; GLint mesaWidth, mesaHeight, mesaFormat;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API) if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -400,11 +401,12 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
{ {
void* mesaBuffer; void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaBytes; GLint mesaWidth, mesaHeight, mesaBytes;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API) if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
@ -434,9 +436,11 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle) GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API) if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View File

@ -142,6 +142,8 @@ GLFWbool _glfwInitVulkan(int mode)
_glfw.vk.KHR_xcb_surface = GLFW_TRUE; _glfw.vk.KHR_xcb_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = GLFW_TRUE; _glfw.vk.KHR_wayland_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_EXT_headless_surface") == 0)
_glfw.vk.EXT_headless_surface = GLFW_TRUE;
} }
_glfw_free(ep); _glfw_free(ep);
@ -272,11 +274,11 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device, VkPhysicalDevice device,
uint32_t queuefamily) uint32_t queuefamily)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
assert(instance != VK_NULL_HANDLE); assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE); assert(device != VK_NULL_HANDLE);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return GLFW_FALSE; return GLFW_FALSE;
@ -297,15 +299,16 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
const VkAllocationCallbacks* allocator, const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface) VkSurfaceKHR* surface)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(instance != VK_NULL_HANDLE);
assert(window != NULL);
assert(surface != NULL); assert(surface != NULL);
*surface = VK_NULL_HANDLE; *surface = VK_NULL_HANDLE;
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED); _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(instance != VK_NULL_HANDLE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;

View File

@ -836,7 +836,6 @@ _GLFWusercontext* _glfwCreateUserContextWGL(_GLFWwindow* window)
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -846,6 +845,9 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
return NULL; return NULL;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API) if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);

View File

@ -33,6 +33,7 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <wchar.h> #include <wchar.h>
#include <assert.h>
// Callback for EnumDisplayMonitors in createMonitor // Callback for EnumDisplayMonitors in createMonitor
@ -539,7 +540,6 @@ void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle) GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -548,12 +548,14 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
return NULL; return NULL;
} }
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->win32.publicAdapterName; return monitor->win32.publicAdapterName;
} }
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle) GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -562,6 +564,9 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
return NULL; return NULL;
} }
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->win32.publicDisplayName; return monitor->win32.publicDisplayName;
} }

View File

@ -32,6 +32,7 @@
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include <windowsx.h> #include <windowsx.h>
#include <shellapi.h> #include <shellapi.h>
@ -2598,7 +2599,6 @@ _GLFWusercontext* _glfwCreateUserContextWin32(_GLFWwindow* window)
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
@ -2608,6 +2608,9 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
return NULL; return NULL;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->win32.handle; return window->win32.handle;
} }

View File

@ -467,10 +467,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value)
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
// Allow closing of NULL (to match the behavior of free) // Allow closing of NULL (to match the behavior of free)
if (window == NULL) if (window == NULL)
return; return;
@ -501,40 +501,43 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return window->shouldClose; return window->shouldClose;
} }
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
window->shouldClose = value; window->shouldClose = value;
} }
GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle) GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return window->title; return window->title;
} }
GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(title != NULL); assert(title != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
char* prev = window->title; char* prev = window->title;
window->title = _glfw_strdup(title); window->title = _glfw_strdup(title);
@ -546,14 +549,15 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
int count, const GLFWimage* images) int count, const GLFWimage* images)
{ {
int i; int i;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(count >= 0); assert(count >= 0);
assert(count == 0 || images != NULL); assert(count == 0 || images != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (count < 0) if (count < 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon"); _glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon");
@ -577,25 +581,26 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
if (ypos) if (ypos)
*ypos = 0; *ypos = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowPos(window, xpos, ypos); _glfw.platform.getWindowPos(window, xpos, ypos);
} }
GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor) if (window->monitor)
return; return;
@ -604,27 +609,29 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (width) if (width)
*width = 0; *width = 0;
if (height) if (height)
*height = 0; *height = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowSize(window, width, height); _glfw.platform.getWindowSize(window, width, height);
} }
GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(width >= 0); assert(width >= 0);
assert(height >= 0); assert(height >= 0);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
window->videoMode.width = width; window->videoMode.width = width;
window->videoMode.height = height; window->videoMode.height = height;
@ -635,11 +642,11 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
int minwidth, int minheight, int minwidth, int minheight,
int maxwidth, int maxheight) int maxwidth, int maxheight)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE) if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE)
{ {
if (minwidth < 0 || minheight < 0) if (minwidth < 0 || minheight < 0)
@ -678,13 +685,14 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(numer != 0); assert(numer != 0);
assert(denom != 0); assert(denom != 0);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)
{ {
if (numer <= 0 || denom <= 0) if (numer <= 0 || denom <= 0)
@ -707,15 +715,16 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (width) if (width)
*width = 0; *width = 0;
if (height) if (height)
*height = 0; *height = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getFramebufferSize(window, width, height); _glfw.platform.getFramebufferSize(window, width, height);
} }
@ -723,9 +732,6 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
int* left, int* top, int* left, int* top,
int* right, int* bottom) int* right, int* bottom)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (left) if (left)
*left = 0; *left = 0;
if (top) if (top)
@ -736,43 +742,50 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
*bottom = 0; *bottom = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowFrameSize(window, left, top, right, bottom); _glfw.platform.getWindowFrameSize(window, left, top, right, bottom);
} }
GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (xscale) if (xscale)
*xscale = 0.f; *xscale = 0.f;
if (yscale) if (yscale)
*yscale = 0.f; *yscale = 0.f;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_glfw.platform.getWindowContentScale(window, xscale, yscale); _glfw.platform.getWindowContentScale(window, xscale, yscale);
} }
GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(0.f);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0.f);
return _glfw.platform.getWindowOpacity(window); return _glfw.platform.getWindowOpacity(window);
} }
GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(opacity == opacity); assert(opacity == opacity);
assert(opacity >= 0.f); assert(opacity >= 0.f);
assert(opacity <= 1.f); assert(opacity <= 1.f);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
if (opacity != opacity || opacity < 0.f || opacity > 1.f) if (opacity != opacity || opacity < 0.f || opacity > 1.f)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity); _glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity);
@ -784,29 +797,31 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.iconifyWindow(window); _glfw.platform.iconifyWindow(window);
} }
GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.restoreWindow(window); _glfw.platform.restoreWindow(window);
} }
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor) if (window->monitor)
return; return;
@ -815,11 +830,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
GLFWAPI void glfwShowWindow(GLFWwindow* handle) GLFWAPI void glfwShowWindow(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor) if (window->monitor)
return; return;
@ -831,21 +846,21 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.requestWindowAttention(window); _glfw.platform.requestWindowAttention(window);
} }
GLFWAPI void glfwHideWindow(GLFWwindow* handle) GLFWAPI void glfwHideWindow(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->monitor) if (window->monitor)
return; return;
@ -854,21 +869,21 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
GLFWAPI void glfwFocusWindow(GLFWwindow* handle) GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.focusWindow(window); _glfw.platform.focusWindow(window);
} }
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
switch (attrib) switch (attrib)
{ {
case GLFW_FOCUSED: case GLFW_FOCUSED:
@ -927,11 +942,11 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
value = value ? GLFW_TRUE : GLFW_FALSE; value = value ? GLFW_TRUE : GLFW_FALSE;
switch (attrib) switch (attrib)
@ -973,10 +988,11 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return (GLFWmonitor*) window->monitor; return (GLFWmonitor*) window->monitor;
} }
@ -986,14 +1002,15 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
int width, int height, int width, int height,
int refreshRate) int refreshRate)
{ {
_GLFWwindow* window = (_GLFWwindow*) wh;
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
assert(window != NULL);
assert(width >= 0); assert(width >= 0);
assert(height >= 0); assert(height >= 0);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) wh;
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
assert(window != NULL);
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,
@ -1021,29 +1038,32 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
{ {
_GLFW_REQUIRE_INIT();
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT();
window->userPointer = pointer; window->userPointer = pointer;
} }
GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return window->userPointer; return window->userPointer;
} }
GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
GLFWwindowposfun cbfun) GLFWwindowposfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun); _GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun);
return cbfun; return cbfun;
} }
@ -1051,10 +1071,11 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWwindowsizefun cbfun) GLFWwindowsizefun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun); _GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun);
return cbfun; return cbfun;
} }
@ -1062,10 +1083,11 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
GLFWwindowclosefun cbfun) GLFWwindowclosefun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun); _GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun);
return cbfun; return cbfun;
} }
@ -1073,10 +1095,11 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
GLFWwindowrefreshfun cbfun) GLFWwindowrefreshfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun); _GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun);
return cbfun; return cbfun;
} }
@ -1084,10 +1107,11 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
GLFWwindowfocusfun cbfun) GLFWwindowfocusfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun); _GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun);
return cbfun; return cbfun;
} }
@ -1095,10 +1119,11 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWwindowiconifyfun cbfun) GLFWwindowiconifyfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun); _GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun);
return cbfun; return cbfun;
} }
@ -1106,10 +1131,11 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
GLFWwindowmaximizefun cbfun) GLFWwindowmaximizefun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun); _GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun);
return cbfun; return cbfun;
} }
@ -1117,10 +1143,11 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle, GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle,
GLFWframebuffersizefun cbfun) GLFWframebuffersizefun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun); _GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun);
return cbfun; return cbfun;
} }
@ -1128,10 +1155,11 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle, GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle,
GLFWwindowcontentscalefun cbfun) GLFWwindowcontentscalefun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun); _GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun);
return cbfun; return cbfun;
} }

View File

@ -137,6 +137,13 @@ static void registryHandleGlobal(void* userData,
wl_registry_bind(registry, name, &wl_seat_interface, wl_registry_bind(registry, name, &wl_seat_interface,
_glfw_min(4, version)); _glfw_min(4, version));
_glfwAddSeatListenerWayland(_glfw.wl.seat); _glfwAddSeatListenerWayland(_glfw.wl.seat);
if (wl_seat_get_version(_glfw.wl.seat) >=
WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
{
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
}
} }
} }
else if (strcmp(interface, "wl_data_device_manager") == 0) else if (strcmp(interface, "wl_data_device_manager") == 0)
@ -854,12 +861,6 @@ int _glfwInitWayland(void)
} }
} }
if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
{
_glfw.wl.keyRepeatTimerfd =
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
}
if (!_glfw.wl.wmBase) if (!_glfw.wl.wmBase)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,

View File

@ -33,6 +33,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <math.h> #include <math.h>
#include <assert.h>
#include "wayland-client-protocol.h" #include "wayland-client-protocol.h"
@ -258,7 +259,6 @@ void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle) GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
@ -267,6 +267,9 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
return NULL; return NULL;
} }
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->wl.output; return monitor->wl.output;
} }

View File

@ -28,8 +28,6 @@
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-compose.h> #include <xkbcommon/xkbcommon-compose.h>
#include <stdbool.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR typedef struct VkWaylandSurfaceCreateInfoKHR

View File

@ -1974,41 +1974,41 @@ static void dataDeviceHandleEnter(void* userData,
_glfw.wl.dragFocus = NULL; _glfw.wl.dragFocus = NULL;
} }
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) unsigned int i;
for (i = 0; i < _glfw.wl.offerCount; i++)
{ {
if (_glfw.wl.offers[i].offer == offer) if (_glfw.wl.offers[i].offer == offer)
{ break;
_GLFWwindow* window = NULL;
if (surface)
{
if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag)
window = wl_surface_get_user_data(surface);
} }
if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list) if (i == _glfw.wl.offerCount)
return;
if (surface && wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag)
{
_GLFWwindow* window = wl_surface_get_user_data(surface);
if (window->wl.surface == surface)
{
if (_glfw.wl.offers[i].text_uri_list)
{ {
_glfw.wl.dragOffer = offer; _glfw.wl.dragOffer = offer;
_glfw.wl.dragFocus = window; _glfw.wl.dragFocus = window;
_glfw.wl.dragSerial = serial; _glfw.wl.dragSerial = serial;
}
_glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];
_glfw.wl.offerCount--;
break;
}
}
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
return;
if (_glfw.wl.dragOffer)
wl_data_offer_accept(offer, serial, "text/uri-list"); wl_data_offer_accept(offer, serial, "text/uri-list");
else }
}
}
if (!_glfw.wl.dragOffer)
{ {
wl_data_offer_accept(offer, serial, NULL); wl_data_offer_accept(offer, serial, NULL);
wl_data_offer_destroy(offer); wl_data_offer_destroy(offer);
} }
_glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];
_glfw.wl.offerCount--;
} }
static void dataDeviceHandleLeave(void* userData, static void dataDeviceHandleLeave(void* userData,
@ -2042,6 +2042,7 @@ static void dataDeviceHandleDrop(void* userData,
int count; int count;
char** paths = _glfwParseUriList(string, &count); char** paths = _glfwParseUriList(string, &count);
if (paths) if (paths)
{
_glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths); _glfwInputDrop(_glfw.wl.dragFocus, count, (const char**) paths);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
@ -2051,6 +2052,7 @@ static void dataDeviceHandleDrop(void* userData,
} }
_glfw_free(string); _glfw_free(string);
}
} }
static void dataDeviceHandleSelection(void* userData, static void dataDeviceHandleSelection(void* userData,
@ -2183,6 +2185,12 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
if (window == _glfw.wl.keyboardFocus) if (window == _glfw.wl.keyboardFocus)
_glfw.wl.keyboardFocus = NULL; _glfw.wl.keyboardFocus = NULL;
if (window->wl.fractionalScale)
wp_fractional_scale_v1_destroy(window->wl.fractionalScale);
if (window->wl.scalingViewport)
wp_viewport_destroy(window->wl.scalingViewport);
if (window->wl.activationToken) if (window->wl.activationToken)
xdg_activation_token_v1_destroy(window->wl.activationToken); xdg_activation_token_v1_destroy(window->wl.activationToken);
@ -3304,7 +3312,6 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void)
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle) GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
@ -3314,6 +3321,9 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
return NULL; return NULL;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->wl.surface; return window->wl.surface;
} }

View File

@ -33,6 +33,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <assert.h>
// Check whether the display mode should be included in enumeration // Check whether the display mode should be included in enumeration
@ -611,7 +612,6 @@ void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle) GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None); _GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -620,12 +620,14 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle)
return None; return None;
} }
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->x11.crtc; return monitor->x11.crtc;
} }
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle) GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None); _GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -634,6 +636,9 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
return None; return None;
} }
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
return monitor->x11.output; return monitor->x11.output;
} }

View File

@ -3320,7 +3320,6 @@ GLFWAPI Display* glfwGetX11Display(void)
GLFWAPI Window glfwGetX11Window(GLFWwindow* handle) GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None); _GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
@ -3329,11 +3328,16 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
return None; return None;
} }
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
return window->x11.handle; return window->x11.handle;
} }
GLFWAPI void glfwSetX11SelectionString(const char* string) GLFWAPI void glfwSetX11SelectionString(const char* string)
{ {
assert(string != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (_glfw.platform.platformID != GLFW_PLATFORM_X11) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)

View File

@ -630,6 +630,7 @@ int main(int argc, char** argv)
glfwTerminate(); glfwTerminate();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
glfwSetInputMode(slots[i].window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
glfwSetWindowUserPointer(slots[i].window, slots + i); glfwSetWindowUserPointer(slots[i].window, slots + i);

View File

@ -78,6 +78,7 @@ int main(int argc, char** argv)
glfwTerminate(); glfwTerminate();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
glfwSetInputMode(window, GLFW_UNLIMITED_MOUSE_BUTTONS, GLFW_TRUE);
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
gladLoadGL(glfwGetProcAddress); gladLoadGL(glfwGetProcAddress);