mirror of
https://github.com/glfw/glfw.git
synced 2026-09-19 15:25:50 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a49ef0a00 | |||
| b1d4b6a595 | |||
| ad12b97acd | |||
| 835dc3d327 | |||
| 6a9fd2e13f | |||
| e53538010a | |||
| ec28696994 | |||
| 0af3bf3b36 | |||
| 8552152f80 | |||
| 85172703db | |||
| d33084447d | |||
| 50f3979dfd | |||
| 977e2b51b0 | |||
| fbe8ae993c | |||
| 487e0419a7 | |||
| 0938462616 |
@@ -7,11 +7,6 @@ branches:
|
|||||||
- master
|
- master
|
||||||
- 3.3-stable
|
- 3.3-stable
|
||||||
skip_tags: true
|
skip_tags: true
|
||||||
skip_commits:
|
|
||||||
files:
|
|
||||||
- README.md
|
|
||||||
- LICENSE.md
|
|
||||||
- docs/*
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- GENERATOR: MinGW Makefiles
|
- GENERATOR: MinGW Makefiles
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(GLFW VERSION 3.3.1 LANGUAGES C)
|
project(GLFW VERSION 3.3.2 LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||||
|
|
||||||
|
|||||||
@@ -118,39 +118,16 @@ information on what to include when reporting a bug.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- Bugfix: The CMake config-file package used an absolute path and was not
|
- [Win32] Bugfix: Super key was not released after Win+V hotkey (#1622)
|
||||||
relocatable (#1470)
|
- [Win32] Bugfix: `glfwGetKeyName` could access out of bounds and return an
|
||||||
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
|
invalid pointer
|
||||||
- Bugfix: Compiling with -Wextra-semi caused warnings (#1440)
|
- [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN`
|
||||||
- Bugfix: Built-in mappings failed because some OEMs re-used VID/PID (#1583)
|
(#1623)
|
||||||
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
|
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||||
symbol redefinition (#1524)
|
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||||
- [Win32] Bugfix: The cursor position event was emitted before its cursor enter
|
- [X11] Bugfix: `glfwFocusWindow` could terminate on older WMs or without a WM
|
||||||
event (#1490)
|
- [X11] Bugfix: Creating an undecorated window could fail with BadMatch (#1620)
|
||||||
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
|
- [X11] Bugfix: Querying a disconnected monitor could segfault (#1602)
|
||||||
window (#1499)
|
|
||||||
- [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions
|
|
||||||
- [Cocoa] Removed dependency on the CoreVideo framework
|
|
||||||
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
|
||||||
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
|
||||||
(#1412)
|
|
||||||
- [Cocoa] Bugfix: Event processing before window creation would assert (#1543)
|
|
||||||
- [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS
|
|
||||||
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
|
|
||||||
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
|
||||||
(#1462,#1528)
|
|
||||||
- [X11] Bugfix: Decorations could not be enabled after window creation (#1566)
|
|
||||||
- [X11] Bugfix: Content scale fallback value could be inconsistent (#1578)
|
|
||||||
- [X11] Bugfix: `glfwMaximizeWindow` had no effect on hidden windows
|
|
||||||
- [X11] Bugfix: Clearing `GLFW_FLOATING` on a hidden window caused invalid read
|
|
||||||
- [X11] Bugfix: Changing `GLFW_FLOATING` on a hidden window could silently fail
|
|
||||||
- [X11] Bugfix: Disabled cursor mode was interrupted by indicator windows
|
|
||||||
- [X11] Bugfix: Monitor physical dimensions could be reported as zero mm
|
|
||||||
- [X11] Bugfix: Window position events were not emitted during resizing (#1613)
|
|
||||||
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
|
||||||
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
|
||||||
macOS versions (#1442)
|
|
||||||
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
|
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
@@ -244,6 +221,7 @@ skills.
|
|||||||
- Cem Karan
|
- Cem Karan
|
||||||
- Osman Keskin
|
- Osman Keskin
|
||||||
- Josh Kilmer
|
- Josh Kilmer
|
||||||
|
- Byunghoon Kim
|
||||||
- Cameron King
|
- Cameron King
|
||||||
- Peter Knut
|
- Peter Knut
|
||||||
- Christoph Kubisch
|
- Christoph Kubisch
|
||||||
@@ -251,6 +229,7 @@ skills.
|
|||||||
- Rokas Kupstys
|
- Rokas Kupstys
|
||||||
- Konstantin Käfer
|
- Konstantin Käfer
|
||||||
- Eric Larson
|
- Eric Larson
|
||||||
|
- Francis Lecavalier
|
||||||
- Robin Leffmann
|
- Robin Leffmann
|
||||||
- Glenn Lewis
|
- Glenn Lewis
|
||||||
- Shane Liesegang
|
- Shane Liesegang
|
||||||
@@ -259,6 +238,7 @@ skills.
|
|||||||
- Eyal Lotem
|
- Eyal Lotem
|
||||||
- Aaron Loucks
|
- Aaron Loucks
|
||||||
- Luflosi
|
- Luflosi
|
||||||
|
- lukect
|
||||||
- Tristam MacDonald
|
- Tristam MacDonald
|
||||||
- Hans Mackowiak
|
- Hans Mackowiak
|
||||||
- Дмитри Малышев
|
- Дмитри Малышев
|
||||||
|
|||||||
+40
-84
@@ -78,6 +78,11 @@ compiler that the GLFW functions are defined in a DLL.
|
|||||||
The following macros control which OpenGL or OpenGL ES API header is included.
|
The following macros control which OpenGL or OpenGL ES API header is included.
|
||||||
Only one of these may be defined at a time.
|
Only one of these may be defined at a time.
|
||||||
|
|
||||||
|
@note GLFW does not provide any of the API headers mentioned below. They are
|
||||||
|
provided by your development environment or your OpenGL, OpenGL ES or Vulkan
|
||||||
|
SDK, and most of them can be downloaded from the
|
||||||
|
[Khronos Registry](https://www.khronos.org/registry/).
|
||||||
|
|
||||||
@anchor GLFW_INCLUDE_GLCOREARB
|
@anchor GLFW_INCLUDE_GLCOREARB
|
||||||
__GLFW_INCLUDE_GLCOREARB__ makes the GLFW header include the modern
|
__GLFW_INCLUDE_GLCOREARB__ makes the GLFW header include the modern
|
||||||
`GL/glcorearb.h` header (`OpenGL/gl3.h` on macOS) instead of the regular OpenGL
|
`GL/glcorearb.h` header (`OpenGL/gl3.h` on macOS) instead of the regular OpenGL
|
||||||
@@ -129,10 +134,6 @@ header selected above. This should only be used with the standard OpenGL header
|
|||||||
and only for compatibility with legacy code. GLU has been deprecated and should
|
and only for compatibility with legacy code. GLU has been deprecated and should
|
||||||
not be used in new code.
|
not be used in new code.
|
||||||
|
|
||||||
@note GLFW does not provide any of the API headers mentioned above. They must
|
|
||||||
be provided by your development environment or your OpenGL, OpenGL ES or Vulkan
|
|
||||||
SDK.
|
|
||||||
|
|
||||||
@note None of these macros may be defined during the compilation of GLFW itself.
|
@note None of these macros may be defined during the compilation of GLFW itself.
|
||||||
If your build includes GLFW and you define any these in your build files, make
|
If your build includes GLFW and you define any these in your build files, make
|
||||||
sure they are not applied to the GLFW sources.
|
sure they are not applied to the GLFW sources.
|
||||||
@@ -166,16 +167,11 @@ must also explicitly link with `gdi32`. Other toolchains including MinGW-w64
|
|||||||
include it in the set of default libraries along with other dependencies like
|
include it in the set of default libraries along with other dependencies like
|
||||||
`user32` and `kernel32`.
|
`user32` and `kernel32`.
|
||||||
|
|
||||||
If you are using GLU, you must also link with `glu32`.
|
|
||||||
|
|
||||||
The link library for the GLFW DLL is named `glfw3dll`. When compiling an
|
The link library for the GLFW DLL is named `glfw3dll`. When compiling an
|
||||||
application that uses the DLL version of GLFW, you need to define the @ref
|
application that uses the DLL version of GLFW, you need to define the @ref
|
||||||
GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done
|
GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done
|
||||||
either with a compiler switch or by defining it in your source code.
|
either with a compiler switch or by defining it in your source code.
|
||||||
|
|
||||||
An application using the GLFW DLL does not need to link against any of its
|
|
||||||
dependencies, but you still have to link against `glu32` if it uses GLU.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_cmake_source With CMake and GLFW source
|
@subsection build_link_cmake_source With CMake and GLFW source
|
||||||
|
|
||||||
@@ -196,52 +192,39 @@ set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|||||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Then add the root directory of the GLFW source tree to your project. This
|
Add the root directory of the GLFW source tree to your project. This will add
|
||||||
will add the `glfw` target and the necessary cache variables to your project.
|
the `glfw` target to your project.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
add_subdirectory(path/to/glfw)
|
add_subdirectory(path/to/glfw)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Once GLFW has been added to the project, link against it with the `glfw` target.
|
Once GLFW has been added, link your application against the `glfw` target.
|
||||||
This adds all link-time dependencies of GLFW as it is currently configured,
|
This adds the GLFW library and its link-time dependencies as it is currently
|
||||||
the include directory for the GLFW header and, when applicable, the @ref
|
configured, the include directory for the GLFW header and, when applicable, the
|
||||||
GLFW_DLL macro.
|
@ref GLFW_DLL macro.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_link_libraries(myapp glfw)
|
target_link_libraries(myapp glfw)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
|
Note that the `glfw` target does not depend on OpenGL, as GLFW loads any OpenGL,
|
||||||
OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
|
OpenGL ES or Vulkan libraries it needs at runtime. If your application calls
|
||||||
If your application calls OpenGL directly, instead of using a modern
|
OpenGL directly, instead of using a modern
|
||||||
[extension loader library](@ref context_glext_auto) you can find it by requiring
|
[extension loader library](@ref context_glext_auto), use the OpenGL CMake
|
||||||
the OpenGL package.
|
package.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If OpenGL is found, the `OPENGL_FOUND` variable is true and the
|
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
||||||
`OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used.
|
library and include directory paths. Link against this like above.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_include_directories(myapp PUBLIC ${OPENGL_INCLUDE_DIR})
|
target_link_libraries(myapp OpenGL::GL)
|
||||||
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The OpenGL CMake package also looks for GLU. If GLU is found, the
|
|
||||||
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and
|
|
||||||
`OPENGL_glu_LIBRARY` cache variables can be used.
|
|
||||||
|
|
||||||
@code{.cmake}
|
|
||||||
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
||||||
|
|
||||||
@@ -257,44 +240,30 @@ find_package(glfw3 3.3 REQUIRED)
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Once GLFW has been added to the project, link against it with the `glfw` target.
|
Once GLFW has been added to the project, link against it with the `glfw` target.
|
||||||
This adds all link-time dependencies of GLFW as it is currently configured,
|
This adds the GLFW library and its link-time dependencies, the include directory
|
||||||
the include directory for the GLFW header and, when applicable, the @ref
|
for the GLFW header and, when applicable, the @ref GLFW_DLL macro.
|
||||||
GLFW_DLL macro.
|
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_link_libraries(myapp glfw)
|
target_link_libraries(myapp glfw)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
|
Note that the `glfw` target does not depend on OpenGL, as GLFW loads any OpenGL,
|
||||||
OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
|
OpenGL ES or Vulkan libraries it needs at runtime. If your application calls
|
||||||
If your application calls OpenGL directly, instead of using a modern
|
OpenGL directly, instead of using a modern
|
||||||
[extension loader library](@ref context_glext_auto) you can find it by requiring
|
[extension loader library](@ref context_glext_auto), use the OpenGL CMake
|
||||||
the OpenGL package.
|
package.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If OpenGL is found, the `OPENGL_FOUND` variable is true and the
|
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
||||||
`OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used.
|
library and include directory paths. Link against this like above.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_include_directories(myapp PUBLIC ${OPENGL_INCLUDE_DIR})
|
target_link_libraries(myapp OpenGL::GL)
|
||||||
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The OpenGL CMake package also looks for GLU. If GLU is found, the
|
|
||||||
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and
|
|
||||||
`OPENGL_glu_LIBRARY` cache variables can be used.
|
|
||||||
|
|
||||||
@code{.cmake}
|
|
||||||
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
||||||
|
|
||||||
@@ -309,42 +278,31 @@ A typical compile and link command-line when using the static version of the
|
|||||||
GLFW library may look like this:
|
GLFW library may look like this:
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3`
|
cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --static --libs glfw3)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If you are using the shared version of the GLFW library, omit the `--static`
|
If you are using the shared version of the GLFW library, omit the `--static`
|
||||||
flag.
|
flag.
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`
|
cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --libs glfw3)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
You can also use the `glfw3.pc` file without installing it first, by using the
|
You can also use the `glfw3.pc` file without installing it first, by using the
|
||||||
`PKG_CONFIG_PATH` environment variable.
|
`PKG_CONFIG_PATH` environment variable.
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`
|
env PKG_CONFIG_PATH=path/to/glfw/src cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --libs glfw3)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The dependencies do not include OpenGL or GLU, as GLFW loads any OpenGL, OpenGL
|
The dependencies do not include OpenGL, as GLFW loads any OpenGL, OpenGL ES or
|
||||||
ES or Vulkan libraries it needs at runtime and does not use GLU. On macOS, GLU
|
Vulkan libraries it needs at runtime. If your application calls OpenGL
|
||||||
is built into the OpenGL framework, so if you need GLU you don't need to do
|
directly, instead of using a modern
|
||||||
anything extra. If you need GLU and are using Linux or BSD, you should add the
|
[extension loader library](@ref context_glext_auto), you should add the `gl`
|
||||||
`glu` pkg-config package.
|
pkg-config package.
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu`
|
cc $(pkg-config --cflags glfw3 gl) -o myprog myprog.c $(pkg-config --libs glfw3 gl)
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
If you are using the static version of the GLFW library, make sure you don't
|
|
||||||
link statically against GLU.
|
|
||||||
|
|
||||||
@code{.sh}
|
|
||||||
cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --static --libs glfw3` `pkg-config --libs glu`
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@@ -378,9 +336,7 @@ for `-lglfw`.
|
|||||||
Note that you do not add the `.framework` extension to a framework when linking
|
Note that you do not add the `.framework` extension to a framework when linking
|
||||||
against it from the command-line.
|
against it from the command-line.
|
||||||
|
|
||||||
The OpenGL framework contains both the OpenGL and GLU APIs, so there is nothing
|
@note Your machine may have `libGL.*.dylib` style OpenGL library, but that is
|
||||||
special to do when using GLU. Also note that even though your machine may have
|
for the X Window System and will not work with the macOS native version of GLFW.
|
||||||
`libGL`-style OpenGL libraries, they are for use with the X Window System and
|
|
||||||
will _not_ work with the macOS native version of GLFW.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
+4
-4
@@ -266,10 +266,10 @@ surfaces on Microsoft Windows. If any of these extensions are not available,
|
|||||||
@ref glfwGetRequiredInstanceExtensions will return an empty list and window
|
@ref glfwGetRequiredInstanceExtensions will return an empty list and window
|
||||||
surface creation will fail.
|
surface creation will fail.
|
||||||
|
|
||||||
GLFW uses the `VK_KHR_surface` and `VK_MVK_macos_surface` extensions to create
|
GLFW uses the `VK_KHR_surface` and either the `VK_MVK_macos_surface` or
|
||||||
surfaces on macOS. If any of these extensions are not available, @ref
|
`VK_EXT_metal_surface` extensions to create surfaces on macOS. If any of these
|
||||||
glfwGetRequiredInstanceExtensions will return an empty list and window surface
|
extensions are not available, @ref glfwGetRequiredInstanceExtensions will
|
||||||
creation will fail.
|
return an empty list and window surface creation will fail.
|
||||||
|
|
||||||
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
|
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
|
||||||
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
|
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ extern "C" {
|
|||||||
* API changes.
|
* API changes.
|
||||||
* @ingroup init
|
* @ingroup init
|
||||||
*/
|
*/
|
||||||
#define GLFW_VERSION_REVISION 1
|
#define GLFW_VERSION_REVISION 2
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! @brief One.
|
/*! @brief One.
|
||||||
@@ -5677,8 +5677,9 @@ GLFWAPI int glfwVulkanSupported(void);
|
|||||||
* returned array, as it is an error to specify an extension more than once in
|
* returned array, as it is an error to specify an extension more than once in
|
||||||
* the `VkInstanceCreateInfo` struct.
|
* the `VkInstanceCreateInfo` struct.
|
||||||
*
|
*
|
||||||
* @remark @macos This function currently only supports the
|
* @remark @macos This function currently supports either the
|
||||||
* `VK_MVK_macos_surface` extension from MoltenVK.
|
* `VK_MVK_macos_surface` extension from MoltenVK or `VK_EXT_metal_surface`
|
||||||
|
* extension.
|
||||||
*
|
*
|
||||||
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||||
* should not free it yourself. It is guaranteed to be valid only until the
|
* should not free it yourself. It is guaranteed to be valid only until the
|
||||||
|
|||||||
@@ -463,6 +463,32 @@ static GLFWbool initializeTIS(void)
|
|||||||
@end // GLFWApplicationDelegate
|
@end // GLFWApplicationDelegate
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* _glfwLoadLocalVulkanLoaderNS(void)
|
||||||
|
{
|
||||||
|
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||||
|
if (!bundle)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CFURLRef url =
|
||||||
|
CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib"));
|
||||||
|
if (!url)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
void* handle = NULL;
|
||||||
|
|
||||||
|
if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1))
|
||||||
|
handle = _glfw_dlopen(path);
|
||||||
|
|
||||||
|
CFRelease(url);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ typedef void* id;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||||
|
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
|
||||||
|
|
||||||
typedef struct VkMacOSSurfaceCreateInfoMVK
|
typedef struct VkMacOSSurfaceCreateInfoMVK
|
||||||
{
|
{
|
||||||
@@ -70,7 +71,16 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
|
|||||||
const void* pView;
|
const void* pView;
|
||||||
} VkMacOSSurfaceCreateInfoMVK;
|
} VkMacOSSurfaceCreateInfoMVK;
|
||||||
|
|
||||||
|
typedef struct VkMetalSurfaceCreateInfoEXT
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkMetalSurfaceCreateFlagsEXT flags;
|
||||||
|
const void* pLayer;
|
||||||
|
} VkMetalSurfaceCreateInfoEXT;
|
||||||
|
|
||||||
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
|
||||||
#include "posix_thread.h"
|
#include "posix_thread.h"
|
||||||
#include "cocoa_joystick.h"
|
#include "cocoa_joystick.h"
|
||||||
@@ -197,3 +207,5 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
|||||||
|
|
||||||
float _glfwTransformYNS(float y);
|
float _glfwTransformYNS(float y);
|
||||||
|
|
||||||
|
void* _glfwLoadLocalVulkanLoaderNS(void);
|
||||||
|
|
||||||
|
|||||||
+59
-22
@@ -1516,6 +1516,13 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
|
if (scancode < 0 || scancode > 0xff ||
|
||||||
|
_glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const int key = _glfw.ns.keycodes[scancode];
|
const int key = _glfw.ns.keycodes[scancode];
|
||||||
|
|
||||||
UInt32 deadKeyState = 0;
|
UInt32 deadKeyState = 0;
|
||||||
@@ -1689,11 +1696,16 @@ const char* _glfwPlatformGetClipboardString(void)
|
|||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (!_glfw.vk.KHR_surface || !_glfw.vk.MVK_macos_surface)
|
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
|
||||||
return;
|
{
|
||||||
|
extensions[0] = "VK_KHR_surface";
|
||||||
extensions[0] = "VK_KHR_surface";
|
extensions[1] = "VK_EXT_metal_surface";
|
||||||
extensions[1] = "VK_MVK_macos_surface";
|
}
|
||||||
|
else if (_glfw.vk.KHR_surface && _glfw.vk.MVK_macos_surface)
|
||||||
|
{
|
||||||
|
extensions[0] = "VK_KHR_surface";
|
||||||
|
extensions[1] = "VK_MVK_macos_surface";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
@@ -1711,19 +1723,6 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
|
||||||
VkResult err;
|
|
||||||
VkMacOSSurfaceCreateInfoMVK sci;
|
|
||||||
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
|
|
||||||
|
|
||||||
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
|
|
||||||
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
|
|
||||||
if (!vkCreateMacOSSurfaceMVK)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
|
|
||||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: Dynamically load Core Animation to avoid adding an extra
|
// HACK: Dynamically load Core Animation to avoid adding an extra
|
||||||
// dependency for the majority who don't use MoltenVK
|
// dependency for the majority who don't use MoltenVK
|
||||||
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
|
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
|
||||||
@@ -1749,11 +1748,49 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
[window->ns.view setLayer:window->ns.layer];
|
[window->ns.view setLayer:window->ns.layer];
|
||||||
[window->ns.view setWantsLayer:YES];
|
[window->ns.view setWantsLayer:YES];
|
||||||
|
|
||||||
memset(&sci, 0, sizeof(sci));
|
VkResult err;
|
||||||
sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
|
||||||
sci.pView = window->ns.view;
|
if (_glfw.vk.EXT_metal_surface)
|
||||||
|
{
|
||||||
|
VkMetalSurfaceCreateInfoEXT sci;
|
||||||
|
|
||||||
|
PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT;
|
||||||
|
vkCreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateMetalSurfaceEXT");
|
||||||
|
if (!vkCreateMetalSurfaceEXT)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Cocoa: Vulkan instance missing VK_EXT_metal_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||||
|
sci.pLayer = window->ns.layer;
|
||||||
|
|
||||||
|
err = vkCreateMetalSurfaceEXT(instance, &sci, allocator, surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VkMacOSSurfaceCreateInfoMVK sci;
|
||||||
|
|
||||||
|
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
|
||||||
|
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
|
||||||
|
if (!vkCreateMacOSSurfaceMVK)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||||
|
sci.pView = window->ns.view;
|
||||||
|
|
||||||
|
err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
|
||||||
|
}
|
||||||
|
|
||||||
err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ typedef enum VkStructureType
|
|||||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
||||||
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
||||||
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
||||||
|
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
|
||||||
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VkStructureType;
|
} VkStructureType;
|
||||||
|
|
||||||
@@ -556,6 +557,7 @@ struct _GLFWlibrary
|
|||||||
GLFWbool KHR_win32_surface;
|
GLFWbool KHR_win32_surface;
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
GLFWbool MVK_macos_surface;
|
GLFWbool MVK_macos_surface;
|
||||||
|
GLFWbool EXT_metal_surface;
|
||||||
#elif defined(_GLFW_X11)
|
#elif defined(_GLFW_X11)
|
||||||
GLFWbool KHR_xlib_surface;
|
GLFWbool KHR_xlib_surface;
|
||||||
GLFWbool KHR_xcb_surface;
|
GLFWbool KHR_xcb_surface;
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
||||||
|
if (!_glfw.vk.handle)
|
||||||
|
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
|
||||||
#else
|
#else
|
||||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
||||||
#endif
|
#endif
|
||||||
@@ -130,6 +132,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
||||||
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
|
||||||
|
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
|
||||||
#elif defined(_GLFW_X11)
|
#elif defined(_GLFW_X11)
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
||||||
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
||||||
|
|||||||
+87
-92
@@ -36,8 +36,6 @@
|
|||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
|
||||||
#define _GLFW_KEY_INVALID -2
|
|
||||||
|
|
||||||
// Returns the window style for the specified window
|
// Returns the window style for the specified window
|
||||||
//
|
//
|
||||||
static DWORD getWindowStyle(const _GLFWwindow* window)
|
static DWORD getWindowStyle(const _GLFWwindow* window)
|
||||||
@@ -448,77 +446,6 @@ static int getKeyMods(void)
|
|||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves and translates modifier keys
|
|
||||||
//
|
|
||||||
static int getAsyncKeyMods(void)
|
|
||||||
{
|
|
||||||
int mods = 0;
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_SHIFT;
|
|
||||||
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_CONTROL;
|
|
||||||
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_ALT;
|
|
||||||
if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_SUPER;
|
|
||||||
if (GetAsyncKeyState(VK_CAPITAL) & 1)
|
|
||||||
mods |= GLFW_MOD_CAPS_LOCK;
|
|
||||||
if (GetAsyncKeyState(VK_NUMLOCK) & 1)
|
|
||||||
mods |= GLFW_MOD_NUM_LOCK;
|
|
||||||
|
|
||||||
return mods;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translates a Windows key to the corresponding GLFW key
|
|
||||||
//
|
|
||||||
static int translateKey(WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
// The Ctrl keys require special handling
|
|
||||||
if (wParam == VK_CONTROL)
|
|
||||||
{
|
|
||||||
MSG next;
|
|
||||||
DWORD time;
|
|
||||||
|
|
||||||
// Right side keys have the extended key bit set
|
|
||||||
if (HIWORD(lParam) & KF_EXTENDED)
|
|
||||||
return GLFW_KEY_RIGHT_CONTROL;
|
|
||||||
|
|
||||||
// HACK: Alt Gr sends Left Ctrl and then Right Alt in close sequence
|
|
||||||
// We only want the Right Alt message, so if the next message is
|
|
||||||
// Right Alt we ignore this (synthetic) Left Ctrl message
|
|
||||||
time = GetMessageTime();
|
|
||||||
|
|
||||||
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
|
||||||
{
|
|
||||||
if (next.message == WM_KEYDOWN ||
|
|
||||||
next.message == WM_SYSKEYDOWN ||
|
|
||||||
next.message == WM_KEYUP ||
|
|
||||||
next.message == WM_SYSKEYUP)
|
|
||||||
{
|
|
||||||
if (next.wParam == VK_MENU &&
|
|
||||||
(HIWORD(next.lParam) & KF_EXTENDED) &&
|
|
||||||
next.time == time)
|
|
||||||
{
|
|
||||||
// Next message is Right Alt down so discard this
|
|
||||||
return _GLFW_KEY_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_KEY_LEFT_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wParam == VK_PROCESSKEY)
|
|
||||||
{
|
|
||||||
// IME notifies that keys have been filtered by setting the virtual
|
|
||||||
// key-code to VK_PROCESSKEY
|
|
||||||
return _GLFW_KEY_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _glfw.win32.keycodes[HIWORD(lParam) & 0x1FF];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fitToMonitor(_GLFWwindow* window)
|
static void fitToMonitor(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MONITORINFO mi = { sizeof(mi) };
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
@@ -739,13 +666,64 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
{
|
{
|
||||||
const int key = translateKey(wParam, lParam);
|
int key, scancode;
|
||||||
const int scancode = (HIWORD(lParam) & 0x1ff);
|
|
||||||
const int action = (HIWORD(lParam) & KF_UP) ? GLFW_RELEASE : GLFW_PRESS;
|
const int action = (HIWORD(lParam) & KF_UP) ? GLFW_RELEASE : GLFW_PRESS;
|
||||||
const int mods = getKeyMods();
|
const int mods = getKeyMods();
|
||||||
|
|
||||||
if (key == _GLFW_KEY_INVALID)
|
scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff));
|
||||||
|
if (!scancode)
|
||||||
|
{
|
||||||
|
// NOTE: Some synthetic key messages have a scancode of zero
|
||||||
|
// HACK: Map the virtual key back to a usable scancode
|
||||||
|
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
|
||||||
|
}
|
||||||
|
|
||||||
|
key = _glfw.win32.keycodes[scancode];
|
||||||
|
|
||||||
|
// The Ctrl keys require special handling
|
||||||
|
if (wParam == VK_CONTROL)
|
||||||
|
{
|
||||||
|
if (HIWORD(lParam) & KF_EXTENDED)
|
||||||
|
{
|
||||||
|
// Right side keys have the extended key bit set
|
||||||
|
key = GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NOTE: Alt Gr sends Left Ctrl followed by Right Alt
|
||||||
|
// HACK: We only want one event for Alt Gr, so if we detect
|
||||||
|
// this sequence we discard this Left Ctrl message now
|
||||||
|
// and later report Right Alt normally
|
||||||
|
MSG next;
|
||||||
|
const DWORD time = GetMessageTime();
|
||||||
|
|
||||||
|
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
||||||
|
{
|
||||||
|
if (next.message == WM_KEYDOWN ||
|
||||||
|
next.message == WM_SYSKEYDOWN ||
|
||||||
|
next.message == WM_KEYUP ||
|
||||||
|
next.message == WM_SYSKEYUP)
|
||||||
|
{
|
||||||
|
if (next.wParam == VK_MENU &&
|
||||||
|
(HIWORD(next.lParam) & KF_EXTENDED) &&
|
||||||
|
next.time == time)
|
||||||
|
{
|
||||||
|
// Next message is Right Alt down so discard this
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a regular Left Ctrl message
|
||||||
|
key = GLFW_KEY_LEFT_CONTROL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wParam == VK_PROCESSKEY)
|
||||||
|
{
|
||||||
|
// IME notifies that keys have been filtered by setting the
|
||||||
|
// virtual key-code to VK_PROCESSKEY
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
|
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
|
||||||
{
|
{
|
||||||
@@ -1924,30 +1902,40 @@ void _glfwPlatformPollEvents(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: Release modifier keys that the system did not emit KEYUP for
|
||||||
|
// NOTE: Shift keys on Windows tend to "stick" when both are pressed as
|
||||||
|
// no key up message is generated by the first key release
|
||||||
|
// NOTE: Windows key is not reported as released by the Win+V hotkey
|
||||||
|
// Other Win hotkeys are handled implicitly by _glfwInputWindowFocus
|
||||||
|
// because they change the input focus
|
||||||
|
// NOTE: The other half of this is in the WM_*KEY* handler in windowProc
|
||||||
handle = GetActiveWindow();
|
handle = GetActiveWindow();
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
// NOTE: Shift keys on Windows tend to "stick" when both are pressed as
|
|
||||||
// no key up message is generated by the first key release
|
|
||||||
// The other half of this is in the handling of WM_KEYUP
|
|
||||||
// HACK: Query actual key state and synthesize release events as needed
|
|
||||||
window = GetPropW(handle, L"GLFW");
|
window = GetPropW(handle, L"GLFW");
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) & 0x8000) != 0;
|
int i;
|
||||||
const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) & 0x8000) != 0;
|
const int keys[4][2] =
|
||||||
|
{
|
||||||
|
{ VK_LSHIFT, GLFW_KEY_LEFT_SHIFT },
|
||||||
|
{ VK_RSHIFT, GLFW_KEY_RIGHT_SHIFT },
|
||||||
|
{ VK_LWIN, GLFW_KEY_LEFT_SUPER },
|
||||||
|
{ VK_RWIN, GLFW_KEY_RIGHT_SUPER }
|
||||||
|
};
|
||||||
|
|
||||||
if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
const int mods = getAsyncKeyMods();
|
const int vk = keys[i][0];
|
||||||
const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT];
|
const int key = keys[i][1];
|
||||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
|
const int scancode = _glfw.win32.scancodes[key];
|
||||||
}
|
|
||||||
else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS)
|
if ((GetKeyState(vk) & 0x8000))
|
||||||
{
|
continue;
|
||||||
const int mods = getAsyncKeyMods();
|
if (window->keys[key] != GLFW_PRESS)
|
||||||
const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT];
|
continue;
|
||||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
|
|
||||||
|
_glfwInputKey(window, key, scancode, GLFW_RELEASE, getKeyMods());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2029,6 +2017,13 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
{
|
{
|
||||||
|
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) ||
|
||||||
|
_glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-7
@@ -322,12 +322,16 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|||||||
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
if (xpos)
|
if (ci)
|
||||||
*xpos = ci->x;
|
{
|
||||||
if (ypos)
|
if (xpos)
|
||||||
*ypos = ci->y;
|
*xpos = ci->x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = ci->y;
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,9 +497,15 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
*mode = vidmodeFromModeInfo(getModeInfo(sr, ci->mode), ci);
|
if (ci)
|
||||||
|
{
|
||||||
|
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||||
|
if (mi) // mi can be NULL if the monitor has been disconnected
|
||||||
|
*mode = vidmodeFromModeInfo(mi, ci);
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+9
-7
@@ -622,6 +622,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
_glfwGrabErrorHandlerX11();
|
_glfwGrabErrorHandlerX11();
|
||||||
|
|
||||||
|
window->x11.parent = _glfw.x11.root;
|
||||||
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
||||||
_glfw.x11.root,
|
_glfw.x11.root,
|
||||||
0, 0, // Position
|
0, 0, // Position
|
||||||
@@ -1258,12 +1259,6 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case CreateNotify:
|
|
||||||
{
|
|
||||||
window->x11.parent = event->xcreatewindow.parent;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ReparentNotify:
|
case ReparentNotify:
|
||||||
{
|
{
|
||||||
window->x11.parent = event->xreparent.parent;
|
window->x11.parent = event->xreparent.parent;
|
||||||
@@ -2457,7 +2452,7 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.NET_ACTIVE_WINDOW)
|
if (_glfw.x11.NET_ACTIVE_WINDOW)
|
||||||
sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
|
sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
|
||||||
else
|
else if (_glfwPlatformWindowVisible(window))
|
||||||
{
|
{
|
||||||
XRaiseWindow(_glfw.x11.display, window->x11.handle);
|
XRaiseWindow(_glfw.x11.display, window->x11.handle);
|
||||||
XSetInputFocus(_glfw.x11.display, window->x11.handle,
|
XSetInputFocus(_glfw.x11.display, window->x11.handle,
|
||||||
@@ -2867,6 +2862,13 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
|||||||
if (!_glfw.x11.xkb.available)
|
if (!_glfw.x11.xkb.available)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (scancode < 0 || scancode > 0xff ||
|
||||||
|
_glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const int key = _glfw.x11.keycodes[scancode];
|
const int key = _glfw.x11.keycodes[scancode];
|
||||||
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display,
|
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display,
|
||||||
scancode, _glfw.x11.xkb.group, 0);
|
scancode, _glfw.x11.xkb.group, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user