mirror of
https://github.com/glfw/glfw.git
synced 2025-12-21 14:42:06 +00:00
Compare commits
71 Commits
3a79504b14
...
b5c68787a7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5c68787a7 | ||
|
|
8e15281d34 | ||
|
|
621e99d53e | ||
|
|
1a0b7827d4 | ||
|
|
4c64184455 | ||
|
|
bfcb98fb6c | ||
|
|
f8582d26d0 | ||
|
|
1fdd39cf3e | ||
|
|
c9b129753a | ||
|
|
04a67c8267 | ||
|
|
5c87937e44 | ||
|
|
af6e36f250 | ||
|
|
5c08ecbb5c | ||
|
|
d35fdc21eb | ||
|
|
32e0089b86 | ||
|
|
e2f9340a8c | ||
|
|
58aad6c136 | ||
|
|
e4e46b4cc5 | ||
|
|
587025f9cb | ||
|
|
ca4485e12e | ||
|
|
ece28b0f19 | ||
|
|
df70d8e9bf | ||
|
|
6148990427 | ||
|
|
64694f17ab | ||
|
|
bbe6c4cfa1 | ||
|
|
c01d16a9ee | ||
|
|
f40442fa59 | ||
|
|
f2a9ea7b7e | ||
|
|
48c0cea73f | ||
|
|
7de1c5c10a | ||
|
|
fc32eb48c5 | ||
|
|
41bb2515ef | ||
|
|
dcf9a51b78 | ||
|
|
23d31b805a | ||
|
|
3b003dd5f0 | ||
|
|
9dfa1649ff | ||
|
|
c97e3a657b | ||
|
|
b88a8c9364 | ||
|
|
7a55ca34b9 | ||
|
|
b0d196c43c | ||
|
|
7b6f25c360 | ||
|
|
c01aa3fec4 | ||
|
|
1ba83ede44 | ||
|
|
7874992888 | ||
|
|
350aebf20a | ||
|
|
e91b1820dd | ||
|
|
ab4b4e95f6 | ||
|
|
e2016291f1 | ||
|
|
375fcdeadb | ||
|
|
1d647668af | ||
|
|
cd68bac78d | ||
|
|
1cb8ab8dc6 | ||
|
|
87ddca831a | ||
|
|
2f2e7f041a | ||
|
|
e55a552eee | ||
|
|
5f52f2a7f8 | ||
|
|
3de9ed6453 | ||
|
|
d01ad1a78d | ||
|
|
f2806aa9ab | ||
|
|
6539d101f3 | ||
|
|
a1a1b77150 | ||
|
|
4caca8b20c | ||
|
|
f2b86a25b3 | ||
|
|
dd854e47ba | ||
|
|
931ba89aad | ||
|
|
51f11929f3 | ||
|
|
5e94092263 | ||
|
|
3a0a3c540c | ||
|
|
998036654c | ||
|
|
0ae4eb4d26 | ||
|
|
a08bfd9891 |
@ -23,6 +23,7 @@ video tutorials.
|
||||
- Denis Bernard
|
||||
- BiBi
|
||||
- Doug Binks
|
||||
- bitb4ker
|
||||
- blanco
|
||||
- Waris Boonyasiriwat
|
||||
- Kyle Brenneman
|
||||
@ -123,6 +124,7 @@ video tutorials.
|
||||
- Josh Kilmer
|
||||
- Byunghoon Kim
|
||||
- Cameron King
|
||||
- knokko
|
||||
- Peter Knut
|
||||
- Christoph Kubisch
|
||||
- Yuri Kunde Schlesner
|
||||
|
||||
135
README.md
135
README.md
@ -9,34 +9,28 @@ GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
|
||||
application development. It provides a simple, platform-independent API for
|
||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
|
||||
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
|
||||
Linux both Wayland and X11 are supported.
|
||||
GLFW is written primarily in C99, with parts of macOS support being written in
|
||||
Objective-C.
|
||||
|
||||
GLFW supports Windows, macOS and Linux, and also works on many other Unix-like
|
||||
systems. On Linux both Wayland and X11 are supported.
|
||||
|
||||
GLFW is licensed under the [zlib/libpng
|
||||
license](https://www.glfw.org/license.html).
|
||||
|
||||
You can [download](https://www.glfw.org/download.html) the latest stable release
|
||||
as source or Windows binaries. Each release starting with 3.0 also has
|
||||
a corresponding [annotated tag](https://github.com/glfw/glfw/releases) with
|
||||
source and binary archives.
|
||||
as source or Windows and macOS binaries. There are [release
|
||||
tags](https://github.com/glfw/glfw/releases) with source and binary archives
|
||||
attached for every version since 3.0.
|
||||
|
||||
The [documentation](https://www.glfw.org/docs/latest/) is available online and is
|
||||
included in all source and binary archives. See the [release
|
||||
notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and
|
||||
deprecations in the latest release. For more details see the [version
|
||||
history](https://www.glfw.org/changelog.html).
|
||||
|
||||
The `master` branch is the stable integration branch and _should_ always compile
|
||||
and run on all supported platforms, although details of newly added features may
|
||||
change until they have been included in a release. New features and many bug
|
||||
fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
|
||||
they are stable enough to merge.
|
||||
|
||||
If you are new to GLFW, you may find the
|
||||
[tutorial](https://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
|
||||
you have used GLFW 2 in the past, there is a [transition
|
||||
guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
|
||||
3 API.
|
||||
also included in source and binary archives, except those generated
|
||||
automatically by Github. The documentation contains guides, a tutorial and the
|
||||
API reference. The [release
|
||||
notes](https://www.glfw.org/docs/latest/news.html) list the new features,
|
||||
caveats and deprecations in the latest release. The [version
|
||||
history](https://www.glfw.org/changelog.html) lists every user-visible change
|
||||
for every release.
|
||||
|
||||
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
|
||||
around the world, whether by reporting bugs, providing community support, adding
|
||||
@ -44,57 +38,37 @@ features, reviewing or testing code, debugging, proofreading docs, suggesting
|
||||
features or fixing bugs.
|
||||
|
||||
|
||||
## Compiling GLFW
|
||||
|
||||
GLFW is written primarily in C99, with parts of macOS support being written in
|
||||
Objective-C. GLFW itself requires only the headers and libraries for your OS
|
||||
and window system. It does not need any additional headers for context creation
|
||||
APIs (WGL, GLX, EGL, NSGL, OSMesa) or rendering APIs (OpenGL, OpenGL ES, Vulkan)
|
||||
to enable support for them.
|
||||
|
||||
GLFW supports compilation on Windows with Visual C++ (2013 and later) and
|
||||
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
|
||||
and Clang. It will likely compile in other environments as well, but this is
|
||||
not regularly tested.
|
||||
|
||||
There are [pre-compiled binaries](https://www.glfw.org/download.html) available
|
||||
for all supported compilers on Windows and macOS.
|
||||
|
||||
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
|
||||
more information about how to compile GLFW yourself.
|
||||
|
||||
|
||||
## Using GLFW
|
||||
|
||||
See the [documentation](https://www.glfw.org/docs/latest/) for tutorials, guides
|
||||
and the API reference.
|
||||
|
||||
|
||||
## Contributing to GLFW
|
||||
|
||||
See the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||
more information.
|
||||
|
||||
|
||||
## System requirements
|
||||
|
||||
GLFW supports Windows 7 and later and macOS 10.11 and later. Linux and other
|
||||
Unix-like systems running the X Window System are supported even without
|
||||
a desktop environment or modern extensions, although some features require
|
||||
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
|
||||
GLFW supports Windows 7 and later and macOS 10.11 and later. On GNOME Wayland,
|
||||
window decorations will be very basic unless the
|
||||
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) package is
|
||||
installed. Linux and other Unix-like systems running X11 are supported even
|
||||
without a desktop environment or modern extensions, although some features
|
||||
require a clipboard manager or a modern window manager.
|
||||
|
||||
See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html)
|
||||
in the documentation for more information.
|
||||
for more detailed information.
|
||||
|
||||
|
||||
## Dependencies
|
||||
## Compiling GLFW
|
||||
|
||||
GLFW itself needs only CMake 3.16 or later and the headers and libraries for your
|
||||
OS and window system.
|
||||
GLFW supports compilation with Visual C++ (2013 and later), GCC and Clang. Both
|
||||
Clang-CL and MinGW-w64 are supported. Other C99 compilers will likely also
|
||||
work, but this is not regularly tested.
|
||||
|
||||
There are [pre-compiled binaries](https://www.glfw.org/download.html)
|
||||
available for Windows and macOS.
|
||||
|
||||
GLFW itself needs only CMake and the headers and libraries for your operating
|
||||
system and window system. No other SDKs are required.
|
||||
|
||||
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
|
||||
more information about compiling GLFW and the exact dependencies required for
|
||||
each window system.
|
||||
|
||||
The examples and test programs depend on a number of tiny libraries. These are
|
||||
located in the `deps/` directory.
|
||||
bundled in the `deps/` directory. The repository has no submodules.
|
||||
|
||||
- [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
|
||||
with command-line options
|
||||
@ -107,8 +81,33 @@ located in the `deps/` directory.
|
||||
- [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
|
||||
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
|
||||
|
||||
The documentation is generated with [Doxygen](https://doxygen.org/) if CMake can
|
||||
find that tool.
|
||||
The documentation is generated with [Doxygen](https://doxygen.org/) when the
|
||||
library is built, provided CMake could find a sufficiently new version of it
|
||||
during configuration.
|
||||
|
||||
|
||||
## Using GLFW
|
||||
|
||||
See the [HTML documentation](https://www.glfw.org/docs/latest/) for a tutorial,
|
||||
guides and the API reference.
|
||||
|
||||
|
||||
## Contributing to GLFW
|
||||
|
||||
See the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||
more information.
|
||||
|
||||
The `master` branch is the stable integration branch and _should_ always compile
|
||||
and run on all supported platforms. Details of a newly added feature,
|
||||
including the public API, may change until it has been included in a release.
|
||||
|
||||
The `latest` branch is equivalent to the [highest numbered](https://semver.org/)
|
||||
release, although it may not always point to the same commit as the tag for that
|
||||
release.
|
||||
|
||||
The `ci` branch is used to trigger continuous integration jobs for code under
|
||||
testing and should never be relied on for any purpose.
|
||||
|
||||
|
||||
## Reporting bugs
|
||||
@ -121,8 +120,13 @@ information on what to include when reporting a bug.
|
||||
|
||||
## Changelog since 3.4
|
||||
|
||||
- Added OpenGL and OpenGL ES user contexts for multiple window contexts via
|
||||
`GLFWusercontext`, `glfwCreateUserContext`, `glfwDestroyUserContext`,
|
||||
`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)
|
||||
- Added `glfwGetEGLConfig` function to query the `EGLConfig` of a window (#2045)
|
||||
- Added `glfwGetGLXFBConfig` function to query the `GLXFBConfig` of a window (#1925)
|
||||
- Updated minimum CMake version to 3.16 (#2541)
|
||||
- Removed support for building with original MinGW (#2540)
|
||||
- [Win32] Removed support for Windows XP and Vista (#2505)
|
||||
@ -149,7 +153,6 @@ information on what to include when reporting a bug.
|
||||
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
|
||||
`GLFW_NATIVE_CONTEXT_API` (#2518)
|
||||
|
||||
|
||||
## Contact
|
||||
|
||||
On [glfw.org](https://www.glfw.org/) you can find the latest version of GLFW, as
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
|
||||
# Because of bugs and limitations in its Markdown support, only fairly recent
|
||||
# versions of Doxygen can produce acceptable output
|
||||
set(MINIMUM_DOXYGEN_VERSION 1.9.8)
|
||||
|
||||
# NOTE: The order of this list determines the order of items in the Guides
|
||||
# (i.e. Pages) list in the generated documentation
|
||||
set(source_files
|
||||
@ -32,10 +36,10 @@ foreach(file IN LISTS source_files)
|
||||
endforeach()
|
||||
|
||||
set(DOXYGEN_SKIP_DOT TRUE)
|
||||
find_package(Doxygen)
|
||||
find_package(Doxygen ${MINIMUM_DOXYGEN_VERSION} QUIET)
|
||||
|
||||
if (NOT DOXYGEN_FOUND OR DOXYGEN_VERSION VERSION_LESS "1.9.8")
|
||||
message(STATUS "Documentation generation requires Doxygen 1.9.8 or later")
|
||||
if (NOT DOXYGEN_FOUND)
|
||||
message(STATUS "Documentation generation requires Doxygen ${MINIMUM_DOXYGEN_VERSION} or later")
|
||||
else()
|
||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||
add_custom_command(OUTPUT "html/index.html"
|
||||
@ -46,7 +50,7 @@ else()
|
||||
COMMENT "Generating HTML documentation"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(docs ALL SOURCES "html/index.html")
|
||||
add_custom_target(docs ALL SOURCES ${source_files} DEPENDS "html/index.html")
|
||||
set_target_properties(docs PROPERTIES FOLDER "GLFW3")
|
||||
|
||||
if (GLFW_INSTALL)
|
||||
|
||||
@ -278,13 +278,7 @@ ALIASES = "thread_safety=@par Thread safety^^" \
|
||||
"analysis=@par Analysis^^" \
|
||||
"reentrancy=@par Reentrancy^^" \
|
||||
"errors=@par Errors^^" \
|
||||
"callback_signature=@par Callback signature^^" \
|
||||
"glfw3=__GLFW 3:__" \
|
||||
"x11=__X11:__" \
|
||||
"wayland=__Wayland:__" \
|
||||
"win32=__Windows:__" \
|
||||
"macos=__macOS:__" \
|
||||
"linux=__Linux:__"
|
||||
"callback_signature=@par Callback signature^^"
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
|
||||
@ -50,10 +50,11 @@ compositing window manager to un-redirect full screen GLFW windows. If the
|
||||
running window manager uses compositing but does not support this property then
|
||||
additional copying may be performed for each buffer swap of full screen windows.
|
||||
|
||||
GLFW uses the [clipboard manager protocol][ClipboardManager] to push a clipboard
|
||||
string (i.e. selection) owned by a GLFW window about to be destroyed to the
|
||||
clipboard manager. If there is no running clipboard manager, the clipboard
|
||||
string will be unavailable once the window has been destroyed.
|
||||
GLFW uses the [clipboard manager protocol][ClipboardManager] to keep the
|
||||
clipboard string availble for the user after the libary has been terminated. If
|
||||
there is no running clipboard manager and the clipboard contents has been set
|
||||
with @ref glfwSetClipboardString, the clipboard will be emptied when the library
|
||||
is terminated.
|
||||
|
||||
[clipboardManager]: https://www.freedesktop.org/wiki/ClipboardManager/
|
||||
|
||||
|
||||
@ -91,6 +91,28 @@ You can disable context creation by setting the
|
||||
Windows without contexts should not be passed to @ref glfwMakeContextCurrent or
|
||||
@ref glfwSwapBuffers. Doing this generates a @ref GLFW_NO_WINDOW_CONTEXT error.
|
||||
|
||||
@subsection context_user User contexts for multi context windows
|
||||
|
||||
GLFW supports multiple OpenGL or OpenGL ES contexts per window. Providing
|
||||
a window with an existing OpenGL or OpenGL ES context has been created further
|
||||
user contexts can be created using @ref glfwCreateUserContext with the same
|
||||
API sharing the window context objects.
|
||||
|
||||
@code
|
||||
GLFWusercontext* usercontext = glfwCreateUserContext(window);
|
||||
|
||||
/* make the user context current */
|
||||
glfwMakeUserContextCurrent(usercontext);
|
||||
|
||||
/* make the window context current */
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
/* destroy the user context */
|
||||
glfwDestroyUserContext(usercontext);
|
||||
|
||||
@endcode
|
||||
|
||||
User contexts See also the test program `usercontext`.
|
||||
|
||||
## Current context {#context_current}
|
||||
|
||||
@ -121,6 +143,26 @@ error.
|
||||
- @ref glfwExtensionSupported
|
||||
- @ref glfwGetProcAddress
|
||||
|
||||
@subsection context_current_user Current user context
|
||||
|
||||
When using [user contexts](@ref context_user) the user context can be
|
||||
made current using @ref glfwMakeUserContextCurrent.
|
||||
|
||||
@code
|
||||
glfwMakeUserContextCurrent(usercontext);
|
||||
@endcode
|
||||
|
||||
This makes the any window context non-current on the calling thread, such that
|
||||
a call to @ref glfwGetCurrentContext will return `NULL`.
|
||||
|
||||
The current user context is returned by @ref glfwGetCurrentUserContext.
|
||||
|
||||
@code
|
||||
GLFWusercontext* usercontext = glfwGetCurrentUserContext();
|
||||
@endcode
|
||||
|
||||
This will return the current user context or `NULL` if either the main window context
|
||||
or no context is current.
|
||||
|
||||
## Buffer swapping {#context_swap}
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ before the application exits. Modern systems are very good at freeing resources
|
||||
allocated by programs that exit, but GLFW sometimes has to change global system
|
||||
settings and these might not be restored without termination.
|
||||
|
||||
@macos When the library is initialized the main menu and dock icon are created.
|
||||
__macOS:__ When the library is initialized the main menu and dock icon are created.
|
||||
These are not desirable for a command-line only program. The creation of the
|
||||
main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init
|
||||
hint.
|
||||
|
||||
@ -255,7 +255,7 @@ hardware gamma correction, which today is typically an approximation of sRGB
|
||||
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
|
||||
produce the default (usually sRGB-like) behavior.
|
||||
|
||||
@note @wayland An application cannot read or modify the monitor gamma ramp. The
|
||||
@ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
|
||||
@note __Wayland:__ An application cannot read or modify the monitor gamma ramp.
|
||||
The @ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
|
||||
emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
|
||||
|
||||
26
docs/news.md
26
docs/news.md
@ -5,6 +5,15 @@
|
||||
|
||||
## New features {#features}
|
||||
|
||||
### Multiple window contexts {#multiple_window_contexts}
|
||||
|
||||
GLFW now provides the ability to create multiple OpenGL and OpenGL ES
|
||||
contexts for a given window. Called user contexts, a [GLFWusercontext](@ref context_user)
|
||||
can be created using @ref glfwCreateUserContext,
|
||||
destroyed using @ref glfwDestroyUserContext, and managed with
|
||||
@ref glfwMakeUserContextCurrent and @ref glfwGetCurrentUserContext.
|
||||
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
|
||||
@ -14,6 +23,19 @@ 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.
|
||||
|
||||
|
||||
### EGLConfig native access function {#eglconfig}
|
||||
|
||||
GLFW now provides the @ref glfwGetEGLConfig native access function for querying
|
||||
the `EGLConfig` of a window that has a `EGLSurface`.
|
||||
|
||||
|
||||
### GLXFBConfig native access function {#glxfbconfig}
|
||||
|
||||
GLFW now provides the @ref glfwGetGLXFBConfig native access function for
|
||||
querying the `GLXFBConfig` of a window that has a `GLXWindow`.
|
||||
|
||||
|
||||
## Caveats {#caveats}
|
||||
|
||||
## Deprecations {#deprecations}
|
||||
@ -39,6 +61,10 @@ actively maintained and available on many platforms.
|
||||
|
||||
### New functions {#new_functions}
|
||||
|
||||
- @ref glfwGetEGLConfig
|
||||
- @ref glfwGetGLXFBConfig
|
||||
|
||||
|
||||
### New types {#new_types}
|
||||
|
||||
### New constants {#new_constants}
|
||||
|
||||
@ -35,7 +35,7 @@ By default, GLFW will load the Vulkan loader dynamically at runtime via its stan
|
||||
`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and
|
||||
`libvulkan.1.dylib` on macOS.
|
||||
|
||||
@macos GLFW will also look up and search the `Frameworks` subdirectory of your
|
||||
__macOS:__ GLFW will also look up and search the `Frameworks` subdirectory of your
|
||||
application bundle.
|
||||
|
||||
If your code is using a Vulkan loader with a different name or in a non-standard location
|
||||
@ -47,7 +47,7 @@ entry point retrieval. This prevents GLFW from dynamically loading the Vulkan l
|
||||
glfwInitVulkanLoader(vkGetInstanceProcAddr);
|
||||
```
|
||||
|
||||
@macos To make your application be redistributable you will need to set up the application
|
||||
__macOS:__ To make your application be redistributable you will need to set up the application
|
||||
bundle according to the LunarG SDK documentation. This is explained in more detail in the
|
||||
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
|
||||
|
||||
@ -186,7 +186,7 @@ check whether any extensions you wish to enable are already in the returned
|
||||
array, as it is an error to specify an extension more than once in the
|
||||
`VkInstanceCreateInfo` struct.
|
||||
|
||||
@macos MoltenVK is (as of July 2022) not yet a fully conformant implementation
|
||||
__macOS:__ MoltenVK is (as of July 2022) not yet a fully conformant implementation
|
||||
of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the
|
||||
`VK_KHR_portability_enumeration` instance extension and set the
|
||||
`VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the instance creation
|
||||
|
||||
@ -363,10 +363,10 @@ which API was used to create the current context may fail if you change this
|
||||
hint. This can be resolved by having it load functions via @ref
|
||||
glfwGetProcAddress.
|
||||
|
||||
@note @wayland The EGL API _is_ the native context creation API, so this hint
|
||||
@note __Wayland:__ The EGL API _is_ the native context creation API, so this hint
|
||||
will have no effect.
|
||||
|
||||
@note @x11 On some Linux systems, creating contexts via both the native and EGL
|
||||
@note __X11:__ On some Linux systems, creating contexts via both the native and EGL
|
||||
APIs in a single process will cause the application to segfault. Stick to one
|
||||
API or the other on Linux for now.
|
||||
|
||||
@ -400,7 +400,7 @@ requested. Additionally, OpenGL ES 1.x cannot be returned if 2.0 or later was
|
||||
requested, and vice versa. This is because OpenGL ES 3.x is backward compatible
|
||||
with 2.0, but OpenGL ES 2.0 is not backward compatible with 1.x.
|
||||
|
||||
@note @macos The OS only supports core profile contexts for OpenGL versions 3.2
|
||||
@note __macOS:__ The OS only supports core profile contexts for OpenGL versions 3.2
|
||||
and later. Before creating an OpenGL context of version 3.2 or later you must
|
||||
set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint accordingly.
|
||||
OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
|
||||
@ -893,7 +893,7 @@ int xpos, ypos;
|
||||
glfwGetWindowPos(window, &xpos, &ypos);
|
||||
```
|
||||
|
||||
@note @wayland An applications cannot know the positions of its windows or
|
||||
@note __Wayland:__ An applications cannot know the positions of its windows or
|
||||
whether one has been moved. The @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y
|
||||
window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos
|
||||
functions emit @ref GLFW_FEATURE_UNAVAILABLE. The window position callback will
|
||||
@ -1044,7 +1044,7 @@ You can also get the current iconification state with @ref glfwGetWindowAttrib.
|
||||
int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
|
||||
```
|
||||
|
||||
@note @wayland An application cannot know if any of its windows have been
|
||||
@note __Wayland:__ An application cannot know if any of its windows have been
|
||||
iconified or restore one from iconification. The @ref glfwRestoreWindow
|
||||
function can only restore windows from maximization and the iconify callback
|
||||
will not be called. The [GLFW_ICONIFIED](@ref GLFW_ICONIFIED_attrib) attribute
|
||||
|
||||
@ -1228,13 +1228,13 @@ extern "C" {
|
||||
* The top-left to bottom-right diagonal resize/move shape. This is usually
|
||||
* a diagonal double-headed arrow.
|
||||
*
|
||||
* @note @macos This shape is provided by a private system API and may fail
|
||||
* @note __macOS:__ This shape is provided by a private system API and may fail
|
||||
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* @note __Wayland:__ This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* @note __X11:__ This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*/
|
||||
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
|
||||
@ -1243,13 +1243,13 @@ extern "C" {
|
||||
* The top-right to bottom-left diagonal resize/move shape. This is usually
|
||||
* a diagonal double-headed arrow.
|
||||
*
|
||||
* @note @macos This shape is provided by a private system API and may fail
|
||||
* @note __macOS:__ This shape is provided by a private system API and may fail
|
||||
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* @note __Wayland:__ This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* @note __X11:__ This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*/
|
||||
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
|
||||
@ -1264,10 +1264,10 @@ extern "C" {
|
||||
* The operation-not-allowed shape. This is usually a circle with a diagonal
|
||||
* line through it.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* @note __Wayland:__ This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* @note __X11:__ This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*/
|
||||
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
|
||||
@ -1403,6 +1403,18 @@ typedef struct GLFWmonitor GLFWmonitor;
|
||||
*/
|
||||
typedef struct GLFWwindow GLFWwindow;
|
||||
|
||||
/*! @brief Opaque user OpenGL & OpenGL ES context object.
|
||||
*
|
||||
* Opaque user OpenGL OpenGL ES context object.
|
||||
*
|
||||
* @see @ref context_user
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
typedef struct GLFWusercontext GLFWusercontext;
|
||||
|
||||
/*! @brief Opaque cursor object.
|
||||
*
|
||||
* Opaque cursor object.
|
||||
@ -1629,7 +1641,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
|
||||
* @sa @ref glfwSetWindowSizeCallback
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -1649,7 +1661,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
|
||||
* @sa @ref glfwSetWindowCloseCallback
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -1669,7 +1681,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
|
||||
* @sa @ref glfwSetWindowRefreshCallback
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -1800,7 +1812,7 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, flo
|
||||
* @sa @ref glfwSetMouseButtonCallback
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle and modifier mask parameters.
|
||||
* __GLFW 3:__ Added window handle and modifier mask parameters.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -1891,7 +1903,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffse
|
||||
* @sa @ref glfwSetKeyCallback
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle, scancode and modifier mask parameters.
|
||||
* __GLFW 3:__ Added window handle, scancode and modifier mask parameters.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -1912,7 +1924,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int actio
|
||||
* @sa @ref glfwSetCharCallback
|
||||
*
|
||||
* @since Added in version 2.4.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -2020,7 +2032,7 @@ typedef void (* GLFWjoystickfun)(int jid, int event);
|
||||
* @sa @ref glfwGetVideoModes
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added refresh rate member.
|
||||
* __GLFW 3:__ Added refresh rate member.
|
||||
*
|
||||
* @ingroup monitor
|
||||
*/
|
||||
@ -2083,7 +2095,7 @@ typedef struct GLFWgammaramp
|
||||
* @sa @ref window_icon
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Removed format and bytes-per-pixel members.
|
||||
* __GLFW 3:__ Removed format and bytes-per-pixel members.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -2183,12 +2195,12 @@ typedef struct GLFWallocator
|
||||
* @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos This function will change the current directory of the
|
||||
* @remark __macOS:__ This function will change the current directory of the
|
||||
* application to the `Contents/Resources` subdirectory of the application's
|
||||
* bundle, if present. This can be disabled with the @ref
|
||||
* GLFW_COCOA_CHDIR_RESOURCES init hint.
|
||||
*
|
||||
* @remark @macos This function will create the main menu and dock icon for the
|
||||
* @remark __macOS:__ This function will create the main menu and dock icon for the
|
||||
* application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to
|
||||
* contain a menu bar. Otherwise a minimal menu bar is created manually with
|
||||
* common commands like Hide, Quit and About. The About entry opens a minimal
|
||||
@ -2203,7 +2215,7 @@ typedef struct GLFWallocator
|
||||
* to something other than `wayland` or `x11`, the regular detection mechanism
|
||||
* will be used instead.
|
||||
*
|
||||
* @remark @x11 This function will set the `LC_CTYPE` category of the
|
||||
* @remark __X11:__ This function will set the `LC_CTYPE` category of the
|
||||
* application locale according to the current environment if that category is
|
||||
* still "C". This is because the "C" locale breaks Unicode text input.
|
||||
*
|
||||
@ -2679,7 +2691,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos,
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @win32 On Windows 8 and earlier the physical size is calculated from
|
||||
* @remark __Win32:__ On Windows 8 and earlier the physical size is calculated from
|
||||
* the current resolution and system DPI instead of querying the monitor EDID data.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -2713,7 +2725,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Fractional scaling information is not yet available for
|
||||
* @remark __Wayland:__ Fractional scaling information is not yet available for
|
||||
* monitors, so this function only returns integer content scales.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -2861,7 +2873,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);
|
||||
* @sa @ref glfwGetVideoMode
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Changed to return an array of modes for a specific monitor.
|
||||
* __GLFW 3:__ Changed to return an array of modes for a specific monitor.
|
||||
*
|
||||
* @ingroup monitor
|
||||
*/
|
||||
@ -2915,7 +2927,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
|
||||
* @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Monitor gamma is a privileged protocol, so this function
|
||||
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -2939,7 +2951,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
|
||||
* and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Monitor gamma is a privileged protocol, so this function
|
||||
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
|
||||
* returning `NULL`.
|
||||
*
|
||||
@ -2981,9 +2993,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
|
||||
* @remark The size of the specified gamma ramp should match the size of the
|
||||
* current ramp for that monitor.
|
||||
*
|
||||
* @remark @win32 The gamma ramp size must be 256.
|
||||
* @remark __Win32:__ The gamma ramp size must be 256.
|
||||
*
|
||||
* @remark @wayland Monitor gamma is a privileged protocol, so this function
|
||||
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @pointer_lifetime The specified gamma ramp is copied before this function
|
||||
@ -3159,32 +3171,32 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 Window creation will fail if the Microsoft GDI software
|
||||
* @remark __Win32:__ Window creation will fail if the Microsoft GDI software
|
||||
* OpenGL implementation is the only one available.
|
||||
*
|
||||
* @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
|
||||
* @remark __Win32:__ If the executable has an icon resource named `GLFW_ICON,` it
|
||||
* will be set as the initial icon for the window. If no such icon is present,
|
||||
* the `IDI_APPLICATION` icon will be used instead. To set a different icon,
|
||||
* see @ref glfwSetWindowIcon.
|
||||
*
|
||||
* @remark @win32 The context to share resources with must not be current on
|
||||
* @remark __Win32:__ The context to share resources with must not be current on
|
||||
* any other thread.
|
||||
*
|
||||
* @remark @macos The OS only supports core profile contexts for OpenGL
|
||||
* @remark __macOS:__ The OS only supports core profile contexts for OpenGL
|
||||
* versions 3.2 and later. Before creating an OpenGL context of version 3.2 or
|
||||
* later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint)
|
||||
* hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all
|
||||
* on macOS.
|
||||
*
|
||||
* @remark @macos The GLFW window has no icon, as it is not a document
|
||||
* @remark __macOS:__ The GLFW window has no icon, as it is not a document
|
||||
* window, but the dock icon will be the same as the application bundle's icon.
|
||||
* For more information on bundles, see the
|
||||
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
|
||||
*
|
||||
* [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
|
||||
* Retina displays unless the
|
||||
* @remark __macOS:__ The window frame will not be rendered at full resolution
|
||||
* on Retina displays unless the
|
||||
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
|
||||
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
|
||||
* application bundle's `Info.plist`. For more information, see
|
||||
@ -3195,11 +3207,11 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
*
|
||||
* [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
|
||||
*
|
||||
* @remark @macos When activating frame autosaving with
|
||||
* @remark __macOS:__ When activating frame autosaving with
|
||||
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
|
||||
* window size and position may be overridden by previously saved values.
|
||||
*
|
||||
* @remark @wayland GLFW uses [libdecor][] where available to create its window
|
||||
* @remark __Wayland:__ GLFW uses [libdecor][] where available to create its window
|
||||
* decorations. This in turn uses server-side XDG decorations where available
|
||||
* and provides high quality client-side decorations on compositors like GNOME.
|
||||
* If both XDG decorations and libdecor are unavailable, GLFW falls back to
|
||||
@ -3208,15 +3220,15 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
*
|
||||
* [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor
|
||||
*
|
||||
* @remark @x11 Some window managers will not respect the placement of
|
||||
* @remark __X11:__ Some window managers will not respect the placement of
|
||||
* initially hidden windows.
|
||||
*
|
||||
* @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
|
||||
* @remark __X11:__ Due to the asynchronous nature of X11, it may take a moment for
|
||||
* a window to reach its requested state. This means you may not be able to
|
||||
* query the final size, position or other attributes directly after window
|
||||
* creation.
|
||||
*
|
||||
* @remark @x11 The class part of the `WM_CLASS` window property will by
|
||||
* @remark __X11:__ The class part of the `WM_CLASS` window property will by
|
||||
* default be set to the window title passed to this function. The instance
|
||||
* part will use the contents of the `RESOURCE_NAME` environment variable, if
|
||||
* present and not empty, or fall back to the window title. Set the
|
||||
@ -3349,7 +3361,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos The window title will not be updated until the next time you
|
||||
* @remark __macOS:__ The window title will not be updated until the next time you
|
||||
* process events.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3358,7 +3370,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
|
||||
* @sa @ref glfwGetWindowTitle
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3392,14 +3404,14 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
|
||||
* @pointer_lifetime The specified image data is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @remark @macos Regular windows do not have icons on macOS. This function
|
||||
* @remark __macOS:__ Regular windows do not have icons on macOS. This function
|
||||
* will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as
|
||||
* the application bundle's icon. For more information on bundles, see the
|
||||
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
|
||||
*
|
||||
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
|
||||
*
|
||||
* @remark @wayland There is no existing protocol to change an icon, the
|
||||
* @remark __Wayland:__ There is no existing protocol to change an icon, the
|
||||
* window will thus inherit the one defined in the application's desktop file.
|
||||
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
@ -3430,7 +3442,7 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Window positions are not currently part of any common
|
||||
* @remark __Wayland:__ Window positions are not currently part of any common
|
||||
* Wayland protocol, so this function cannot be implemented and will emit @ref
|
||||
* GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
@ -3464,7 +3476,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Window positions are not currently part of any common
|
||||
* @remark __Wayland:__ Window positions are not currently part of any common
|
||||
* Wayland protocol, so this function cannot be implemented and will emit @ref
|
||||
* GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
@ -3474,7 +3486,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
||||
* @sa @ref glfwGetWindowPos
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3504,7 +3516,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
|
||||
* @sa @ref glfwSetWindowSize
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3539,7 +3551,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
|
||||
* @remark If you set size limits and an aspect ratio that conflict, the
|
||||
* results are undefined.
|
||||
*
|
||||
* @remark @wayland The size limits will not be applied until the window is
|
||||
* @remark __Wayland:__ The size limits will not be applied until the window is
|
||||
* actually resized, either by the user or by the compositor.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3582,7 +3594,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
|
||||
* @remark If you set size limits and an aspect ratio that conflict, the
|
||||
* results are undefined.
|
||||
*
|
||||
* @remark @wayland The aspect ratio will not be applied until the window is
|
||||
* @remark __Wayland:__ The aspect ratio will not be applied until the window is
|
||||
* actually resized, either by the user or by the compositor.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3628,7 +3640,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
|
||||
* @sa @ref glfwSetWindowMonitor
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3778,7 +3790,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland There is no way to set an opacity factor for a window.
|
||||
* @remark __Wayland:__ There is no way to set an opacity factor for a window.
|
||||
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3814,7 +3826,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
|
||||
* @sa @ref glfwMaximizeWindow
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3834,9 +3846,9 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Restoring a window from maximization is not currently part
|
||||
* of any common Wayland protocol, so this function can only restore windows
|
||||
* from maximization.
|
||||
* @remark __Wayland:__ Restoring a window from maximization is not currently
|
||||
* part of any common Wayland protocol, so this function can only restore
|
||||
* windows from maximization.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -3845,7 +3857,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
|
||||
* @sa @ref glfwMaximizeWindow
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3892,7 +3904,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Because Wayland wants every frame of the desktop to be
|
||||
* @remark __Wayland:__ Because Wayland wants every frame of the desktop to be
|
||||
* complete, this function does not immediately make the window visible.
|
||||
* Instead it will become visible the next time the window framebuffer is
|
||||
* updated after this call.
|
||||
@ -3955,7 +3967,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland The compositor will likely ignore focus requests unless
|
||||
* @remark __Wayland:__ The compositor will likely ignore focus requests unless
|
||||
* another window created by the same application already has input focus.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3983,7 +3995,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos Attention is requested to the application as a whole, not the
|
||||
* @remark __macOS:__ Attention is requested to the application as a whole, not the
|
||||
* specific window.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4058,7 +4070,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
|
||||
* affected by any resizing or mode switching, although you may need to update
|
||||
* your viewport if the framebuffer size has changed.
|
||||
*
|
||||
* @remark @wayland Window positions are not currently part of any common
|
||||
* @remark __Wayland:__ Window positions are not currently part of any common
|
||||
* Wayland protocol. The window position arguments are ignored.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4096,7 +4108,7 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
|
||||
* errors. However, this function should not fail as long as it is passed
|
||||
* valid arguments and the library has been [initialized](@ref intro_init).
|
||||
*
|
||||
* @remark @wayland Checking whether a window is iconified is not currently
|
||||
* @remark __Wayland:__ Checking whether a window is iconified is not currently
|
||||
* part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
|
||||
* cannot be implemented and is always `GLFW_FALSE`.
|
||||
*
|
||||
@ -4140,7 +4152,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
|
||||
* @remark Calling @ref glfwGetWindowAttrib will always return the latest
|
||||
* value, even if that value is ignored by the current mode of the window.
|
||||
*
|
||||
* @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
|
||||
* @remark __Wayland:__ The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
|
||||
* not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4220,7 +4232,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @wayland This callback will not be called. The Wayland protocol
|
||||
* @remark __Wayland:__ This callback will not be called. The Wayland protocol
|
||||
* provides no way to be notified of when a window is moved.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4259,7 +4271,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
|
||||
* @sa @ref window_size
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -4291,7 +4303,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @macos Selecting Quit from the application menu will trigger the
|
||||
* @remark __macOS:__ Selecting Quit from the application menu will trigger the
|
||||
* close callback for all windows.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4299,7 +4311,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
|
||||
* @sa @ref window_close
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -4335,7 +4347,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
|
||||
* @sa @ref window_refresh
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -4396,7 +4408,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @wayland This callback will not be called. The Wayland protocol
|
||||
* @remark __Wayland:__ This callback will not be called. The Wayland protocol
|
||||
* provides no way to be notified of when a window is iconified, and no way to
|
||||
* check whether a window is currently iconified.
|
||||
*
|
||||
@ -4905,7 +4917,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
|
||||
* @sa @ref input_key
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -4937,7 +4949,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
|
||||
* @sa @ref input_mouse_button
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5007,7 +5019,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland This function will only work when the cursor mode is
|
||||
* @remark __Wayland:__ This function will only work when the cursor mode is
|
||||
* `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -5205,7 +5217,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
||||
* @sa @ref input_key
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5248,7 +5260,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
|
||||
* @sa @ref input_char
|
||||
*
|
||||
* @since Added in version 2.4.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5332,7 +5344,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
|
||||
* @sa @ref input_mouse_button
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5562,7 +5574,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
|
||||
* @sa @ref joystick_button
|
||||
*
|
||||
* @since Added in version 2.2.
|
||||
* @glfw3 Changed to return a dynamic array.
|
||||
* __GLFW 3:__ Changed to return a dynamic array.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5926,7 +5938,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 The clipboard on Windows has a single global lock for reading and
|
||||
* @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
|
||||
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it
|
||||
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
|
||||
* It is safe to try this multiple times.
|
||||
@ -5959,7 +5971,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 The clipboard on Windows has a single global lock for reading and
|
||||
* @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
|
||||
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it
|
||||
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
|
||||
* It is safe to try this multiple times.
|
||||
@ -6093,6 +6105,9 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
|
||||
* thread can have only a single current context at a time. Making a context
|
||||
* current detaches any previously current context on the calling thread.
|
||||
*
|
||||
* Making a context of a window current on a given thread will detach
|
||||
* any user context which is current on that thread and visa versa.
|
||||
*
|
||||
* When moving a context between threads, you must detach it (make it
|
||||
* non-current) on the old thread before making it current on the new one.
|
||||
*
|
||||
@ -6120,6 +6135,9 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
|
||||
*
|
||||
* @sa @ref context_current
|
||||
* @sa @ref glfwGetCurrentContext
|
||||
* @sa @ref context_current_user
|
||||
* @sa @ref glfwMakeUserContextCurrent
|
||||
* @sa @ref glfwGetCurrentUserContext
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
@ -6176,7 +6194,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
|
||||
* @sa @ref glfwSwapInterval
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -6308,6 +6326,147 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
|
||||
*/
|
||||
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
|
||||
|
||||
/*! @brief Create a new OpenGL or OpenGL ES user context for a window
|
||||
*
|
||||
* This function creates a new OpenGL or OpenGL ES user context for a
|
||||
* window, which can be used to call OpenGL or OpenGL ES functions on
|
||||
* another thread. For a valid user context the window must be created
|
||||
* with a [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) other than
|
||||
* `GLFW_NO_API`.
|
||||
*
|
||||
* User context creation uses the window context and framebuffer related
|
||||
* hints to ensure a valid context is created for that window, these hints
|
||||
* should be the same at the time of user context creation as when the
|
||||
* window was created.
|
||||
*
|
||||
* Contexts share resources with the window context and with any other
|
||||
* user context created for that window.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED,
|
||||
* @ref GLFW_INVALID_VALUE the window parameter is `NULL`,
|
||||
* @ref GLFW_NO_WINDOW_CONTEXT if the window has no OpenGL or
|
||||
* OpenGL US context, and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @param[in] window The Window for which the user context is to be
|
||||
* created.
|
||||
* @return The handle of the user context created, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref context_user
|
||||
* @sa @ref usercontext_creation
|
||||
* @sa @ref glfwDestroyUserContext
|
||||
* @sa @ref window_creation
|
||||
* @sa @ref glfwCreateWindow
|
||||
* @sa @ref glfwDestroyWindow
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup context
|
||||
*/
|
||||
GLFWAPI GLFWusercontext* glfwCreateUserContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Destroys the specified user context
|
||||
*
|
||||
* This function destroys the specified user context.
|
||||
* User contexts should be destroyed before destroying the
|
||||
* window they were made with.
|
||||
*
|
||||
* If the user context is current on the main thread, it is
|
||||
* detached before being destroyed.
|
||||
*
|
||||
* @param[in] context The user context to destroy.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @note The user context must not be current on any other
|
||||
* thread when this function is called.
|
||||
*
|
||||
* @reentrancy This function must not be called from a callback.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref context_user
|
||||
* @sa @ref usercontext_creation
|
||||
* @sa @ref glfwCreateUserContext
|
||||
* @sa @ref window_creation
|
||||
* @sa @ref glfwCreateWindow
|
||||
* @sa @ref glfwDestroyWindow
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup context
|
||||
*/
|
||||
GLFWAPI void glfwDestroyUserContext(GLFWusercontext* context);
|
||||
|
||||
/*! @brief Makes the user context current for the calling thread.
|
||||
*
|
||||
* This function makes the OpenGL or OpenGL ES context of the specified user
|
||||
* context current on the calling thread. A context must only be made current on
|
||||
* a single thread at a time and each thread can have only a single current
|
||||
* context at a time.
|
||||
*
|
||||
* Making a user context current on a given thread will detach the context of
|
||||
* any window which is current on that thread and visa versa.
|
||||
*
|
||||
* When moving a context between threads, you must make it non-current on the
|
||||
* old thread before making it current on the new one.
|
||||
*
|
||||
* By default, making a context non-current implicitly forces a pipeline flush.
|
||||
* On machines that support `GL_KHR_context_flush_control`, you can control
|
||||
* whether a context performs this flush by setting the
|
||||
* [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint)
|
||||
* hint.
|
||||
*
|
||||
* @param[in] context The user context to make current, or `NULL` to
|
||||
* detach the current context.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED,
|
||||
* and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread.
|
||||
*
|
||||
* @sa @ref context_user
|
||||
* @sa @ref context_current_user
|
||||
* @sa @ref glfwGetCurrentUserContext
|
||||
* @sa @ref context_current
|
||||
* @sa @ref glfwMakeContextCurrent
|
||||
* @sa @ref glfwGetCurrentContext
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup context
|
||||
*/
|
||||
GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* context);
|
||||
|
||||
/*! @brief Returns the current OpenGL or OpenGL ES user context
|
||||
*
|
||||
* This function returns the user context which is current
|
||||
* on the calling thread.
|
||||
*
|
||||
* @return The user context current, or `NULL` if no user context
|
||||
* is current.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread.
|
||||
*
|
||||
* @sa @ref context_user
|
||||
* @sa @ref context_current_user
|
||||
* @sa @ref glfwMakeUserContextCurrent
|
||||
* @sa @ref context_current
|
||||
* @sa @ref glfwMakeContextCurrent
|
||||
* @sa @ref glfwGetCurrentContext
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup context
|
||||
*/
|
||||
GLFWAPI GLFWusercontext* glfwGetCurrentUserContext(void);
|
||||
|
||||
|
||||
/*! @brief Returns whether the Vulkan loader and an ICD have been found.
|
||||
*
|
||||
* This function returns whether the Vulkan loader and any minimally functional
|
||||
@ -6443,7 +6602,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos This function currently always returns `GLFW_TRUE`, as the
|
||||
* @remark __macOS:__ This function currently always returns `GLFW_TRUE`, as the
|
||||
* `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide
|
||||
* a `vkGetPhysicalDevice*PresentationSupport` type function.
|
||||
*
|
||||
@ -6501,15 +6660,15 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
|
||||
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
|
||||
* eliminate almost all occurrences of these errors.
|
||||
*
|
||||
* @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the
|
||||
* @remark __macOS:__ GLFW prefers the `VK_EXT_metal_surface` extension, with the
|
||||
* `VK_MVK_macos_surface` extension as a fallback. The name of the selected
|
||||
* extension, if any, is included in the array returned by @ref
|
||||
* glfwGetRequiredInstanceExtensions.
|
||||
*
|
||||
* @remark @macos This function creates and sets a `CAMetalLayer` instance for
|
||||
* @remark __macOS:__ This function creates and sets a `CAMetalLayer` instance for
|
||||
* the window content view, which is required for MoltenVK to function.
|
||||
*
|
||||
* @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension,
|
||||
* @remark __X11:__ By default GLFW prefers the `VK_KHR_xcb_surface` extension,
|
||||
* with the `VK_KHR_xlib_surface` extension as a fallback. You can make
|
||||
* `VK_KHR_xlib_surface` the preferred extension by setting the
|
||||
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
|
||||
|
||||
@ -478,6 +478,29 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
|
||||
/*! @brief Retrieves the `GLXFBConfig` of the specified window's `GLXWindow`.
|
||||
*
|
||||
* @param[in] window The window whose `GLXWindow` to query.
|
||||
* @param[out] config The `GLXFBConfig` of the window `GLXWindow`, if available.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @remark `GLXFBConfig` is an opaque type. Unlike other GLFW functions, the
|
||||
* @p config out parameter is not cleared on error, as core GLX does not define
|
||||
* any invalid value.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.5
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* window, GLXFBConfig* config);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
@ -586,6 +609,29 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
|
||||
/*! @brief Retrieves the `EGLConfig` of the specified window's `EGLSurface`.
|
||||
*
|
||||
* @param[in] window The window whose `EGLSurface` to query.
|
||||
* @param[out] config The `EGLConfig` of the window `EGLSurface`, if available.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @remark `EGLConfig` is an opaque type. Unlike other GLFW functions, the @p
|
||||
* config out parameter is not cleared on error, as core EGL does not define
|
||||
* any invalid value.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.5.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetEGLConfig(GLFWwindow* window, EGLConfig* config);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
|
||||
@ -559,6 +559,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
||||
.waitEvents = _glfwWaitEventsCocoa,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutCocoa,
|
||||
.postEmptyEvent = _glfwPostEmptyEventCocoa,
|
||||
.createUserContext = _glfwCreateUserContextCocoa,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformCocoa,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayCocoa,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowCocoa,
|
||||
|
||||
@ -107,6 +107,7 @@ typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMeta
|
||||
|
||||
#define GLFW_NSGL_CONTEXT_STATE _GLFWcontextNSGL nsgl;
|
||||
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
|
||||
#define GLFW_NSGL_USER_CONTEXT_STATE _GLFWusercontextNSGL nsgl;
|
||||
|
||||
// HIToolbox.framework pointer typedefs
|
||||
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
|
||||
@ -134,6 +135,14 @@ typedef struct _GLFWlibraryNSGL
|
||||
CFBundleRef framework;
|
||||
} _GLFWlibraryNSGL;
|
||||
|
||||
// NSGL-specific per usercontext data
|
||||
//
|
||||
typedef struct _GLFWusercontextNSGL
|
||||
{
|
||||
id object;
|
||||
|
||||
} _GLFWusercontextNSGL;
|
||||
|
||||
// Cocoa-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowNS
|
||||
@ -300,3 +309,5 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextCocoa(_GLFWwindow* window);
|
||||
_GLFWusercontext* _glfwCreateUserContextNSGL(_GLFWwindow* window);
|
||||
|
||||
@ -884,7 +884,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
|
||||
[window->ns.object setContentView:window->ns.view];
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
[window->ns.object setTitle:@(wndconfig->title)];
|
||||
[window->ns.object setTitle:@(window->title)];
|
||||
[window->ns.object setDelegate:window->ns.delegate];
|
||||
[window->ns.object setAcceptsMouseMovedEvents:YES];
|
||||
[window->ns.object setRestorable:NO];
|
||||
@ -2021,6 +2021,25 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
|
||||
}
|
||||
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextCocoa(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.nsgl.object)
|
||||
{
|
||||
return _glfwCreateUserContextNSGL(window);
|
||||
}
|
||||
else if (window->context.egl.handle)
|
||||
{
|
||||
return _glfwCreateUserContextEGL(window);
|
||||
}
|
||||
else if (window->context.osmesa.handle)
|
||||
{
|
||||
return _glfwCreateUserContextOSMesa(window);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -619,7 +619,9 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
||||
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFWwindow* previous;
|
||||
_GLFWusercontext* previousUserContext;
|
||||
|
||||
previousUserContext = _glfwPlatformGetTls(&_glfw.usercontextSlot);
|
||||
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
|
||||
if (window && window->context.client == GLFW_NO_API)
|
||||
@ -629,6 +631,12 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
||||
return;
|
||||
}
|
||||
|
||||
if (previousUserContext)
|
||||
{
|
||||
assert(previous==NULL);
|
||||
previousUserContext->makeCurrent(NULL);
|
||||
}
|
||||
|
||||
if (previous)
|
||||
{
|
||||
if (!window || window->context.source != previous->context.source)
|
||||
@ -763,3 +771,65 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
||||
return window->context.getProcAddress(procname);
|
||||
}
|
||||
|
||||
GLFWAPI GLFWusercontext* glfwCreateUserContext(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWusercontext* context;
|
||||
_GLFWwindow* window = (_GLFWwindow*)handle;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (!window)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Cannot create a user context without a valid window handle");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
|
||||
"Cannot create a user context for a window that has no OpenGL or OpenGL ES context");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context = _glfw.platform.createUserContext(window);
|
||||
|
||||
return (GLFWusercontext*)context;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwDestroyUserContext(GLFWusercontext* handle)
|
||||
{
|
||||
_GLFWusercontext* context = (_GLFWusercontext*)handle;
|
||||
_GLFWusercontext* current = _glfwPlatformGetTls(&_glfw.usercontextSlot);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (context)
|
||||
{
|
||||
if(current==context)
|
||||
glfwMakeContextCurrent(NULL);
|
||||
|
||||
context->destroy(context);
|
||||
}
|
||||
}
|
||||
|
||||
GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* handle)
|
||||
{
|
||||
_GLFWusercontext* context = (_GLFWusercontext*)handle;
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
// Call glfwMakeContextCurrent(NULL) to both clear context TLS and set
|
||||
// context to NULL if required by platform & context, and this
|
||||
// handles case of calling glfwMakeUserContextCurrent(NULL)
|
||||
glfwMakeContextCurrent(NULL);
|
||||
|
||||
if (context)
|
||||
context->makeCurrent(context);
|
||||
}
|
||||
|
||||
GLFWAPI GLFWusercontext* glfwGetCurrentUserContext(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return _glfwPlatformGetTls(&_glfw.usercontextSlot);
|
||||
}
|
||||
@ -436,6 +436,10 @@ GLFWbool _glfwInitEGL(void)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString");
|
||||
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetProcAddress");
|
||||
_glfw.egl.CreatePbufferSurface = (PFN_eglCreatePbufferSurface)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreatePbufferSurface");
|
||||
_glfw.egl.ChooseConfig = (PFN_eglChooseConfig)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglChooseConfig");
|
||||
|
||||
if (!_glfw.egl.GetConfigAttrib ||
|
||||
!_glfw.egl.GetConfigs ||
|
||||
@ -453,7 +457,9 @@ GLFWbool _glfwInitEGL(void)
|
||||
!_glfw.egl.SwapBuffers ||
|
||||
!_glfw.egl.SwapInterval ||
|
||||
!_glfw.egl.QueryString ||
|
||||
!_glfw.egl.GetProcAddress)
|
||||
!_glfw.egl.GetProcAddress ||
|
||||
!_glfw.egl.CreatePbufferSurface||
|
||||
!_glfw.egl.ChooseConfig)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to load required entry points");
|
||||
@ -569,17 +575,15 @@ void _glfwTerminateEGL(void)
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
// Create the OpenGL or OpenGL ES context for the window eglConfig
|
||||
//
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
GLFWbool _glfwCreateContextForConfigEGL(EGLConfig eglConfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
EGLContext* context)
|
||||
{
|
||||
EGLint attribs[40];
|
||||
EGLConfig config;
|
||||
EGLContext share = NULL;
|
||||
EGLNativeWindowType native;
|
||||
int index = 0;
|
||||
EGLContext share = NULL;
|
||||
|
||||
if (!_glfw.egl.display)
|
||||
{
|
||||
@ -590,9 +594,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.egl.handle;
|
||||
|
||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (!eglBindAPI(EGL_OPENGL_ES_API))
|
||||
@ -688,10 +689,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
|
||||
SET_ATTRIB(EGL_NONE, EGL_NONE);
|
||||
|
||||
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
|
||||
config, share, attribs);
|
||||
*context = eglCreateContext(_glfw.egl.display, eglConfig, share, attribs);
|
||||
|
||||
if (window->context.egl.handle == EGL_NO_CONTEXT)
|
||||
if (*context == EGL_NO_CONTEXT)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"EGL: Failed to create context: %s",
|
||||
@ -699,9 +699,32 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// Set up attributes for surface creation
|
||||
index = 0;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
EGLNativeWindowType native;
|
||||
EGLint attribs[40];
|
||||
int index = 0;
|
||||
|
||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &window->context.egl.config))
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwCreateContextForConfigEGL(window->context.egl.config,ctxconfig,&window->context.egl.handle))
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// Set up attributes for surface creation
|
||||
if (fbconfig->sRGB)
|
||||
{
|
||||
if (_glfw.egl.KHR_gl_colorspace)
|
||||
@ -735,18 +758,18 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
// implement eglCreatePlatformWindowSurfaceEXT despite reporting
|
||||
// support for EGL_EXT_platform_base
|
||||
window->context.egl.surface =
|
||||
eglCreateWindowSurface(_glfw.egl.display, 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, config, attribs);
|
||||
eglCreatePbufferSurface(_glfw.egl.display, window->context.egl.config, attribs);
|
||||
}
|
||||
else
|
||||
{
|
||||
window->context.egl.surface =
|
||||
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
|
||||
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, window->context.egl.config, native, attribs);
|
||||
}
|
||||
|
||||
if (window->context.egl.surface == EGL_NO_SURFACE)
|
||||
@ -757,7 +780,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.egl.config = config;
|
||||
|
||||
// Load the appropriate client library
|
||||
if (!_glfw.egl.KHR_get_all_proc_addresses)
|
||||
@ -895,6 +917,109 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
}
|
||||
#endif // _GLFW_X11
|
||||
|
||||
static void _glfwMakeUserContextCurrentEGL(_GLFWusercontext* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
if (!eglMakeCurrent(_glfw.egl.display,
|
||||
context->egl.surface,
|
||||
context->egl.surface,
|
||||
context->egl.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to make user context current: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!eglMakeCurrent(_glfw.egl.display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to clear current user context: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, context);
|
||||
}
|
||||
|
||||
static void _glfwDestroyUserContextEGL(_GLFWusercontext* context)
|
||||
{
|
||||
if (context->egl.surface!=EGL_NO_SURFACE)
|
||||
eglDestroySurface(_glfw.egl.display,context->egl.surface);
|
||||
|
||||
eglDestroyContext(_glfw.egl.display, context->egl.handle);
|
||||
free(context);
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window)
|
||||
{
|
||||
_GLFWusercontext* context;
|
||||
_GLFWctxconfig ctxconfig;
|
||||
EGLint dummyConfigAttribs[] =
|
||||
{
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint dummySurfaceAttribs[] =
|
||||
{
|
||||
EGL_WIDTH, 1, EGL_HEIGHT, 1,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint dummySurfaceNumConfigs;
|
||||
EGLConfig dummySurfaceConfig;
|
||||
|
||||
context = calloc(1, sizeof(_GLFWusercontext));
|
||||
context->window = window;
|
||||
|
||||
ctxconfig = _glfw.hints.context;
|
||||
ctxconfig.share = window;
|
||||
|
||||
if (!_glfwCreateContextForConfigEGL(window->context.egl.config,&ctxconfig,&context->egl.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to create user OpenGL context");
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
if (glfwExtensionSupported("EGL_KHR_surfaceless_context"))
|
||||
context->egl.surface = EGL_NO_SURFACE;
|
||||
else
|
||||
{
|
||||
eglChooseConfig(_glfw.egl.display, dummyConfigAttribs, &dummySurfaceConfig, 1, &dummySurfaceNumConfigs);
|
||||
if (!dummySurfaceNumConfigs)
|
||||
{
|
||||
eglDestroyContext(_glfw.egl.display, context->egl.handle);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to find surface config for user context: %s", getEGLErrorString(eglGetError()));
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
context->egl.surface = eglCreatePbufferSurface(_glfw.egl.display, dummySurfaceConfig, dummySurfaceAttribs);
|
||||
if (context->egl.surface == EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroyContext(_glfw.egl.display, context->egl.handle);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to create surface for user context: %s for %s", getEGLErrorString(eglGetError()), eglQueryString(_glfw.egl.display,0x3054));
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
context->makeCurrent = _glfwMakeUserContextCurrentEGL;
|
||||
context->destroy = _glfwDestroyUserContextEGL;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
@ -939,10 +1064,32 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
|
||||
window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return EGL_NO_CONTEXT;
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
return window->context.egl.surface;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetEGLConfig(GLFWwindow* handle, EGLConfig* config)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
assert(config != NULL);
|
||||
|
||||
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);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*config = window->context.egl.config;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -447,26 +447,19 @@ void _glfwTerminateGLX(void)
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
|
||||
// Create the OpenGL or OpenGL ES context for the window fbConfig
|
||||
//
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
GLFWbool _glfwCreateContextForFBGLX(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
GLXContext* context)
|
||||
{
|
||||
int attribs[40];
|
||||
GLXFBConfig native = NULL;
|
||||
GLXContext share = NULL;
|
||||
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.glx.handle;
|
||||
|
||||
if (!chooseGLXFBConfig(fbconfig, &native))
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"GLX: Failed to find a suitable GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (!_glfw.glx.ARB_create_context ||
|
||||
@ -581,9 +574,9 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
|
||||
SET_ATTRIB(None, None);
|
||||
|
||||
window->context.glx.handle =
|
||||
*context =
|
||||
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
|
||||
native,
|
||||
window->context.glx.fbconfig,
|
||||
share,
|
||||
True,
|
||||
attribs);
|
||||
@ -592,40 +585,64 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
// implementation of GLX_ARB_create_context_profile that fail
|
||||
// default 1.0 context creation with a GLXBadProfileARB error in
|
||||
// violation of the extension spec
|
||||
if (!window->context.glx.handle)
|
||||
if (!(*context))
|
||||
{
|
||||
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
|
||||
ctxconfig->client == GLFW_OPENGL_API &&
|
||||
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
|
||||
ctxconfig->forward == GLFW_FALSE)
|
||||
{
|
||||
window->context.glx.handle =
|
||||
createLegacyContextGLX(window, native, share);
|
||||
*context =
|
||||
createLegacyContextGLX(window, window->context.glx.fbconfig, share);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
window->context.glx.handle =
|
||||
createLegacyContextGLX(window, native, share);
|
||||
*context =
|
||||
createLegacyContextGLX(window, window->context.glx.fbconfig, share);
|
||||
}
|
||||
|
||||
_glfwReleaseErrorHandlerX11();
|
||||
|
||||
if (!window->context.glx.handle)
|
||||
if (!(*context))
|
||||
{
|
||||
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
|
||||
if (!chooseGLXFBConfig(fbconfig, &window->context.glx.fbconfig))
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"GLX: Failed to find a suitable GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if(!_glfwCreateContextForFBGLX(window,ctxconfig,&window->context.glx.handle))
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.glx.window =
|
||||
glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
|
||||
glXCreateWindow(_glfw.x11.display, window->context.glx.fbconfig, window->x11.handle, NULL);
|
||||
if (!window->context.glx.window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.glx.fbconfig = native;
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentGLX;
|
||||
window->context.swapBuffers = swapBuffersGLX;
|
||||
window->context.swapInterval = swapIntervalGLX;
|
||||
@ -670,6 +687,60 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static void _glfwMakeUserContextCurrentGLX(_GLFWusercontext* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
if(!glXMakeCurrent(_glfw.x11.display, context->window->context.glx.window,context->glx.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to make user context current");
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to clear current user context");
|
||||
return;
|
||||
}
|
||||
}
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, context);
|
||||
}
|
||||
|
||||
static void _glfwDestroyUserContextGLX(_GLFWusercontext* context)
|
||||
{
|
||||
glXDestroyContext(_glfw.x11.display, context->glx.handle);
|
||||
free(context);
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextGLX(_GLFWwindow* window)
|
||||
{
|
||||
_GLFWusercontext* context;
|
||||
_GLFWctxconfig ctxconfig;
|
||||
|
||||
context = calloc(1, sizeof(_GLFWusercontext));
|
||||
context->window = window;
|
||||
|
||||
ctxconfig = _glfw.hints.context;
|
||||
ctxconfig.share = window;
|
||||
|
||||
if(!_glfwCreateContextForFBGLX(window,&ctxconfig,&context->glx.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to create user OpenGL context");
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->makeCurrent = _glfwMakeUserContextCurrentGLX;
|
||||
context->destroy = _glfwDestroyUserContextGLX;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
@ -719,5 +790,29 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
return window->context.glx.window;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* handle, GLXFBConfig* config)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
assert(config != NULL);
|
||||
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
*config = window->context.glx.fbconfig;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#endif // _GLFW_X11
|
||||
|
||||
|
||||
@ -132,6 +132,7 @@ static void terminate(void)
|
||||
_glfw_free(error);
|
||||
}
|
||||
|
||||
_glfwPlatformDestroyTls(&_glfw.usercontextSlot);
|
||||
_glfwPlatformDestroyTls(&_glfw.contextSlot);
|
||||
_glfwPlatformDestroyTls(&_glfw.errorSlot);
|
||||
_glfwPlatformDestroyMutex(&_glfw.errorLock);
|
||||
@ -410,7 +411,8 @@ GLFWAPI int glfwInit(void)
|
||||
|
||||
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
|
||||
!_glfwPlatformCreateTls(&_glfw.errorSlot) ||
|
||||
!_glfwPlatformCreateTls(&_glfw.contextSlot))
|
||||
!_glfwPlatformCreateTls(&_glfw.contextSlot) ||
|
||||
!_glfwPlatformCreateTls(&_glfw.usercontextSlot))
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
|
||||
@ -79,6 +79,7 @@ typedef struct _GLFWmapping _GLFWmapping;
|
||||
typedef struct _GLFWjoystick _GLFWjoystick;
|
||||
typedef struct _GLFWtls _GLFWtls;
|
||||
typedef struct _GLFWmutex _GLFWmutex;
|
||||
typedef struct _GLFWusercontext _GLFWusercontext;
|
||||
|
||||
#define GL_VERSION 0x1f02
|
||||
#define GL_NONE 0
|
||||
@ -217,6 +218,7 @@ typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
|
||||
typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
|
||||
typedef const char* (APIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
|
||||
typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*);
|
||||
typedef EGLBoolean (APIENTRY * PFN_eglChooseConfig)(EGLDisplay,EGLint const*,EGLConfig*,EGLint,EGLint*);
|
||||
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
|
||||
#define eglGetConfigs _glfw.egl.GetConfigs
|
||||
#define eglGetDisplay _glfw.egl.GetDisplay
|
||||
@ -234,6 +236,8 @@ typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*);
|
||||
#define eglSwapInterval _glfw.egl.SwapInterval
|
||||
#define eglQueryString _glfw.egl.QueryString
|
||||
#define eglGetProcAddress _glfw.egl.GetProcAddress
|
||||
#define eglCreatePbufferSurface _glfw.egl.CreatePbufferSurface
|
||||
#define eglChooseConfig _glfw.egl.ChooseConfig
|
||||
|
||||
typedef EGLDisplay (APIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
|
||||
typedef EGLSurface (APIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*);
|
||||
@ -402,7 +406,6 @@ struct _GLFWwndconfig
|
||||
int ypos;
|
||||
int width;
|
||||
int height;
|
||||
const char* title;
|
||||
GLFWbool resizable;
|
||||
GLFWbool visible;
|
||||
GLFWbool decorated;
|
||||
@ -525,6 +528,29 @@ struct _GLFWcontext
|
||||
GLFW_PLATFORM_CONTEXT_STATE
|
||||
};
|
||||
|
||||
|
||||
// User Context structure
|
||||
//
|
||||
struct _GLFWusercontext
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
void (*makeCurrent)(_GLFWusercontext* context);
|
||||
void (*destroy)(_GLFWusercontext* context);
|
||||
|
||||
struct {
|
||||
EGLContext handle;
|
||||
EGLSurface surface;
|
||||
} egl;
|
||||
|
||||
struct {
|
||||
OSMesaContext handle;
|
||||
} osmesa;
|
||||
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_USER_CONTEXT_STATE
|
||||
};
|
||||
|
||||
// Window and context structure
|
||||
//
|
||||
struct _GLFWwindow
|
||||
@ -751,6 +777,7 @@ struct _GLFWplatform
|
||||
void (*waitEvents)(void);
|
||||
void (*waitEventsTimeout)(double);
|
||||
void (*postEmptyEvent)(void);
|
||||
_GLFWusercontext* (*createUserContext)(_GLFWwindow*);
|
||||
// EGL
|
||||
EGLenum (*getEGLPlatform)(EGLint**);
|
||||
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
|
||||
@ -792,6 +819,7 @@ struct _GLFWlibrary
|
||||
|
||||
_GLFWtls errorSlot;
|
||||
_GLFWtls contextSlot;
|
||||
_GLFWtls usercontextSlot;
|
||||
_GLFWmutex errorLock;
|
||||
|
||||
struct {
|
||||
@ -842,6 +870,7 @@ struct _GLFWlibrary
|
||||
PFN_eglSwapInterval SwapInterval;
|
||||
PFN_eglQueryString QueryString;
|
||||
PFN_eglGetProcAddress GetProcAddress;
|
||||
PFN_eglChooseConfig ChooseConfig;
|
||||
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
|
||||
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT;
|
||||
@ -992,6 +1021,7 @@ void _glfwTerminateEGL(void);
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
_GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window);
|
||||
#if defined(_GLFW_X11)
|
||||
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
@ -1004,6 +1034,7 @@ void _glfwTerminateOSMesa(void);
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
_GLFWusercontext* _glfwCreateUserContextOSMesa(_GLFWwindow* window);
|
||||
|
||||
GLFWbool _glfwInitVulkan(int mode);
|
||||
void _glfwTerminateVulkan(void);
|
||||
|
||||
@ -353,6 +353,54 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
|
||||
static void _glfwMakeUserContextCurrentNSGL(_GLFWusercontext* context)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
if (context)
|
||||
[context->nsgl.object makeCurrentContext];
|
||||
else
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, context);
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
static void _glfwDestroyUserContextNSGL(_GLFWusercontext* context)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
[context->nsgl.object release];
|
||||
|
||||
} // autoreleasepool
|
||||
free(context);
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextNSGL(_GLFWwindow* window)
|
||||
{
|
||||
_GLFWusercontext* context;
|
||||
|
||||
context = calloc(1, sizeof(_GLFWusercontext));
|
||||
context->window = window;
|
||||
|
||||
context->nsgl.object =
|
||||
[[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
|
||||
shareContext:window->context.nsgl.object];
|
||||
if (window->context.nsgl.object == nil)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: Failed to create OpenGL user context");
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->makeCurrent = _glfwMakeUserContextCurrentNSGL;
|
||||
context->destroy = _glfwDestroyUserContextNSGL;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -105,6 +105,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
||||
.waitEvents = _glfwWaitEventsNull,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutNull,
|
||||
.postEmptyEvent = _glfwPostEmptyEventNull,
|
||||
.createUserContext = _glfwCreateUserContextNull,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformNull,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayNull,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowNull,
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#define GLFW_NULL_CONTEXT_STATE
|
||||
#define GLFW_NULL_CURSOR_STATE
|
||||
#define GLFW_NULL_LIBRARY_CONTEXT_STATE
|
||||
#define GLFW_NULL_USER_CONTEXT_STATE
|
||||
|
||||
#define GLFW_NULL_SC_FIRST GLFW_NULL_SC_SPACE
|
||||
#define GLFW_NULL_SC_SPACE 1
|
||||
@ -280,3 +281,5 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window,
|
||||
|
||||
void _glfwPollMonitorsNull(void);
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextNull(_GLFWwindow* window);
|
||||
|
||||
|
||||
@ -747,3 +747,12 @@ VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
|
||||
return err;
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextNull(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.osmesa.handle)
|
||||
{
|
||||
return _glfwCreateUserContextOSMesa(window);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -194,9 +194,9 @@ void _glfwTerminateOSMesa(void)
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
GLFWbool _glfwCreateContextForConfigOSMesa(const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
OSMesaContext* context )
|
||||
{
|
||||
OSMesaContext share = NULL;
|
||||
const int accumBits = fbconfig->accumRedBits +
|
||||
@ -247,7 +247,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
|
||||
SET_ATTRIB(0, 0);
|
||||
|
||||
window->context.osmesa.handle =
|
||||
*context =
|
||||
OSMesaCreateContextAttribs(attribs, share);
|
||||
}
|
||||
else
|
||||
@ -259,7 +259,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.osmesa.handle =
|
||||
*context =
|
||||
OSMesaCreateContextExt(OSMESA_RGBA,
|
||||
fbconfig->depthBits,
|
||||
fbconfig->stencilBits,
|
||||
@ -267,13 +267,27 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
share);
|
||||
}
|
||||
|
||||
if (window->context.osmesa.handle == NULL)
|
||||
if (*context == NULL)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: Failed to create context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
if(!_glfwCreateContextForConfigOSMesa(ctxconfig,fbconfig,&window->context.osmesa.handle))
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentOSMesa;
|
||||
window->context.swapBuffers = swapBuffersOSMesa;
|
||||
window->context.swapInterval = swapIntervalOSMesa;
|
||||
@ -284,8 +298,62 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#undef SET_ATTRIB
|
||||
static void _glfwMakeUserContextCurrentOSMesa(_GLFWusercontext* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
if (!OSMesaMakeCurrent(context->osmesa.handle,
|
||||
context->window->context.osmesa.buffer,
|
||||
GL_UNSIGNED_BYTE,
|
||||
context->window->context.osmesa.width, context->window->context.osmesa.height))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OSMesa: Failed to make user context current");
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, context);
|
||||
}
|
||||
|
||||
static void _glfwDestroyUserContextOSMesa(_GLFWusercontext* context)
|
||||
{
|
||||
if (context->osmesa.handle)
|
||||
{
|
||||
OSMesaDestroyContext(context->osmesa.handle);
|
||||
}
|
||||
free(context);
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextOSMesa(_GLFWwindow* window)
|
||||
{
|
||||
_GLFWusercontext* context;
|
||||
_GLFWctxconfig ctxconfig;
|
||||
_GLFWfbconfig fbconfig;
|
||||
|
||||
context = calloc(1, sizeof(_GLFWusercontext));
|
||||
context->window = window;
|
||||
|
||||
ctxconfig = _glfw.hints.context;
|
||||
ctxconfig.share = window;
|
||||
|
||||
fbconfig = _glfw.hints.framebuffer;
|
||||
|
||||
if(!_glfwCreateContextForConfigOSMesa(&ctxconfig,&fbconfig,&context->osmesa.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OSMesa: Failed to create user OpenGL context");
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->makeCurrent = _glfwMakeUserContextCurrentOSMesa;
|
||||
context->destroy = _glfwDestroyUserContextOSMesa;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
#undef SET_ATTRIB
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
#define GLFW_WIN32_LIBRARY_WINDOW_STATE
|
||||
#define GLFW_WGL_CONTEXT_STATE
|
||||
#define GLFW_WGL_LIBRARY_CONTEXT_STATE
|
||||
#define GLFW_WGL_USER_CONTEXT_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
@ -65,6 +66,7 @@
|
||||
#define GLFW_COCOA_LIBRARY_WINDOW_STATE
|
||||
#define GLFW_NSGL_CONTEXT_STATE
|
||||
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE
|
||||
#define GLFW_NSGL_USER_CONTEXT_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
@ -88,6 +90,7 @@
|
||||
#define GLFW_X11_LIBRARY_WINDOW_STATE
|
||||
#define GLFW_GLX_CONTEXT_STATE
|
||||
#define GLFW_GLX_LIBRARY_CONTEXT_STATE
|
||||
#define GLFW_GLX_USER_CONTEXT_STATE
|
||||
#endif
|
||||
|
||||
#include "null_joystick.h"
|
||||
@ -165,6 +168,11 @@
|
||||
GLFW_NSGL_LIBRARY_CONTEXT_STATE \
|
||||
GLFW_GLX_LIBRARY_CONTEXT_STATE
|
||||
|
||||
#define GLFW_PLATFORM_USER_CONTEXT_STATE \
|
||||
GLFW_WGL_USER_CONTEXT_STATE \
|
||||
GLFW_NSGL_USER_CONTEXT_STATE \
|
||||
GLFW_GLX_USER_CONTEXT_STATE
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define GLFW_BUILD_WIN32_THREAD
|
||||
#else
|
||||
|
||||
@ -536,47 +536,17 @@ void _glfwTerminateWGL(void)
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
// Create the OpenGL or OpenGL ES context for the given HDC
|
||||
//
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
GLFWbool _glfwCreateContextForDCWGL(HDC dc, const _GLFWctxconfig* ctxconfig, HGLRC* context)
|
||||
{
|
||||
int attribs[40];
|
||||
int pixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC share = NULL;
|
||||
|
||||
*context = NULL;
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.wgl.handle;
|
||||
|
||||
window->context.wgl.dc = GetDC(window->win32.handle);
|
||||
if (!window->context.wgl.dc)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve DC for window");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig);
|
||||
if (!pixelFormat)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
pixelFormat, sizeof(pfd), &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve PFD for selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
@ -690,9 +660,9 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
|
||||
SET_ATTRIB(0, 0);
|
||||
|
||||
window->context.wgl.handle =
|
||||
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
|
||||
if (!window->context.wgl.handle)
|
||||
*context =
|
||||
wglCreateContextAttribsARB(dc, share, attribs);
|
||||
if (!(*context))
|
||||
{
|
||||
const DWORD error = GetLastError();
|
||||
|
||||
@ -742,8 +712,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
}
|
||||
else
|
||||
{
|
||||
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
||||
if (!window->context.wgl.handle)
|
||||
*context = wglCreateContext(dc);
|
||||
if (!(*context) )
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL context");
|
||||
@ -752,7 +722,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
|
||||
if (share)
|
||||
{
|
||||
if (!wglShareLists(share, window->context.wgl.handle))
|
||||
if (!wglShareLists(share, *context))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to enable sharing with specified OpenGL context");
|
||||
@ -761,6 +731,50 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int pixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
window->context.wgl.dc = GetDC(window->win32.handle);
|
||||
if (!window->context.wgl.dc)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve DC for window");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig);
|
||||
if (!pixelFormat)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
pixelFormat, sizeof(pfd), &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve PFD for selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if(!_glfwCreateContextForDCWGL( window->context.wgl.dc, ctxconfig, &window->context.wgl.handle ))
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentWGL;
|
||||
window->context.swapBuffers = swapBuffersWGL;
|
||||
window->context.swapInterval = swapIntervalWGL;
|
||||
@ -771,6 +785,65 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static void _glfwMakeUserContextCurrentWGL(_GLFWusercontext* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
if (!wglMakeCurrent(context->window->context.wgl.dc,context->wgl.handle))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to make user context current");
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wglMakeCurrent(NULL, NULL))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to clear current user context");
|
||||
}
|
||||
}
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.usercontextSlot, context);
|
||||
}
|
||||
|
||||
static void _glfwDestroyUserContextWGL(_GLFWusercontext* context)
|
||||
{
|
||||
wglDeleteContext(context->wgl.handle);
|
||||
free(context);
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextWGL(_GLFWwindow* window)
|
||||
{
|
||||
_GLFWusercontext* context;
|
||||
_GLFWctxconfig ctxconfig;
|
||||
|
||||
context = calloc(1, sizeof(_GLFWusercontext));
|
||||
context->window = window;
|
||||
|
||||
ctxconfig = _glfw.hints.context;
|
||||
ctxconfig.share = window;
|
||||
|
||||
if (!_glfwCreateContextForDCWGL(window->context.wgl.dc, &ctxconfig, &context->wgl.handle))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to create user OpenGL context");
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->makeCurrent = _glfwMakeUserContextCurrentWGL;
|
||||
context->destroy = _glfwDestroyUserContextWGL;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#undef SET_ATTRIB
|
||||
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||
|
||||
@ -664,6 +664,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
||||
.waitEvents = _glfwWaitEventsWin32,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutWin32,
|
||||
.postEmptyEvent = _glfwPostEmptyEventWin32,
|
||||
.createUserContext = _glfwCreateUserContextWin32,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformWin32,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayWin32,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowWin32,
|
||||
|
||||
@ -307,6 +307,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
||||
|
||||
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
||||
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
|
||||
#define GLFW_WGL_USER_CONTEXT_STATE _GLFWusercontextWGL wgl;
|
||||
|
||||
|
||||
// WGL-specific per-context data
|
||||
@ -350,6 +351,14 @@ typedef struct _GLFWlibraryWGL
|
||||
GLFWbool ARB_context_flush_control;
|
||||
} _GLFWlibraryWGL;
|
||||
|
||||
// WGL-specific per-usercontext data
|
||||
//
|
||||
typedef struct _GLFWusercontextWGL
|
||||
{
|
||||
HDC dc;
|
||||
HGLRC handle;
|
||||
} _GLFWusercontextWGL;
|
||||
|
||||
// Win32-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowWin32
|
||||
@ -565,3 +574,5 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextWin32(_GLFWwindow* window);
|
||||
_GLFWusercontext* _glfwCreateUserContextWGL(_GLFWwindow* window);
|
||||
|
||||
@ -1377,7 +1377,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
frameHeight = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(window->title);
|
||||
if (!wideTitle)
|
||||
return GLFW_FALSE;
|
||||
|
||||
@ -2562,6 +2562,28 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance,
|
||||
return err;
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextWin32(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.wgl.handle)
|
||||
{
|
||||
return _glfwCreateUserContextWGL(window);
|
||||
}
|
||||
else if (window->context.egl.handle)
|
||||
{
|
||||
return _glfwCreateUserContextEGL(window);
|
||||
}
|
||||
else if (window->context.osmesa.handle)
|
||||
{
|
||||
return _glfwCreateUserContextOSMesa(window);
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
@ -208,7 +208,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
|
||||
wndconfig.width = width;
|
||||
wndconfig.height = height;
|
||||
wndconfig.title = title;
|
||||
ctxconfig.share = (_GLFWwindow*) share;
|
||||
|
||||
if (!_glfwIsValidContextConfig(&ctxconfig))
|
||||
|
||||
@ -510,6 +510,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
||||
.waitEvents = _glfwWaitEventsWayland,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutWayland,
|
||||
.postEmptyEvent = _glfwPostEmptyEventWayland,
|
||||
.createUserContext = _glfwCreateUserContextWayland,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformWayland,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayWayland,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowWayland,
|
||||
|
||||
@ -690,6 +690,8 @@ void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||
void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window);
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextWayland(_GLFWwindow* window);
|
||||
|
||||
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
||||
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
||||
|
||||
|
||||
@ -3324,6 +3324,19 @@ VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance,
|
||||
return err;
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextWayland(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.egl.handle)
|
||||
{
|
||||
return _glfwCreateUserContextEGL(window);
|
||||
}
|
||||
else if (window->context.osmesa.handle)
|
||||
{
|
||||
return _glfwCreateUserContextOSMesa(window);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
|
||||
@ -1241,6 +1241,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
||||
.waitEvents = _glfwWaitEventsX11,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutX11,
|
||||
.postEmptyEvent = _glfwPostEmptyEventX11,
|
||||
.createUserContext = _glfwCreateUserContextX11,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformX11,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayX11,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowX11,
|
||||
|
||||
@ -462,7 +462,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
||||
|
||||
#define GLFW_GLX_CONTEXT_STATE _GLFWcontextGLX glx;
|
||||
#define GLFW_GLX_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
|
||||
|
||||
#define GLFW_GLX_USER_CONTEXT_STATE _GLFWusercontextGLX glx;
|
||||
|
||||
// GLX-specific per-context data
|
||||
//
|
||||
@ -470,6 +470,7 @@ typedef struct _GLFWcontextGLX
|
||||
{
|
||||
GLXContext handle;
|
||||
GLXWindow window;
|
||||
GLXFBConfig fbconfig;
|
||||
} _GLFWcontextGLX;
|
||||
|
||||
// GLX-specific global data
|
||||
@ -518,6 +519,13 @@ typedef struct _GLFWlibraryGLX
|
||||
GLFWbool ARB_context_flush_control;
|
||||
} _GLFWlibraryGLX;
|
||||
|
||||
// GLX-specific per usercontext data
|
||||
//
|
||||
typedef struct _GLFWusercontextGLX
|
||||
{
|
||||
GLXContext handle;
|
||||
} _GLFWusercontextGLX;
|
||||
|
||||
// X11-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowX11
|
||||
@ -1002,3 +1010,5 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth);
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextX11(_GLFWwindow* window);
|
||||
_GLFWusercontext* _glfwCreateUserContextGLX(_GLFWwindow* window);
|
||||
|
||||
@ -754,13 +754,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
const char* resourceName = getenv("RESOURCE_NAME");
|
||||
if (resourceName && strlen(resourceName))
|
||||
hint->res_name = (char*) resourceName;
|
||||
else if (strlen(wndconfig->title))
|
||||
hint->res_name = (char*) wndconfig->title;
|
||||
else if (strlen(window->title))
|
||||
hint->res_name = (char*) window->title;
|
||||
else
|
||||
hint->res_name = (char*) "glfw-application";
|
||||
|
||||
if (strlen(wndconfig->title))
|
||||
hint->res_class = (char*) wndconfig->title;
|
||||
if (strlen(window->title))
|
||||
hint->res_class = (char*) window->title;
|
||||
else
|
||||
hint->res_class = (char*) "GLFW-Application";
|
||||
}
|
||||
@ -780,7 +780,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
if (_glfw.x11.im)
|
||||
_glfwCreateInputContextX11(window);
|
||||
|
||||
_glfwSetWindowTitleX11(window, wndconfig->title);
|
||||
_glfwSetWindowTitleX11(window, window->title);
|
||||
_glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos);
|
||||
_glfwGetWindowSizeX11(window, &window->x11.width, &window->x11.height);
|
||||
|
||||
@ -3282,6 +3282,24 @@ VkResult _glfwCreateWindowSurfaceX11(VkInstance instance,
|
||||
}
|
||||
}
|
||||
|
||||
_GLFWusercontext* _glfwCreateUserContextX11(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.glx.handle)
|
||||
{
|
||||
return _glfwCreateUserContextGLX(window);
|
||||
}
|
||||
else if (window->context.egl.handle)
|
||||
{
|
||||
return _glfwCreateUserContextEGL(window);
|
||||
}
|
||||
else if (window->context.osmesa.handle)
|
||||
{
|
||||
return _glfwCreateUserContextOSMesa(window);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
|
||||
@ -28,6 +28,7 @@ add_executable(iconify iconify.c ${GETOPT} ${GLAD_GL})
|
||||
add_executable(monitors monitors.c ${GETOPT} ${GLAD_GL})
|
||||
add_executable(reopen reopen.c ${GLAD_GL})
|
||||
add_executable(cursor cursor.c ${GLAD_GL})
|
||||
add_executable(usercontext usercontext.c ${TINYCTHREAD} ${GLAD_GL})
|
||||
|
||||
add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD} ${GLAD_GL})
|
||||
add_executable(gamma WIN32 MACOSX_BUNDLE gamma.c ${GLAD_GL})
|
||||
@ -51,7 +52,7 @@ endif()
|
||||
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads
|
||||
timeout title triangle-vulkan window)
|
||||
set(CONSOLE_BINARIES allocator clipboard events msaa glfwinfo iconify monitors
|
||||
reopen cursor)
|
||||
reopen cursor usercontext)
|
||||
|
||||
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||
C_STANDARD 99
|
||||
|
||||
200
tests/usercontext.c
Normal file
200
tests/usercontext.c
Normal file
@ -0,0 +1,200 @@
|
||||
//========================================================================
|
||||
// User context test
|
||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
//
|
||||
// This test is intended to verify whether the OpenGL user context part of
|
||||
// the GLFW API is able to be used from multiple threads
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "tinycthread.h"
|
||||
|
||||
#define GLAD_GL_IMPLEMENTATION
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static int thread_main(void* data)
|
||||
{
|
||||
GLFWusercontext* usercontext = (GLFWusercontext*)data;
|
||||
|
||||
/* set the user context current */
|
||||
glfwMakeUserContextCurrent(usercontext);
|
||||
|
||||
if (glfwGetCurrentContext() != NULL)
|
||||
{
|
||||
fprintf(stderr, "Current glfw window context not NULL after glfwMakeUserContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
if (glfwGetCurrentUserContext() != usercontext)
|
||||
{
|
||||
fprintf(stderr, "Current user context not correct after glfwMakeUserContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set the user context to NULL */
|
||||
glfwMakeUserContextCurrent(NULL);
|
||||
if (glfwGetCurrentUserContext() != NULL)
|
||||
{
|
||||
fprintf(stderr, "Current user context not NULL after glfwMakeContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
GLFWwindow* window;
|
||||
GLFWusercontext* usercontext;
|
||||
thrd_t thread_id;
|
||||
int result, count;
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
/* Initialize the library */
|
||||
if (!glfwInit())
|
||||
return -1;
|
||||
|
||||
/* Create a windowed mode window and its OpenGL context */
|
||||
window = glfwCreateWindow(640, 480, "User Context", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make the window's context current */
|
||||
glfwMakeContextCurrent(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
|
||||
/* make a new context */
|
||||
usercontext = glfwCreateUserContext(window);
|
||||
if (!usercontext)
|
||||
{
|
||||
fprintf(stderr, "Failed to create user context\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set the user context current */
|
||||
glfwMakeUserContextCurrent(usercontext);
|
||||
|
||||
if (glfwGetCurrentContext() != NULL)
|
||||
{
|
||||
fprintf(stderr, "Current glfw window context not NULL after glfwMakeUserContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
if (glfwGetCurrentUserContext() != usercontext)
|
||||
{
|
||||
fprintf(stderr, "Current user context not correct after glfwMakeUserContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set the window context current */
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
if (glfwGetCurrentUserContext() != NULL)
|
||||
{
|
||||
fprintf(stderr, "Current user context not NULL after glfwMakeContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
if (glfwGetCurrentContext() != window)
|
||||
{
|
||||
fprintf(stderr, "Current glfw window context not correct after glfwMakeContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glClearColor( 0.4f, 0.3f, 0.4f, 1.0f );
|
||||
|
||||
// Launch a thread which should create and use the usercontext
|
||||
if (thrd_create(&thread_id, thread_main, usercontext ) !=
|
||||
thrd_success)
|
||||
{
|
||||
fprintf(stderr, "Failed to create secondary thread\n");
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Loop 60 times or until the user closes the window */
|
||||
count = 0;
|
||||
while (!glfwWindowShouldClose(window) && count++ < 60)
|
||||
{
|
||||
/* Render here */
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
/* Swap front and back buffers */
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
/* Poll for and process events */
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
thrd_join(thread_id, &result);
|
||||
|
||||
/* One more test now the thread has joined */
|
||||
|
||||
/* set the user context current */
|
||||
glfwMakeUserContextCurrent(usercontext);
|
||||
|
||||
if (glfwGetCurrentContext() != NULL)
|
||||
{
|
||||
fprintf(stderr, "Current glfw window context not NULL after glfwMakeUserContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
if (glfwGetCurrentUserContext() != usercontext)
|
||||
{
|
||||
fprintf(stderr, "Current user context not correct after glfwMakeUserContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set the user context to NULL */
|
||||
glfwMakeUserContextCurrent(NULL);
|
||||
if (glfwGetCurrentUserContext() != NULL)
|
||||
{
|
||||
fprintf(stderr, "Current user context not NULL after glfwMakeContextCurrent\n");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwDestroyUserContext(usercontext);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user