mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 22:34:35 +00:00
Compare commits
1 Commits
db09dc6bb4
...
ae7239979e
Author | SHA1 | Date | |
---|---|---|---|
|
ae7239979e |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -54,7 +54,7 @@ jobs:
|
|||||||
timeout-minutes: 4
|
timeout-minutes: 4
|
||||||
env:
|
env:
|
||||||
CFLAGS: -Werror
|
CFLAGS: -Werror
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.11
|
MACOSX_DEPLOYMENT_TARGET: 10.8
|
||||||
CMAKE_OSX_ARCHITECTURES: x86_64;arm64
|
CMAKE_OSX_ARCHITECTURES: x86_64;arm64
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
@ -79,7 +79,7 @@ more information.
|
|||||||
|
|
||||||
## System requirements
|
## System requirements
|
||||||
|
|
||||||
GLFW supports Windows XP and later and macOS 10.11 and later. Linux and other
|
GLFW supports Windows XP and later and macOS 10.8 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.
|
||||||
@ -123,11 +123,8 @@ information on what to include when reporting a bug.
|
|||||||
|
|
||||||
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
|
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
|
||||||
the limit of the mouse button tokens to be reported (#2423)
|
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: The fractional scaling related objects were not destroyed
|
||||||
- [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517)
|
- [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 Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
||||||
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
|
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
|
||||||
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
|
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
|
||||||
|
@ -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, IOKit and QuartzCore frameworks to the project as dependencies. They
|
OpenGL and IOKit frameworks to the project as dependencies. They can all be
|
||||||
can all be found in `/System/Library/Frameworks`.
|
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 -framework QuartzCore
|
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
|
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
|
||||||
|
@ -242,27 +242,24 @@ extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
|
|||||||
|
|
||||||
## OpenGL on macOS {#compat_osx}
|
## OpenGL on macOS {#compat_osx}
|
||||||
|
|
||||||
macOS (as of version 14) still provides OpenGL but it has been deprecated by
|
Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then
|
||||||
Apple. While the API is still available, it is poorly maintained and frequently
|
only forward-compatible, core profile contexts are supported. Support for
|
||||||
develops new issues. On modern systems, OpenGL is implemented on top of Metal
|
OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible,
|
||||||
and is not fully thread-safe.
|
core profile contexts. There is also still no mechanism for requesting debug
|
||||||
|
contexts or no-error contexts. Versions of Mac OS X earlier than 10.7 support
|
||||||
|
at most OpenGL version 2.1.
|
||||||
|
|
||||||
macOS does not support OpenGL stereo rendering. If the `GLFW_STEREO` hint is
|
Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
||||||
set to true, OpenGL context creation will always fail.
|
`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if
|
||||||
|
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.
|
||||||
|
|
||||||
macOS only supports OpenGL core profile contexts that are forward-compatible,
|
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
||||||
but the `GLFW_OPENGL_FORWARD_COMPAT` hint is ignored since GLFW 3.4. Even if
|
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
|
||||||
this hint is set to false (the default), a forward-compatible context will be
|
setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
|
||||||
returned if available.
|
a non-default value will cause @ref glfwCreateWindow to fail and the
|
||||||
|
`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}
|
||||||
|
@ -3183,8 +3183,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 The window frame will not be rendered at full resolution on
|
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
|
||||||
* Retina displays unless the
|
* at full resolution on 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
|
||||||
|
@ -151,11 +151,10 @@ 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 -framework QuartzCore")
|
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GLFW_BUILD_WAYLAND)
|
if (GLFW_BUILD_WAYLAND)
|
||||||
|
@ -137,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))
|
||||||
@ -164,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)
|
||||||
{
|
{
|
||||||
@ -180,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;
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
#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>
|
#include <assert.h>
|
||||||
@ -312,6 +310,7 @@ 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)
|
||||||
@ -319,6 +318,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
else
|
else
|
||||||
window->ns.occluded = GLFW_TRUE;
|
window->ns.occluded = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -1950,8 +1950,19 @@ 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 = [CAMetalLayer layer];
|
window->ns.layer = [[bundle classNamed:@"CAMetalLayer"] layer];
|
||||||
if (!window->ns.layer)
|
if (!window->ns.layer)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@ -2016,6 +2027,9 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
#else
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
@ -183,16 +183,16 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context robustness modes (GL_KHR_robustness) are not supported by
|
// Context robustness modes (GL_KHR_robustness) are not yet 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
|
// Context release behaviors (GL_KHR_context_flush_control) are not yet
|
||||||
// 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 supported by macOS but are not
|
// Debug contexts (GL_KHR_debug) are not yet 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 supported by macOS but
|
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
||||||
// are not a hard constraint, so ignore and continue
|
// are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
#define ADD_ATTRIB(a) \
|
#define ADD_ATTRIB(a) \
|
||||||
@ -218,11 +218,14 @@ 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 if (ctxconfig->major >= 3)
|
else
|
||||||
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||||
|
if (ctxconfig->major >= 3)
|
||||||
{
|
{
|
||||||
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
||||||
}
|
}
|
||||||
|
@ -1974,41 +1974,41 @@ static void dataDeviceHandleEnter(void* userData,
|
|||||||
_glfw.wl.dragFocus = NULL;
|
_glfw.wl.dragFocus = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i;
|
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
|
||||||
|
|
||||||
for (i = 0; i < _glfw.wl.offerCount; i++)
|
|
||||||
{
|
{
|
||||||
if (_glfw.wl.offers[i].offer == offer)
|
if (_glfw.wl.offers[i].offer == offer)
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
_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)
|
||||||
{
|
{
|
||||||
_glfw.wl.dragOffer = offer;
|
_glfw.wl.dragOffer = offer;
|
||||||
_glfw.wl.dragFocus = window;
|
_glfw.wl.dragFocus = window;
|
||||||
_glfw.wl.dragSerial = serial;
|
_glfw.wl.dragSerial = serial;
|
||||||
|
|
||||||
wl_data_offer_accept(offer, serial, "text/uri-list");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.wl.offers[i] = _glfw.wl.offers[_glfw.wl.offerCount - 1];
|
||||||
|
_glfw.wl.offerCount--;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_glfw.wl.dragOffer)
|
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");
|
||||||
|
else
|
||||||
{
|
{
|
||||||
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,17 +2042,15 @@ 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++)
|
||||||
_glfw_free(paths[i]);
|
_glfw_free(paths[i]);
|
||||||
|
|
||||||
_glfw_free(paths);
|
_glfw_free(paths);
|
||||||
}
|
|
||||||
|
|
||||||
_glfw_free(string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw_free(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dataDeviceHandleSelection(void* userData,
|
static void dataDeviceHandleSelection(void* userData,
|
||||||
|
Loading…
Reference in New Issue
Block a user