Compare commits

...

16 Commits

Author SHA1 Message Date
Camilla Löwy 0a49ef0a00 Update OpenGL bits of build documentation slightly
This removes most references to GLU, replaces the legacy CMake cache
variables for OpenGL with the modern namespaced target and switches to
$() for command substitution.

Fixes #1580.

(cherry picked from commit d973acc123)
2020-01-19 23:43:31 +01:00
Camilla Löwy b1d4b6a595 Remove AppVeyor skip commits setting
(cherry picked from commit 46c7c1cdff)
2020-01-17 15:51:12 +01:00
Camilla Löwy ad12b97acd Update changelog and add credit
Related to #1602.

(cherry picked from commit 13479ed27d)
2020-01-17 15:51:05 +01:00
Kovid Goyal 835dc3d327 X11: Fix queries crashing if monitor disconnected
Merged from downstream kovidgoyal/glfw.  First of many.

Related to #1602.

(cherry picked from commit a5e5b782c7)
2020-01-17 15:48:05 +01:00
Camilla Löwy 6a9fd2e13f Win32: Add matching comment
(cherry picked from commit 190673e779)
2020-01-17 15:47:03 +01:00
Camilla Löwy e53538010a Win32: Fix scancode when key message only had VK
Some synthetic key messages come with a scancode of zero, causing them
to be translate to GLFW_KEY_UNKNOWN.  This fills in the missing scancode
by translating the provided virtual key.

Rather than further complicate a single-use function, its body is merged
into the key message handler.

Fixes #1623.

(cherry picked from commit 789a2bcb39)
2020-01-17 15:46:40 +01:00
Camilla Löwy ec28696994 Check scancode before use in glfwGetKeyName
(cherry picked from commit 5f1631cb0e)
2020-01-17 15:46:18 +01:00
Camilla Löwy 0af3bf3b36 Win32: Use non-async key state for modifier hack
The synchronous key state seems to make more sense in context.

(cherry picked from commit a491b0698c)
2020-01-17 15:45:32 +01:00
Camilla Löwy 8552152f80 Win32: Fix no Super key release event after Win+V
The Win+V hotkey brings up a clipboard history IME that consumes the key
release.  This adds left and right Super to the modifier keys manually
polled for undetected release during event processing.

Fixes #1622.

(cherry picked from commit 562c17d131)
2020-01-17 15:44:45 +01:00
Camilla Löwy 85172703db Cocoa: Add fully dynamic loading of Vulkan loader
If the application is not linked against the Vulkan loader and relies on
a third-party loader library or glfwGetInstanceProcAddress, then our
call to dlopen will fail without a custom dyld environment variable.

This adds a fallback of looking in the directory of the main executable,
which matches the bundle structure recommended by the Vulkan SDK, making
that finally work out of the box for fully dynamic loading.

(cherry picked from commit 7da87aaae7)
2020-01-17 15:42:39 +01:00
Camilla Löwy d33084447d Cocoa: Select Vulkan surface extension at runtime
This mostly just follows the pattern established by X11.

Related to #1619.

(cherry picked from commit 15d91801b7)
2020-01-17 15:40:48 +01:00
ByunghoonKim 50f3979dfd Cocoa: Add support for VK_EXT_metal_surface
This adds optional support for the VK_EXT_metal_surface instance
extension.

Closes #1619.

(cherry picked from commit c5cb4a253a)
2020-01-17 15:38:54 +01:00
Camilla Löwy 977e2b51b0 Update changelog
This is a fix relative to 3.3.1 but not 3.3.

Related to #1620.
2020-01-14 21:29:07 +01:00
Camilla Löwy fbe8ae993c X11: Fix parent window handle initialization
This should have been initialized to the screen root, not None.  This
issue was introduced by fe57e3c292.

Fixes #1620.

(cherry picked from commit 9372ba95fa)
2020-01-14 21:28:58 +01:00
Camilla Löwy 487e0419a7 X11: Fix BadMatch focusing a window on non-EWMH WM
When the WM does not support EWMH or there is no WM running, GLFW falls
back to XSetInputFocus, which will emit BadMatch if the window is not
viewable, which will terminate the program.

Bug spotted on IRC.

(cherry picked from commit aa5e313561)
2020-01-12 17:54:49 +01:00
Camilla Löwy 0938462616 Start 3.3.2 2020-01-05 14:50:14 +01:00
14 changed files with 278 additions and 258 deletions
-5
View File
@@ -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
View File
@@ -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)
+13 -33
View File
@@ -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
View File
@@ -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
View File
@@ -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`
+4 -3
View File
@@ -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
+26
View File
@@ -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 //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
+12
View File
@@ -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
View File
@@ -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,
+2
View File
@@ -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;
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);