Merge branch '3.3-stable' into new-cursors-on-3.3-stable

This commit is contained in:
Camilla Löwy 2023-12-12 23:03:54 +01:00
commit dd288eabf6
59 changed files with 8870 additions and 3842 deletions

View File

@ -3,6 +3,7 @@ on:
pull_request: pull_request:
push: push:
branches: [ ci, master, latest, 3.3-stable ] branches: [ ci, master, latest, 3.3-stable ]
workflow_dispatch:
permissions: permissions:
statuses: write statuses: write
contents: read contents: read
@ -15,7 +16,7 @@ jobs:
CC: clang CC: clang
CFLAGS: -Werror CFLAGS: -Werror
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update sudo apt update
@ -38,7 +39,7 @@ jobs:
CC: clang CC: clang
CFLAGS: -Werror CFLAGS: -Werror
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update sudo apt update
@ -61,7 +62,7 @@ jobs:
CC: clang CC: clang
CFLAGS: -Werror CFLAGS: -Werror
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update sudo apt update
@ -84,7 +85,7 @@ jobs:
CFLAGS: -Werror CFLAGS: -Werror
MACOSX_DEPLOYMENT_TARGET: 10.8 MACOSX_DEPLOYMENT_TARGET: 10.8
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Configure static library - name: Configure static library
run: cmake -S . -B build-static run: cmake -S . -B build-static
@ -102,7 +103,7 @@ jobs:
env: env:
CFLAGS: /WX CFLAGS: /WX
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Configure static library - name: Configure static library
run: cmake -S . -B build-static -G "Visual Studio 17 2022" run: cmake -S . -B build-static -G "Visual Studio 17 2022"

View File

@ -1,8 +1,6 @@
cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR) cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR)
project(GLFW VERSION 3.3.7 LANGUAGES C) project(GLFW VERSION 3.3.9 LANGUAGES C)
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
if (POLICY CMP0054) if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0054 NEW)
@ -47,6 +45,7 @@ if (BUILD_SHARED_LIBS AND UNIX)
else() else()
set(GLFW_LIB_NAME glfw3) set(GLFW_LIB_NAME glfw3)
endif() endif()
set(GLFW_LIB_NAME_SUFFIX "")
if (GLFW_VULKAN_STATIC) if (GLFW_VULKAN_STATIC)
if (BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
@ -198,6 +197,10 @@ if (_GLFW_WIN32)
if (GLFW_USE_HYBRID_HPG) if (GLFW_USE_HYBRID_HPG)
set(_GLFW_USE_HYBRID_HPG 1) set(_GLFW_USE_HYBRID_HPG 1)
endif() endif()
if (BUILD_SHARED_LIBS)
set (GLFW_LIB_NAME_SUFFIX "dll")
endif()
endif() endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------

View File

@ -8,6 +8,7 @@ video tutorials.
- Bobyshev Alexander - Bobyshev Alexander
- Laurent Aphecetche - Laurent Aphecetche
- Matt Arsenault - Matt Arsenault
- Takuro Ashie
- ashishgamedev - ashishgamedev
- David Avedissian - David Avedissian
- Keith Bauer - Keith Bauer
@ -18,11 +19,13 @@ video tutorials.
- Nevyn Bengtsson - Nevyn Bengtsson
- Niklas Bergström - Niklas Bergström
- Denis Bernard - Denis Bernard
- BiBi
- Doug Binks - Doug Binks
- blanco - blanco
- Waris Boonyasiriwat - Waris Boonyasiriwat
- Kyle Brenneman - Kyle Brenneman
- Rok Breulj - Rok Breulj
- TheBrokenRail
- Kai Burjack - Kai Burjack
- Martin Capitanio - Martin Capitanio
- Nicolas Caramelli - Nicolas Caramelli
@ -43,6 +46,7 @@ video tutorials.
- Noel Cower - Noel Cower
- CuriouserThing - CuriouserThing
- Jason Daly - Jason Daly
- danhambleton
- Jarrod Davis - Jarrod Davis
- Olivier Delannoy - Olivier Delannoy
- Paul R. Deppe - Paul R. Deppe
@ -57,36 +61,49 @@ video tutorials.
- Jan Ekström - Jan Ekström
- Siavash Eliasi - Siavash Eliasi
- TheExileFox - TheExileFox
- Nikita Fediuchin
- Felipe Ferreira - Felipe Ferreira
- Michael Fogleman - Michael Fogleman
- forworldm
- Jason Francis - Jason Francis
- Gerald Franz - Gerald Franz
- Mário Freitas - Mário Freitas
- GeO4d - GeO4d
- Marcus Geelnard - Marcus Geelnard
- Gegy
- ghuser404 - ghuser404
- Charles Giessen - Charles Giessen
- Ryan C. Gordon - Ryan C. Gordon
- Stephen Gowen - Stephen Gowen
- Kovid Goyal - Kovid Goyal
- Kevin Grandemange
- Eloi Marín Gratacós - Eloi Marín Gratacós
- Grzesiek11
- Stefan Gustavson - Stefan Gustavson
- Andrew Gutekanst - Andrew Gutekanst
- Stephen Gutekanst - Stephen Gutekanst
- Jonathan Hale - Jonathan Hale
- Daniel Hauser
- hdf89shfdfs - hdf89shfdfs
- Moritz Heinemann
- Sylvain Hellegouarch - Sylvain Hellegouarch
- Björn Hempel
- Matthew Henry - Matthew Henry
- heromyth - heromyth
- Lucas Hinderberger - Lucas Hinderberger
- Paul Holden - Paul Holden
- Hajime Hoshi
- Warren Hu - Warren Hu
- Charles Huber - Charles Huber
- Brent Huisman
- illustris - illustris
- InKryption - InKryption
- IntellectualKitty - IntellectualKitty
- Aaron Jacobs - Aaron Jacobs
- JannikGM
- Erik S. V. Jansson - Erik S. V. Jansson
- jjYBdx4IL
- Peter Johnson
- Toni Jovanoski - Toni Jovanoski
- Arseny Kapoulkine - Arseny Kapoulkine
- Cem Karan - Cem Karan
@ -109,12 +126,15 @@ video tutorials.
- Anders Lindqvist - Anders Lindqvist
- Leon Linhart - Leon Linhart
- Marco Lizza - Marco Lizza
- lo-v-ol
- Eyal Lotem - Eyal Lotem
- Aaron Loucks - Aaron Loucks
- Luflosi - Luflosi
- lukect - lukect
- Tristam MacDonald - Tristam MacDonald
- Jean-Luc Mackail
- Hans Mackowiak - Hans Mackowiak
- Ramiro Magno
- Дмитри Малышев - Дмитри Малышев
- Zbigniew Mandziejewicz - Zbigniew Mandziejewicz
- Adam Marcus - Adam Marcus
@ -127,19 +147,24 @@ video tutorials.
- Marcel Metz - Marcel Metz
- Liam Middlebrook - Liam Middlebrook
- Ave Milia - Ave Milia
- Icyllis Milica
- Jonathan Miller - Jonathan Miller
- Kenneth Miller - Kenneth Miller
- Bruce Mitchener - Bruce Mitchener
- Jack Moffitt - Jack Moffitt
- Ravi Mohan
- Jeff Molofee - Jeff Molofee
- Alexander Monakov - Alexander Monakov
- Pierre Morel - Pierre Morel
- Jon Morton - Jon Morton
- Pierre Moulon - Pierre Moulon
- Martins Mozeiko - Martins Mozeiko
- James Murphy
- Julian Møller - Julian Møller
- ndogxj - ndogxj
- F. Nedelec
- Kristian Nielsen - Kristian Nielsen
- Joel Niemelä
- Kamil Nowakowski - Kamil Nowakowski
- onox - onox
- Denis Ovod - Denis Ovod
@ -150,10 +175,12 @@ video tutorials.
- Christopher Pelloux - Christopher Pelloux
- Arturo J. Pérez - Arturo J. Pérez
- Vladimir Perminov - Vladimir Perminov
- Olivier Perret
- Anthony Pesch - Anthony Pesch
- Orson Peters - Orson Peters
- Emmanuel Gil Peyrot - Emmanuel Gil Peyrot
- Cyril Pichard - Cyril Pichard
- Pilzschaf
- Keith Pitt - Keith Pitt
- Stanislav Podgorskiy - Stanislav Podgorskiy
- Konstantin Podsvirov - Konstantin Podsvirov
@ -162,10 +189,13 @@ video tutorials.
- Pablo Prietz - Pablo Prietz
- przemekmirek - przemekmirek
- pthom - pthom
- Martin Pulec
- Guillaume Racicot - Guillaume Racicot
- Christian Rauch
- Philip Rideout - Philip Rideout
- Eddie Ringle - Eddie Ringle
- Max Risuhin - Max Risuhin
- Joe Roback
- Jorge Rodriguez - Jorge Rodriguez
- Luca Rood - Luca Rood
- Ed Ropple - Ed Ropple
@ -178,11 +208,13 @@ video tutorials.
- Matt Sealey - Matt Sealey
- Steve Sexton - Steve Sexton
- Arkady Shapkin - Arkady Shapkin
- Mingjie Shen
- Ali Sherief - Ali Sherief
- Yoshiki Shibukawa - Yoshiki Shibukawa
- Dmitri Shuralyov - Dmitri Shuralyov
- Joao da Silva - Joao da Silva
- Daniel Sieger - Daniel Sieger
- Michael Skec
- Daniel Skorupski - Daniel Skorupski
- Slemmie - Slemmie
- Bradley Smith - Bradley Smith
@ -201,6 +233,7 @@ video tutorials.
- TTK-Bandit - TTK-Bandit
- Sergey Tikhomirov - Sergey Tikhomirov
- Arthur Tombs - Arthur Tombs
- TronicLabs
- Ioannis Tsakpinis - Ioannis Tsakpinis
- Samuli Tuomola - Samuli Tuomola
- Matthew Turner - Matthew Turner
@ -210,10 +243,12 @@ video tutorials.
- Jari Vetoniemi - Jari Vetoniemi
- Ricardo Vieira - Ricardo Vieira
- Nicholas Vitovitch - Nicholas Vitovitch
- Vladimír Vondruš
- Simon Voordouw - Simon Voordouw
- Corentin Wallez - Corentin Wallez
- Torsten Walluhn - Torsten Walluhn
- Patrick Walton - Patrick Walton
- Jim Wang
- Xo Wang - Xo Wang
- Jay Weisskopf - Jay Weisskopf
- Frank Wille - Frank Wille

View File

@ -123,33 +123,33 @@ information on what to include when reporting a bug.
## Changelog ## Changelog
- [Win32] Bugfix: A window created maximized and undecorated would cover the whole - Bugfix: `glfwGetKeyScancode` returned `0` on error when initialized instead of `-1`
monitor (#1806) - Bugfix: Failure to make a newly created context current could cause segfault (#2327)
- [Win32] Bugfix: The default restored window position was lost when creating a maximized - [Win32] Fix pkg-config for dynamic library on Windows (#2386, #2420)
window - [Win32] Bugfix: `glfwWaitEventsTimeout` did not return for some sent messages (#2408)
- [Win32] Bugfix: `glfwMaximizeWindow` would make a hidden window visible - [Win32] Bugfix: XInput could reportedly provide invalid DPad bit masks (#2291)
- [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003) - [Cocoa] Bugfix: Compilation failed on OS X 10.8 due to unconditional use of 10.9+
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences symbols (#2161)
- [X11] Bugfix: Waiting for events would fail if file descriptor was too large - [Cocoa] Bugfix: Full screen windows were resizable by the user (#2377,#2405)
(#2024) - [Cocoa] Bugfix: Full screen windows were miniaturized when clicked on macOS
- [X11] Bugfix: Joystick events could lead to busy-waiting (#1872) 10.15 (#2377,#2405)
- [X11] Bugfix: `glfwWaitEvents*` did not continue for joystick events - [Cocoa] Bugfix: Querying joystick elements could reportedly segfault on macOS
- [X11] Bugfix: `glfwPostEmptyEvent` could be ignored due to race condition 13 Ventura (#2320)
(#379,#1281,#1285,#2033) - [Cocoa] Bugfix: Print Screen key was not correctly reported (#1786,#2169)
- [X11] Bugfix: Dynamic loading on NetBSD failed due to soname differences - [Wayland] Added improved fallback window decorations via libdecor (#1639,#1693)
- [X11] Bugfix: Left shift of int constant relied on undefined behavior (#1951) - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450)
- [Wayland] Added support for key names via xkbcommon - [Wayland] Disabled alpha channel for opaque windows on systems lacking
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) `EGL_EXT_present_opaque` (#1895)
- [Wayland] Bugfix: Activating a window would emit two input focus events - [Wayland] Bugfix: Buffer would overrun when storing received drag offer (#2225)
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus - [Wayland] Bugfix: Joysticks connected after `glfwInit` were not detected (#2198)
- [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731) - [Wayland] Bugfix: Fallback decorations emitted `GLFW_CURSOR_UNAVAILABLE` errors
- [Wayland] Bugfix: A key being repeated was not released when window lost focus - [Wayland] Bugfix: Some events could fail to end wait for new events (#2397)
- [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043)
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE` - [Linux] Bugfix: A small amount of memory could leak if initialization failed (#2229)
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN` - [EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL
- [Wayland] Bugfix: Text input did not repeat along with key repeat - [EGL] Bugfix: `EGL_EXT_present_opaque` caused issues on X11 with Nvidia blob (#2365)
- [Wayland] Bugfix: `glfwPostEmptyEvent` sometimes had no effect (#1520,#1521) - [EGL] Bugfix: Setting `GLFW_CONTEXT_DEBUG` caused creation to fail (#2348)
- [GLX] Bugfix: Context creation failed if GLX 1.4 was not exported by GLX library - [GLX] Added loading of glvnd `libGLX.so.0` where available
## Contact ## Contact

View File

@ -2,19 +2,9 @@
/* File: vk_platform.h */ /* File: vk_platform.h */
/* */ /* */
/* /*
** Copyright (c) 2014-2017 The Khronos Group Inc. ** Copyright 2014-2022 The Khronos Group Inc.
** **
** Licensed under the Apache License, Version 2.0 (the "License"); ** SPDX-License-Identifier: Apache-2.0
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/ */
@ -52,7 +42,7 @@ extern "C"
#define VKAPI_CALL __stdcall #define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL #define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan isn't supported for the 'armeabi' NDK ABI" #error "Vulkan is not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
/* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */ /* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
/* calling convention, i.e. float parameters are passed in registers. This */ /* calling convention, i.e. float parameters are passed in registers. This */
@ -68,7 +58,9 @@ extern "C"
#define VKAPI_PTR #define VKAPI_PTR
#endif #endif
#if !defined(VK_NO_STDDEF_H)
#include <stddef.h> #include <stddef.h>
#endif /* !defined(VK_NO_STDDEF_H) */
#if !defined(VK_NO_STDINT_H) #if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600) #if defined(_MSC_VER) && (_MSC_VER < 1600)

2284
deps/glad/vulkan.h vendored

File diff suppressed because it is too large Load Diff

556
deps/glad_vulkan.c vendored
View File

@ -14,10 +14,18 @@
#endif /* GLAD_IMPL_UTIL_C_ */ #endif /* GLAD_IMPL_UTIL_C_ */
#ifdef __cplusplus
extern "C" {
#endif
int GLAD_VK_VERSION_1_0 = 0; int GLAD_VK_VERSION_1_0 = 0;
int GLAD_VK_VERSION_1_1 = 0; int GLAD_VK_VERSION_1_1 = 0;
int GLAD_VK_VERSION_1_2 = 0;
int GLAD_VK_VERSION_1_3 = 0;
int GLAD_VK_EXT_debug_report = 0; int GLAD_VK_EXT_debug_report = 0;
int GLAD_VK_KHR_portability_enumeration = 0;
int GLAD_VK_KHR_surface = 0; int GLAD_VK_KHR_surface = 0;
int GLAD_VK_KHR_swapchain = 0; int GLAD_VK_KHR_swapchain = 0;
@ -35,18 +43,26 @@ PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL; PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL;
PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL; PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL; PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 = NULL;
PFN_vkCmdBeginRendering glad_vkCmdBeginRendering = NULL;
PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL; PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL; PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL; PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL; PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 = NULL;
PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL; PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2 = NULL;
PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL; PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL; PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL; PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL; PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 = NULL;
PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL; PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 = NULL;
PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL; PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2 = NULL;
PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL; PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 = NULL;
PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL; PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
PFN_vkCmdDispatch glad_vkCmdDispatch = NULL; PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL; PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL;
@ -54,31 +70,56 @@ PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
PFN_vkCmdDraw glad_vkCmdDraw = NULL; PFN_vkCmdDraw glad_vkCmdDraw = NULL;
PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL; PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL; PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount = NULL;
PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL; PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount = NULL;
PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL; PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL; PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 = NULL;
PFN_vkCmdEndRendering glad_vkCmdEndRendering = NULL;
PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL; PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL; PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL; PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2 = NULL;
PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL; PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 = NULL;
PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL; PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL; PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2 = NULL;
PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL; PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL; PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2 = NULL;
PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL; PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
PFN_vkCmdSetCullMode glad_vkCmdSetCullMode = NULL;
PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL; PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable = NULL;
PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL; PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL;
PFN_vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable = NULL;
PFN_vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp = NULL;
PFN_vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable = NULL;
PFN_vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable = NULL;
PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL; PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL;
PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL; PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2 = NULL;
PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace = NULL;
PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL; PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL;
PFN_vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable = NULL;
PFN_vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology = NULL;
PFN_vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable = NULL;
PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL; PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL;
PFN_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount = NULL;
PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL; PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp = NULL;
PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL; PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable = NULL;
PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL; PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL; PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount = NULL;
PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL; PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL; PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2 = NULL;
PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL; PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 = NULL;
PFN_vkCreateBuffer glad_vkCreateBuffer = NULL; PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
PFN_vkCreateBufferView glad_vkCreateBufferView = NULL; PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL; PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
@ -97,8 +138,10 @@ PFN_vkCreateImageView glad_vkCreateImageView = NULL;
PFN_vkCreateInstance glad_vkCreateInstance = NULL; PFN_vkCreateInstance glad_vkCreateInstance = NULL;
PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL; PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL; PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot = NULL;
PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL; PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL; PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2 = NULL;
PFN_vkCreateSampler glad_vkCreateSampler = NULL; PFN_vkCreateSampler glad_vkCreateSampler = NULL;
PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL; PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL;
PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL; PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
@ -122,6 +165,7 @@ PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL; PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL; PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL; PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot = NULL;
PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL; PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL; PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
PFN_vkDestroySampler glad_vkDestroySampler = NULL; PFN_vkDestroySampler glad_vkDestroySampler = NULL;
@ -143,13 +187,19 @@ PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL; PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL; PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
PFN_vkFreeMemory glad_vkFreeMemory = NULL; PFN_vkFreeMemory glad_vkFreeMemory = NULL;
PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress = NULL;
PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL; PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL; PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL;
PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress = NULL;
PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL; PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL;
PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements = NULL;
PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL; PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL;
PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL; PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL; PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements = NULL;
PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements = NULL;
PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL; PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress = NULL;
PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL; PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL; PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL; PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL;
@ -183,9 +233,12 @@ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCap
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL; PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL; PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL; PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties = NULL;
PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL; PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
PFN_vkGetPrivateData glad_vkGetPrivateData = NULL;
PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL; PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL; PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue = NULL;
PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL; PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL; PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
PFN_vkMapMemory glad_vkMapMemory = NULL; PFN_vkMapMemory glad_vkMapMemory = NULL;
@ -193,216 +246,277 @@ PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL; PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL; PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
PFN_vkQueueSubmit glad_vkQueueSubmit = NULL; PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
PFN_vkQueueSubmit2 glad_vkQueueSubmit2 = NULL;
PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL; PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL; PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
PFN_vkResetCommandPool glad_vkResetCommandPool = NULL; PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL; PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
PFN_vkResetEvent glad_vkResetEvent = NULL; PFN_vkResetEvent glad_vkResetEvent = NULL;
PFN_vkResetFences glad_vkResetFences = NULL; PFN_vkResetFences glad_vkResetFences = NULL;
PFN_vkResetQueryPool glad_vkResetQueryPool = NULL;
PFN_vkSetEvent glad_vkSetEvent = NULL; PFN_vkSetEvent glad_vkSetEvent = NULL;
PFN_vkSetPrivateData glad_vkSetPrivateData = NULL;
PFN_vkSignalSemaphore glad_vkSignalSemaphore = NULL;
PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL; PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL;
PFN_vkUnmapMemory glad_vkUnmapMemory = NULL; PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL; PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL;
PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL; PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
PFN_vkWaitForFences glad_vkWaitForFences = NULL; PFN_vkWaitForFences glad_vkWaitForFences = NULL;
PFN_vkWaitSemaphores glad_vkWaitSemaphores = NULL;
static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_0) return; if(!GLAD_VK_VERSION_1_0) return;
vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load("vkAllocateCommandBuffers", userptr); glad_vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load(userptr, "vkAllocateCommandBuffers");
vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load("vkAllocateDescriptorSets", userptr); glad_vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load(userptr, "vkAllocateDescriptorSets");
vkAllocateMemory = (PFN_vkAllocateMemory) load("vkAllocateMemory", userptr); glad_vkAllocateMemory = (PFN_vkAllocateMemory) load(userptr, "vkAllocateMemory");
vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load("vkBeginCommandBuffer", userptr); glad_vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load(userptr, "vkBeginCommandBuffer");
vkBindBufferMemory = (PFN_vkBindBufferMemory) load("vkBindBufferMemory", userptr); glad_vkBindBufferMemory = (PFN_vkBindBufferMemory) load(userptr, "vkBindBufferMemory");
vkBindImageMemory = (PFN_vkBindImageMemory) load("vkBindImageMemory", userptr); glad_vkBindImageMemory = (PFN_vkBindImageMemory) load(userptr, "vkBindImageMemory");
vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load("vkCmdBeginQuery", userptr); glad_vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load(userptr, "vkCmdBeginQuery");
vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load("vkCmdBeginRenderPass", userptr); glad_vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load(userptr, "vkCmdBeginRenderPass");
vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load("vkCmdBindDescriptorSets", userptr); glad_vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load(userptr, "vkCmdBindDescriptorSets");
vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load("vkCmdBindIndexBuffer", userptr); glad_vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load(userptr, "vkCmdBindIndexBuffer");
vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load("vkCmdBindPipeline", userptr); glad_vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load(userptr, "vkCmdBindPipeline");
vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load("vkCmdBindVertexBuffers", userptr); glad_vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load(userptr, "vkCmdBindVertexBuffers");
vkCmdBlitImage = (PFN_vkCmdBlitImage) load("vkCmdBlitImage", userptr); glad_vkCmdBlitImage = (PFN_vkCmdBlitImage) load(userptr, "vkCmdBlitImage");
vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load("vkCmdClearAttachments", userptr); glad_vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load(userptr, "vkCmdClearAttachments");
vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load("vkCmdClearColorImage", userptr); glad_vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load(userptr, "vkCmdClearColorImage");
vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load("vkCmdClearDepthStencilImage", userptr); glad_vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load(userptr, "vkCmdClearDepthStencilImage");
vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load("vkCmdCopyBuffer", userptr); glad_vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load(userptr, "vkCmdCopyBuffer");
vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load("vkCmdCopyBufferToImage", userptr); glad_vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load(userptr, "vkCmdCopyBufferToImage");
vkCmdCopyImage = (PFN_vkCmdCopyImage) load("vkCmdCopyImage", userptr); glad_vkCmdCopyImage = (PFN_vkCmdCopyImage) load(userptr, "vkCmdCopyImage");
vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load("vkCmdCopyImageToBuffer", userptr); glad_vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load(userptr, "vkCmdCopyImageToBuffer");
vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load("vkCmdCopyQueryPoolResults", userptr); glad_vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load(userptr, "vkCmdCopyQueryPoolResults");
vkCmdDispatch = (PFN_vkCmdDispatch) load("vkCmdDispatch", userptr); glad_vkCmdDispatch = (PFN_vkCmdDispatch) load(userptr, "vkCmdDispatch");
vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load("vkCmdDispatchIndirect", userptr); glad_vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load(userptr, "vkCmdDispatchIndirect");
vkCmdDraw = (PFN_vkCmdDraw) load("vkCmdDraw", userptr); glad_vkCmdDraw = (PFN_vkCmdDraw) load(userptr, "vkCmdDraw");
vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load("vkCmdDrawIndexed", userptr); glad_vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load(userptr, "vkCmdDrawIndexed");
vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load("vkCmdDrawIndexedIndirect", userptr); glad_vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load(userptr, "vkCmdDrawIndexedIndirect");
vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load("vkCmdDrawIndirect", userptr); glad_vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load(userptr, "vkCmdDrawIndirect");
vkCmdEndQuery = (PFN_vkCmdEndQuery) load("vkCmdEndQuery", userptr); glad_vkCmdEndQuery = (PFN_vkCmdEndQuery) load(userptr, "vkCmdEndQuery");
vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load("vkCmdEndRenderPass", userptr); glad_vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load(userptr, "vkCmdEndRenderPass");
vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load("vkCmdExecuteCommands", userptr); glad_vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load(userptr, "vkCmdExecuteCommands");
vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load("vkCmdFillBuffer", userptr); glad_vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load(userptr, "vkCmdFillBuffer");
vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load("vkCmdNextSubpass", userptr); glad_vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load(userptr, "vkCmdNextSubpass");
vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load("vkCmdPipelineBarrier", userptr); glad_vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load(userptr, "vkCmdPipelineBarrier");
vkCmdPushConstants = (PFN_vkCmdPushConstants) load("vkCmdPushConstants", userptr); glad_vkCmdPushConstants = (PFN_vkCmdPushConstants) load(userptr, "vkCmdPushConstants");
vkCmdResetEvent = (PFN_vkCmdResetEvent) load("vkCmdResetEvent", userptr); glad_vkCmdResetEvent = (PFN_vkCmdResetEvent) load(userptr, "vkCmdResetEvent");
vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load("vkCmdResetQueryPool", userptr); glad_vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load(userptr, "vkCmdResetQueryPool");
vkCmdResolveImage = (PFN_vkCmdResolveImage) load("vkCmdResolveImage", userptr); glad_vkCmdResolveImage = (PFN_vkCmdResolveImage) load(userptr, "vkCmdResolveImage");
vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load("vkCmdSetBlendConstants", userptr); glad_vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load(userptr, "vkCmdSetBlendConstants");
vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load("vkCmdSetDepthBias", userptr); glad_vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load(userptr, "vkCmdSetDepthBias");
vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load("vkCmdSetDepthBounds", userptr); glad_vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load(userptr, "vkCmdSetDepthBounds");
vkCmdSetEvent = (PFN_vkCmdSetEvent) load("vkCmdSetEvent", userptr); glad_vkCmdSetEvent = (PFN_vkCmdSetEvent) load(userptr, "vkCmdSetEvent");
vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load("vkCmdSetLineWidth", userptr); glad_vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load(userptr, "vkCmdSetLineWidth");
vkCmdSetScissor = (PFN_vkCmdSetScissor) load("vkCmdSetScissor", userptr); glad_vkCmdSetScissor = (PFN_vkCmdSetScissor) load(userptr, "vkCmdSetScissor");
vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load("vkCmdSetStencilCompareMask", userptr); glad_vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load(userptr, "vkCmdSetStencilCompareMask");
vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load("vkCmdSetStencilReference", userptr); glad_vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load(userptr, "vkCmdSetStencilReference");
vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load("vkCmdSetStencilWriteMask", userptr); glad_vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load(userptr, "vkCmdSetStencilWriteMask");
vkCmdSetViewport = (PFN_vkCmdSetViewport) load("vkCmdSetViewport", userptr); glad_vkCmdSetViewport = (PFN_vkCmdSetViewport) load(userptr, "vkCmdSetViewport");
vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load("vkCmdUpdateBuffer", userptr); glad_vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load(userptr, "vkCmdUpdateBuffer");
vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load("vkCmdWaitEvents", userptr); glad_vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load(userptr, "vkCmdWaitEvents");
vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load("vkCmdWriteTimestamp", userptr); glad_vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load(userptr, "vkCmdWriteTimestamp");
vkCreateBuffer = (PFN_vkCreateBuffer) load("vkCreateBuffer", userptr); glad_vkCreateBuffer = (PFN_vkCreateBuffer) load(userptr, "vkCreateBuffer");
vkCreateBufferView = (PFN_vkCreateBufferView) load("vkCreateBufferView", userptr); glad_vkCreateBufferView = (PFN_vkCreateBufferView) load(userptr, "vkCreateBufferView");
vkCreateCommandPool = (PFN_vkCreateCommandPool) load("vkCreateCommandPool", userptr); glad_vkCreateCommandPool = (PFN_vkCreateCommandPool) load(userptr, "vkCreateCommandPool");
vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load("vkCreateComputePipelines", userptr); glad_vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load(userptr, "vkCreateComputePipelines");
vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load("vkCreateDescriptorPool", userptr); glad_vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load(userptr, "vkCreateDescriptorPool");
vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load("vkCreateDescriptorSetLayout", userptr); glad_vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load(userptr, "vkCreateDescriptorSetLayout");
vkCreateDevice = (PFN_vkCreateDevice) load("vkCreateDevice", userptr); glad_vkCreateDevice = (PFN_vkCreateDevice) load(userptr, "vkCreateDevice");
vkCreateEvent = (PFN_vkCreateEvent) load("vkCreateEvent", userptr); glad_vkCreateEvent = (PFN_vkCreateEvent) load(userptr, "vkCreateEvent");
vkCreateFence = (PFN_vkCreateFence) load("vkCreateFence", userptr); glad_vkCreateFence = (PFN_vkCreateFence) load(userptr, "vkCreateFence");
vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load("vkCreateFramebuffer", userptr); glad_vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load(userptr, "vkCreateFramebuffer");
vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load("vkCreateGraphicsPipelines", userptr); glad_vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load(userptr, "vkCreateGraphicsPipelines");
vkCreateImage = (PFN_vkCreateImage) load("vkCreateImage", userptr); glad_vkCreateImage = (PFN_vkCreateImage) load(userptr, "vkCreateImage");
vkCreateImageView = (PFN_vkCreateImageView) load("vkCreateImageView", userptr); glad_vkCreateImageView = (PFN_vkCreateImageView) load(userptr, "vkCreateImageView");
vkCreateInstance = (PFN_vkCreateInstance) load("vkCreateInstance", userptr); glad_vkCreateInstance = (PFN_vkCreateInstance) load(userptr, "vkCreateInstance");
vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load("vkCreatePipelineCache", userptr); glad_vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load(userptr, "vkCreatePipelineCache");
vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load("vkCreatePipelineLayout", userptr); glad_vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load(userptr, "vkCreatePipelineLayout");
vkCreateQueryPool = (PFN_vkCreateQueryPool) load("vkCreateQueryPool", userptr); glad_vkCreateQueryPool = (PFN_vkCreateQueryPool) load(userptr, "vkCreateQueryPool");
vkCreateRenderPass = (PFN_vkCreateRenderPass) load("vkCreateRenderPass", userptr); glad_vkCreateRenderPass = (PFN_vkCreateRenderPass) load(userptr, "vkCreateRenderPass");
vkCreateSampler = (PFN_vkCreateSampler) load("vkCreateSampler", userptr); glad_vkCreateSampler = (PFN_vkCreateSampler) load(userptr, "vkCreateSampler");
vkCreateSemaphore = (PFN_vkCreateSemaphore) load("vkCreateSemaphore", userptr); glad_vkCreateSemaphore = (PFN_vkCreateSemaphore) load(userptr, "vkCreateSemaphore");
vkCreateShaderModule = (PFN_vkCreateShaderModule) load("vkCreateShaderModule", userptr); glad_vkCreateShaderModule = (PFN_vkCreateShaderModule) load(userptr, "vkCreateShaderModule");
vkDestroyBuffer = (PFN_vkDestroyBuffer) load("vkDestroyBuffer", userptr); glad_vkDestroyBuffer = (PFN_vkDestroyBuffer) load(userptr, "vkDestroyBuffer");
vkDestroyBufferView = (PFN_vkDestroyBufferView) load("vkDestroyBufferView", userptr); glad_vkDestroyBufferView = (PFN_vkDestroyBufferView) load(userptr, "vkDestroyBufferView");
vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load("vkDestroyCommandPool", userptr); glad_vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load(userptr, "vkDestroyCommandPool");
vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load("vkDestroyDescriptorPool", userptr); glad_vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load(userptr, "vkDestroyDescriptorPool");
vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load("vkDestroyDescriptorSetLayout", userptr); glad_vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load(userptr, "vkDestroyDescriptorSetLayout");
vkDestroyDevice = (PFN_vkDestroyDevice) load("vkDestroyDevice", userptr); glad_vkDestroyDevice = (PFN_vkDestroyDevice) load(userptr, "vkDestroyDevice");
vkDestroyEvent = (PFN_vkDestroyEvent) load("vkDestroyEvent", userptr); glad_vkDestroyEvent = (PFN_vkDestroyEvent) load(userptr, "vkDestroyEvent");
vkDestroyFence = (PFN_vkDestroyFence) load("vkDestroyFence", userptr); glad_vkDestroyFence = (PFN_vkDestroyFence) load(userptr, "vkDestroyFence");
vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load("vkDestroyFramebuffer", userptr); glad_vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load(userptr, "vkDestroyFramebuffer");
vkDestroyImage = (PFN_vkDestroyImage) load("vkDestroyImage", userptr); glad_vkDestroyImage = (PFN_vkDestroyImage) load(userptr, "vkDestroyImage");
vkDestroyImageView = (PFN_vkDestroyImageView) load("vkDestroyImageView", userptr); glad_vkDestroyImageView = (PFN_vkDestroyImageView) load(userptr, "vkDestroyImageView");
vkDestroyInstance = (PFN_vkDestroyInstance) load("vkDestroyInstance", userptr); glad_vkDestroyInstance = (PFN_vkDestroyInstance) load(userptr, "vkDestroyInstance");
vkDestroyPipeline = (PFN_vkDestroyPipeline) load("vkDestroyPipeline", userptr); glad_vkDestroyPipeline = (PFN_vkDestroyPipeline) load(userptr, "vkDestroyPipeline");
vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load("vkDestroyPipelineCache", userptr); glad_vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load(userptr, "vkDestroyPipelineCache");
vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load("vkDestroyPipelineLayout", userptr); glad_vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load(userptr, "vkDestroyPipelineLayout");
vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load("vkDestroyQueryPool", userptr); glad_vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load(userptr, "vkDestroyQueryPool");
vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load("vkDestroyRenderPass", userptr); glad_vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load(userptr, "vkDestroyRenderPass");
vkDestroySampler = (PFN_vkDestroySampler) load("vkDestroySampler", userptr); glad_vkDestroySampler = (PFN_vkDestroySampler) load(userptr, "vkDestroySampler");
vkDestroySemaphore = (PFN_vkDestroySemaphore) load("vkDestroySemaphore", userptr); glad_vkDestroySemaphore = (PFN_vkDestroySemaphore) load(userptr, "vkDestroySemaphore");
vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load("vkDestroyShaderModule", userptr); glad_vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load(userptr, "vkDestroyShaderModule");
vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load("vkDeviceWaitIdle", userptr); glad_vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load(userptr, "vkDeviceWaitIdle");
vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load("vkEndCommandBuffer", userptr); glad_vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load(userptr, "vkEndCommandBuffer");
vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load("vkEnumerateDeviceExtensionProperties", userptr); glad_vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load(userptr, "vkEnumerateDeviceExtensionProperties");
vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load("vkEnumerateDeviceLayerProperties", userptr); glad_vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load(userptr, "vkEnumerateDeviceLayerProperties");
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load("vkEnumerateInstanceExtensionProperties", userptr); glad_vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load(userptr, "vkEnumerateInstanceExtensionProperties");
vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load("vkEnumerateInstanceLayerProperties", userptr); glad_vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load(userptr, "vkEnumerateInstanceLayerProperties");
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load("vkEnumeratePhysicalDevices", userptr); glad_vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load(userptr, "vkEnumeratePhysicalDevices");
vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load("vkFlushMappedMemoryRanges", userptr); glad_vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load(userptr, "vkFlushMappedMemoryRanges");
vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load("vkFreeCommandBuffers", userptr); glad_vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load(userptr, "vkFreeCommandBuffers");
vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load("vkFreeDescriptorSets", userptr); glad_vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load(userptr, "vkFreeDescriptorSets");
vkFreeMemory = (PFN_vkFreeMemory) load("vkFreeMemory", userptr); glad_vkFreeMemory = (PFN_vkFreeMemory) load(userptr, "vkFreeMemory");
vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load("vkGetBufferMemoryRequirements", userptr); glad_vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load(userptr, "vkGetBufferMemoryRequirements");
vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load("vkGetDeviceMemoryCommitment", userptr); glad_vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load(userptr, "vkGetDeviceMemoryCommitment");
vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load("vkGetDeviceProcAddr", userptr); glad_vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load(userptr, "vkGetDeviceProcAddr");
vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load("vkGetDeviceQueue", userptr); glad_vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load(userptr, "vkGetDeviceQueue");
vkGetEventStatus = (PFN_vkGetEventStatus) load("vkGetEventStatus", userptr); glad_vkGetEventStatus = (PFN_vkGetEventStatus) load(userptr, "vkGetEventStatus");
vkGetFenceStatus = (PFN_vkGetFenceStatus) load("vkGetFenceStatus", userptr); glad_vkGetFenceStatus = (PFN_vkGetFenceStatus) load(userptr, "vkGetFenceStatus");
vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load("vkGetImageMemoryRequirements", userptr); glad_vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load(userptr, "vkGetImageMemoryRequirements");
vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load("vkGetImageSparseMemoryRequirements", userptr); glad_vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load(userptr, "vkGetImageSparseMemoryRequirements");
vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load("vkGetImageSubresourceLayout", userptr); glad_vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load(userptr, "vkGetImageSubresourceLayout");
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load("vkGetInstanceProcAddr", userptr); glad_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load(userptr, "vkGetInstanceProcAddr");
vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load("vkGetPhysicalDeviceFeatures", userptr); glad_vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load(userptr, "vkGetPhysicalDeviceFeatures");
vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load("vkGetPhysicalDeviceFormatProperties", userptr); glad_vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load(userptr, "vkGetPhysicalDeviceFormatProperties");
vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load("vkGetPhysicalDeviceImageFormatProperties", userptr); glad_vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load(userptr, "vkGetPhysicalDeviceImageFormatProperties");
vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load("vkGetPhysicalDeviceMemoryProperties", userptr); glad_vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load(userptr, "vkGetPhysicalDeviceMemoryProperties");
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load("vkGetPhysicalDeviceProperties", userptr); glad_vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load(userptr, "vkGetPhysicalDeviceProperties");
vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load("vkGetPhysicalDeviceQueueFamilyProperties", userptr); glad_vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties");
vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr); glad_vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties");
vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load("vkGetPipelineCacheData", userptr); glad_vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load(userptr, "vkGetPipelineCacheData");
vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load("vkGetQueryPoolResults", userptr); glad_vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load(userptr, "vkGetQueryPoolResults");
vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load("vkGetRenderAreaGranularity", userptr); glad_vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load(userptr, "vkGetRenderAreaGranularity");
vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load("vkInvalidateMappedMemoryRanges", userptr); glad_vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load(userptr, "vkInvalidateMappedMemoryRanges");
vkMapMemory = (PFN_vkMapMemory) load("vkMapMemory", userptr); glad_vkMapMemory = (PFN_vkMapMemory) load(userptr, "vkMapMemory");
vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load("vkMergePipelineCaches", userptr); glad_vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load(userptr, "vkMergePipelineCaches");
vkQueueBindSparse = (PFN_vkQueueBindSparse) load("vkQueueBindSparse", userptr); glad_vkQueueBindSparse = (PFN_vkQueueBindSparse) load(userptr, "vkQueueBindSparse");
vkQueueSubmit = (PFN_vkQueueSubmit) load("vkQueueSubmit", userptr); glad_vkQueueSubmit = (PFN_vkQueueSubmit) load(userptr, "vkQueueSubmit");
vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load("vkQueueWaitIdle", userptr); glad_vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load(userptr, "vkQueueWaitIdle");
vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load("vkResetCommandBuffer", userptr); glad_vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load(userptr, "vkResetCommandBuffer");
vkResetCommandPool = (PFN_vkResetCommandPool) load("vkResetCommandPool", userptr); glad_vkResetCommandPool = (PFN_vkResetCommandPool) load(userptr, "vkResetCommandPool");
vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load("vkResetDescriptorPool", userptr); glad_vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load(userptr, "vkResetDescriptorPool");
vkResetEvent = (PFN_vkResetEvent) load("vkResetEvent", userptr); glad_vkResetEvent = (PFN_vkResetEvent) load(userptr, "vkResetEvent");
vkResetFences = (PFN_vkResetFences) load("vkResetFences", userptr); glad_vkResetFences = (PFN_vkResetFences) load(userptr, "vkResetFences");
vkSetEvent = (PFN_vkSetEvent) load("vkSetEvent", userptr); glad_vkSetEvent = (PFN_vkSetEvent) load(userptr, "vkSetEvent");
vkUnmapMemory = (PFN_vkUnmapMemory) load("vkUnmapMemory", userptr); glad_vkUnmapMemory = (PFN_vkUnmapMemory) load(userptr, "vkUnmapMemory");
vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load("vkUpdateDescriptorSets", userptr); glad_vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load(userptr, "vkUpdateDescriptorSets");
vkWaitForFences = (PFN_vkWaitForFences) load("vkWaitForFences", userptr); glad_vkWaitForFences = (PFN_vkWaitForFences) load(userptr, "vkWaitForFences");
} }
static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_1) return; if(!GLAD_VK_VERSION_1_1) return;
vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load("vkBindBufferMemory2", userptr); glad_vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load(userptr, "vkBindBufferMemory2");
vkBindImageMemory2 = (PFN_vkBindImageMemory2) load("vkBindImageMemory2", userptr); glad_vkBindImageMemory2 = (PFN_vkBindImageMemory2) load(userptr, "vkBindImageMemory2");
vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load("vkCmdDispatchBase", userptr); glad_vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load(userptr, "vkCmdDispatchBase");
vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load("vkCmdSetDeviceMask", userptr); glad_vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load(userptr, "vkCmdSetDeviceMask");
vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load("vkCreateDescriptorUpdateTemplate", userptr); glad_vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load(userptr, "vkCreateDescriptorUpdateTemplate");
vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load("vkCreateSamplerYcbcrConversion", userptr); glad_vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load(userptr, "vkCreateSamplerYcbcrConversion");
vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load("vkDestroyDescriptorUpdateTemplate", userptr); glad_vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load(userptr, "vkDestroyDescriptorUpdateTemplate");
vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load("vkDestroySamplerYcbcrConversion", userptr); glad_vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load(userptr, "vkDestroySamplerYcbcrConversion");
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr); glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion");
vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load("vkEnumeratePhysicalDeviceGroups", userptr); glad_vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load(userptr, "vkEnumeratePhysicalDeviceGroups");
vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load("vkGetBufferMemoryRequirements2", userptr); glad_vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load(userptr, "vkGetBufferMemoryRequirements2");
vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load("vkGetDescriptorSetLayoutSupport", userptr); glad_vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load(userptr, "vkGetDescriptorSetLayoutSupport");
vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load("vkGetDeviceGroupPeerMemoryFeatures", userptr); glad_vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load(userptr, "vkGetDeviceGroupPeerMemoryFeatures");
vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load("vkGetDeviceQueue2", userptr); glad_vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load(userptr, "vkGetDeviceQueue2");
vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load("vkGetImageMemoryRequirements2", userptr); glad_vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load(userptr, "vkGetImageMemoryRequirements2");
vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load("vkGetImageSparseMemoryRequirements2", userptr); glad_vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load(userptr, "vkGetImageSparseMemoryRequirements2");
vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load("vkGetPhysicalDeviceExternalBufferProperties", userptr); glad_vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load(userptr, "vkGetPhysicalDeviceExternalBufferProperties");
vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load("vkGetPhysicalDeviceExternalFenceProperties", userptr); glad_vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load(userptr, "vkGetPhysicalDeviceExternalFenceProperties");
vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load("vkGetPhysicalDeviceExternalSemaphoreProperties", userptr); glad_vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load(userptr, "vkGetPhysicalDeviceExternalSemaphoreProperties");
vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load("vkGetPhysicalDeviceFeatures2", userptr); glad_vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load(userptr, "vkGetPhysicalDeviceFeatures2");
vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load("vkGetPhysicalDeviceFormatProperties2", userptr); glad_vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load(userptr, "vkGetPhysicalDeviceFormatProperties2");
vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load("vkGetPhysicalDeviceImageFormatProperties2", userptr); glad_vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceImageFormatProperties2");
vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load("vkGetPhysicalDeviceMemoryProperties2", userptr); glad_vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load(userptr, "vkGetPhysicalDeviceMemoryProperties2");
vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load("vkGetPhysicalDeviceProperties2", userptr); glad_vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load(userptr, "vkGetPhysicalDeviceProperties2");
vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load("vkGetPhysicalDeviceQueueFamilyProperties2", userptr); glad_vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties2");
vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load("vkGetPhysicalDeviceSparseImageFormatProperties2", userptr); glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties2");
vkTrimCommandPool = (PFN_vkTrimCommandPool) load("vkTrimCommandPool", userptr); glad_vkTrimCommandPool = (PFN_vkTrimCommandPool) load(userptr, "vkTrimCommandPool");
vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load("vkUpdateDescriptorSetWithTemplate", userptr); glad_vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load(userptr, "vkUpdateDescriptorSetWithTemplate");
}
static void glad_vk_load_VK_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_2) return;
glad_vkCmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2) load(userptr, "vkCmdBeginRenderPass2");
glad_vkCmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount) load(userptr, "vkCmdDrawIndexedIndirectCount");
glad_vkCmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount) load(userptr, "vkCmdDrawIndirectCount");
glad_vkCmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2) load(userptr, "vkCmdEndRenderPass2");
glad_vkCmdNextSubpass2 = (PFN_vkCmdNextSubpass2) load(userptr, "vkCmdNextSubpass2");
glad_vkCreateRenderPass2 = (PFN_vkCreateRenderPass2) load(userptr, "vkCreateRenderPass2");
glad_vkGetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress) load(userptr, "vkGetBufferDeviceAddress");
glad_vkGetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress) load(userptr, "vkGetBufferOpaqueCaptureAddress");
glad_vkGetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress) load(userptr, "vkGetDeviceMemoryOpaqueCaptureAddress");
glad_vkGetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue) load(userptr, "vkGetSemaphoreCounterValue");
glad_vkResetQueryPool = (PFN_vkResetQueryPool) load(userptr, "vkResetQueryPool");
glad_vkSignalSemaphore = (PFN_vkSignalSemaphore) load(userptr, "vkSignalSemaphore");
glad_vkWaitSemaphores = (PFN_vkWaitSemaphores) load(userptr, "vkWaitSemaphores");
}
static void glad_vk_load_VK_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_3) return;
glad_vkCmdBeginRendering = (PFN_vkCmdBeginRendering) load(userptr, "vkCmdBeginRendering");
glad_vkCmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2) load(userptr, "vkCmdBindVertexBuffers2");
glad_vkCmdBlitImage2 = (PFN_vkCmdBlitImage2) load(userptr, "vkCmdBlitImage2");
glad_vkCmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2) load(userptr, "vkCmdCopyBuffer2");
glad_vkCmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2) load(userptr, "vkCmdCopyBufferToImage2");
glad_vkCmdCopyImage2 = (PFN_vkCmdCopyImage2) load(userptr, "vkCmdCopyImage2");
glad_vkCmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2) load(userptr, "vkCmdCopyImageToBuffer2");
glad_vkCmdEndRendering = (PFN_vkCmdEndRendering) load(userptr, "vkCmdEndRendering");
glad_vkCmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2) load(userptr, "vkCmdPipelineBarrier2");
glad_vkCmdResetEvent2 = (PFN_vkCmdResetEvent2) load(userptr, "vkCmdResetEvent2");
glad_vkCmdResolveImage2 = (PFN_vkCmdResolveImage2) load(userptr, "vkCmdResolveImage2");
glad_vkCmdSetCullMode = (PFN_vkCmdSetCullMode) load(userptr, "vkCmdSetCullMode");
glad_vkCmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable) load(userptr, "vkCmdSetDepthBiasEnable");
glad_vkCmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable) load(userptr, "vkCmdSetDepthBoundsTestEnable");
glad_vkCmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp) load(userptr, "vkCmdSetDepthCompareOp");
glad_vkCmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable) load(userptr, "vkCmdSetDepthTestEnable");
glad_vkCmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable) load(userptr, "vkCmdSetDepthWriteEnable");
glad_vkCmdSetEvent2 = (PFN_vkCmdSetEvent2) load(userptr, "vkCmdSetEvent2");
glad_vkCmdSetFrontFace = (PFN_vkCmdSetFrontFace) load(userptr, "vkCmdSetFrontFace");
glad_vkCmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable) load(userptr, "vkCmdSetPrimitiveRestartEnable");
glad_vkCmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology) load(userptr, "vkCmdSetPrimitiveTopology");
glad_vkCmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable) load(userptr, "vkCmdSetRasterizerDiscardEnable");
glad_vkCmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount) load(userptr, "vkCmdSetScissorWithCount");
glad_vkCmdSetStencilOp = (PFN_vkCmdSetStencilOp) load(userptr, "vkCmdSetStencilOp");
glad_vkCmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable) load(userptr, "vkCmdSetStencilTestEnable");
glad_vkCmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount) load(userptr, "vkCmdSetViewportWithCount");
glad_vkCmdWaitEvents2 = (PFN_vkCmdWaitEvents2) load(userptr, "vkCmdWaitEvents2");
glad_vkCmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2) load(userptr, "vkCmdWriteTimestamp2");
glad_vkCreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot) load(userptr, "vkCreatePrivateDataSlot");
glad_vkDestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot) load(userptr, "vkDestroyPrivateDataSlot");
glad_vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements) load(userptr, "vkGetDeviceBufferMemoryRequirements");
glad_vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements) load(userptr, "vkGetDeviceImageMemoryRequirements");
glad_vkGetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements) load(userptr, "vkGetDeviceImageSparseMemoryRequirements");
glad_vkGetPhysicalDeviceToolProperties = (PFN_vkGetPhysicalDeviceToolProperties) load(userptr, "vkGetPhysicalDeviceToolProperties");
glad_vkGetPrivateData = (PFN_vkGetPrivateData) load(userptr, "vkGetPrivateData");
glad_vkQueueSubmit2 = (PFN_vkQueueSubmit2) load(userptr, "vkQueueSubmit2");
glad_vkSetPrivateData = (PFN_vkSetPrivateData) load(userptr, "vkSetPrivateData");
} }
static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) { static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_EXT_debug_report) return; if(!GLAD_VK_EXT_debug_report) return;
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load("vkCreateDebugReportCallbackEXT", userptr); glad_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load(userptr, "vkCreateDebugReportCallbackEXT");
vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load("vkDebugReportMessageEXT", userptr); glad_vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load(userptr, "vkDebugReportMessageEXT");
vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load("vkDestroyDebugReportCallbackEXT", userptr); glad_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load(userptr, "vkDestroyDebugReportCallbackEXT");
} }
static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) { static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_surface) return; if(!GLAD_VK_KHR_surface) return;
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load("vkDestroySurfaceKHR", userptr); glad_vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load(userptr, "vkDestroySurfaceKHR");
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr); glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load(userptr, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr); glad_vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load(userptr, "vkGetPhysicalDeviceSurfaceFormatsKHR");
vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr); glad_vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load(userptr, "vkGetPhysicalDeviceSurfacePresentModesKHR");
vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr); glad_vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load(userptr, "vkGetPhysicalDeviceSurfaceSupportKHR");
} }
static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) { static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_swapchain) return; if(!GLAD_VK_KHR_swapchain) return;
vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load("vkAcquireNextImage2KHR", userptr); glad_vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load(userptr, "vkAcquireNextImage2KHR");
vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load("vkAcquireNextImageKHR", userptr); glad_vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load(userptr, "vkAcquireNextImageKHR");
vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load("vkCreateSwapchainKHR", userptr); glad_vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load(userptr, "vkCreateSwapchainKHR");
vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load("vkDestroySwapchainKHR", userptr); glad_vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load(userptr, "vkDestroySwapchainKHR");
vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr); glad_vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load(userptr, "vkGetDeviceGroupPresentCapabilitiesKHR");
vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load("vkGetDeviceGroupSurfacePresentModesKHR", userptr); glad_vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load(userptr, "vkGetDeviceGroupSurfacePresentModesKHR");
vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load("vkGetPhysicalDevicePresentRectanglesKHR", userptr); glad_vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load(userptr, "vkGetPhysicalDevicePresentRectanglesKHR");
vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load("vkGetSwapchainImagesKHR", userptr); glad_vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load(userptr, "vkGetSwapchainImagesKHR");
vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load("vkQueuePresentKHR", userptr); glad_vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load(userptr, "vkQueuePresentKHR");
} }
@ -411,47 +525,49 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o
uint32_t i; uint32_t i;
uint32_t instance_extension_count = 0; uint32_t instance_extension_count = 0;
uint32_t device_extension_count = 0; uint32_t device_extension_count = 0;
uint32_t max_extension_count; uint32_t max_extension_count = 0;
uint32_t total_extension_count; uint32_t total_extension_count = 0;
char **extensions; char **extensions = NULL;
VkExtensionProperties *ext_properties; VkExtensionProperties *ext_properties = NULL;
VkResult result; VkResult result;
if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) { if (glad_vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && glad_vkEnumerateDeviceExtensionProperties == NULL)) {
return 0; return 0;
} }
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
return 0; return 0;
} }
if (physical_device != NULL) { if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL); result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
return 0; return 0;
} }
} }
total_extension_count = instance_extension_count + device_extension_count; total_extension_count = instance_extension_count + device_extension_count;
if (total_extension_count <= 0) {
return 0;
}
max_extension_count = instance_extension_count > device_extension_count max_extension_count = instance_extension_count > device_extension_count
? instance_extension_count : device_extension_count; ? instance_extension_count : device_extension_count;
ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties)); ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties));
if (ext_properties == NULL) { if (ext_properties == NULL) {
return 0; goto glad_vk_get_extensions_error;
} }
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties); result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
free((void*) ext_properties); goto glad_vk_get_extensions_error;
return 0;
} }
extensions = (char**) calloc(total_extension_count, sizeof(char*)); extensions = (char**) calloc(total_extension_count, sizeof(char*));
if (extensions == NULL) { if (extensions == NULL) {
free((void*) ext_properties); goto glad_vk_get_extensions_error;
return 0;
} }
for (i = 0; i < instance_extension_count; ++i) { for (i = 0; i < instance_extension_count; ++i) {
@ -459,17 +575,16 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o
size_t extension_name_length = strlen(ext.extensionName) + 1; size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[i] = (char*) malloc(extension_name_length * sizeof(char)); extensions[i] = (char*) malloc(extension_name_length * sizeof(char));
if (extensions[i] == NULL) {
goto glad_vk_get_extensions_error;
}
memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char)); memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char));
} }
if (physical_device != NULL) { if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties); result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
for (i = 0; i < instance_extension_count; ++i) { goto glad_vk_get_extensions_error;
free((void*) extensions[i]);
}
free(extensions);
return 0;
} }
for (i = 0; i < device_extension_count; ++i) { for (i = 0; i < device_extension_count; ++i) {
@ -477,6 +592,9 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o
size_t extension_name_length = strlen(ext.extensionName) + 1; size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char)); extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char));
if (extensions[instance_extension_count + i] == NULL) {
goto glad_vk_get_extensions_error;
}
memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char)); memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char));
} }
} }
@ -487,6 +605,16 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o
*out_extensions = extensions; *out_extensions = extensions;
return 1; return 1;
glad_vk_get_extensions_error:
free((void*) ext_properties);
if (extensions != NULL) {
for (i = 0; i < total_extension_count; ++i) {
free((void*) extensions[i]);
}
free(extensions);
}
return 0;
} }
static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) { static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) {
@ -503,7 +631,7 @@ static int glad_vk_has_extension(const char *name, uint32_t extension_count, cha
uint32_t i; uint32_t i;
for (i = 0; i < extension_count; ++i) { for (i = 0; i < extension_count; ++i) {
if(strcmp(name, extensions[i]) == 0) { if(extensions[i] != NULL && strcmp(name, extensions[i]) == 0) {
return 1; return 1;
} }
} }
@ -511,7 +639,7 @@ static int glad_vk_has_extension(const char *name, uint32_t extension_count, cha
return 0; return 0;
} }
static GLADapiproc glad_vk_get_proc_from_userptr(const char* name, void *userptr) { static GLADapiproc glad_vk_get_proc_from_userptr(void *userptr, const char* name) {
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
} }
@ -521,9 +649,12 @@ static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) {
if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0; if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0;
GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions); GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions);
GLAD_VK_KHR_portability_enumeration = glad_vk_has_extension("VK_KHR_portability_enumeration", extension_count, extensions);
GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions); GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions);
GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions); GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
(void) glad_vk_has_extension;
glad_vk_free_extensions(extension_count, extensions); glad_vk_free_extensions(extension_count, extensions);
return 1; return 1;
@ -534,11 +665,11 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
int minor = 0; int minor = 0;
#ifdef VK_VERSION_1_1 #ifdef VK_VERSION_1_1
if (vkEnumerateInstanceVersion != NULL) { if (glad_vkEnumerateInstanceVersion != NULL) {
uint32_t version; uint32_t version;
VkResult result; VkResult result;
result = vkEnumerateInstanceVersion(&version); result = glad_vkEnumerateInstanceVersion(&version);
if (result == VK_SUCCESS) { if (result == VK_SUCCESS) {
major = (int) VK_VERSION_MAJOR(version); major = (int) VK_VERSION_MAJOR(version);
minor = (int) VK_VERSION_MINOR(version); minor = (int) VK_VERSION_MINOR(version);
@ -546,9 +677,9 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
} }
#endif #endif
if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) { if (physical_device != NULL && glad_vkGetPhysicalDeviceProperties != NULL) {
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(physical_device, &properties); glad_vkGetPhysicalDeviceProperties(physical_device, &properties);
major = (int) VK_VERSION_MAJOR(properties.apiVersion); major = (int) VK_VERSION_MAJOR(properties.apiVersion);
minor = (int) VK_VERSION_MINOR(properties.apiVersion); minor = (int) VK_VERSION_MINOR(properties.apiVersion);
@ -556,6 +687,8 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
GLAD_VK_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
GLAD_VK_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1;
return GLAD_MAKE_VERSION(major, minor); return GLAD_MAKE_VERSION(major, minor);
} }
@ -564,7 +697,7 @@ int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc
int version; int version;
#ifdef VK_VERSION_1_1 #ifdef VK_VERSION_1_1
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr); glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion");
#endif #endif
version = glad_vk_find_core_vulkan( physical_device); version = glad_vk_find_core_vulkan( physical_device);
if (!version) { if (!version) {
@ -573,6 +706,8 @@ int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc
glad_vk_load_VK_VERSION_1_0(load, userptr); glad_vk_load_VK_VERSION_1_0(load, userptr);
glad_vk_load_VK_VERSION_1_1(load, userptr); glad_vk_load_VK_VERSION_1_1(load, userptr);
glad_vk_load_VK_VERSION_1_2(load, userptr);
glad_vk_load_VK_VERSION_1_3(load, userptr);
if (!glad_vk_find_extensions_vulkan( physical_device)) return 0; if (!glad_vk_find_extensions_vulkan( physical_device)) return 0;
glad_vk_load_VK_EXT_debug_report(load, userptr); glad_vk_load_VK_EXT_debug_report(load, userptr);
@ -591,3 +726,8 @@ int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) {
#ifdef __cplusplus
}
#endif

910
deps/stb_image_write.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -351,8 +351,8 @@ __Note:__ If you haven't already implemented the feature, check first if there
already is an open issue for it and if it's already being developed in an already is an open issue for it and if it's already being developed in an
[experimental branch](https://github.com/glfw/glfw/branches/all). [experimental branch](https://github.com/glfw/glfw/branches/all).
__There is no preferred patch size__. A one character change is just as welcome __There is no preferred patch size__. A one-character change is just as welcome
as one adding a thousand line one, if that is the appropriate size for the as one adding a thousand lines, if that is the appropriate size for the
feature. feature.
In addition to the code, a complete feature includes: In addition to the code, a complete feature includes:

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ GLFW.
@endcode @endcode
This header defines all the constants and declares all the types and function This header defines all the constants and declares all the types and function
prototypes of the GLFW API. By default it also includes the OpenGL header from prototypes of the GLFW API. By default, it also includes the OpenGL header from
your development environment. See [option macros](@ref build_macros) below for your development environment. See [option macros](@ref build_macros) below for
how to select OpenGL ES headers and more. how to select OpenGL ES headers and more.
@ -57,7 +57,7 @@ macros that disable similar headers below it.
Both of these mechanisms depend on the extension loader header defining a known Both of these mechanisms depend on the extension loader header defining a known
macro. If yours doesn't or you don't know which one your users will pick, the macro. If yours doesn't or you don't know which one your users will pick, the
@ref GLFW_INCLUDE_NONE macro will explicitly to prevent the GLFW header from @ref GLFW_INCLUDE_NONE macro will explicitly prevent the GLFW header from
including the OpenGL header. This will also allow you to include the two including the OpenGL header. This will also allow you to include the two
headers in any order. headers in any order.

View File

@ -111,11 +111,7 @@ has been configured in the compositor.
GLFW uses the [xdg-shell GLFW uses the [xdg-shell
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml) protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
to provide better window management. This protocol is part of to provide better window management. This protocol is part of
wayland-protocols 1.12, and mandatory at build time. If the running compositor wayland-protocols 1.12, and mandatory at build time.
does not support this protocol, the older [wl_shell
interface](https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml#n972)
will be used instead. This will result in a worse integration with the
desktop, especially on tiling compositors.
GLFW uses the [relative pointer GLFW uses the [relative pointer
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml) protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml)
@ -133,6 +129,14 @@ wayland-protocols 1.6, and mandatory at build time. If the running compositor
does not support this protocol, the screensaver may start even for full screen does not support this protocol, the screensaver may start even for full screen
windows. windows.
GLFW uses the [libdecor library](https://gitlab.freedesktop.org/libdecor/libdecor)
for window decorations, where available. This in turn provides good quality
client-side decorations (drawn by the application) on desktop systems that do
not support server-side decorations (drawn by the window manager). On systems
that do not provide either libdecor or xdg-decoration, very basic window
decorations are provided. These do not include the window title or any caption
buttons.
GLFW uses the [xdg-decoration GLFW uses the [xdg-decoration
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml) protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
to request decorations to be drawn around its windows. This protocol is part to request decorations to be drawn around its windows. This protocol is part
@ -157,7 +161,7 @@ formats. If GLX 1.3 is not supported, @ref glfwInit will fail.
GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and
`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization `GLX_SGI_swap_control` extensions to provide vertical retrace synchronization
(or _vsync_), in that order of preference. Where none of these extension are (or _vsync_), in that order of preference. When none of these extensions are
available, calling @ref glfwSwapInterval will have no effect. available, calling @ref glfwSwapInterval will have no effect.
GLFW uses the `GLX_ARB_multisample` extension to create contexts with GLFW uses the `GLX_ARB_multisample` extension to create contexts with
@ -226,8 +230,8 @@ extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no
effect and the context will always be flushed when released. effect and the context will always be flushed when released.
GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB` GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB`
extensions to provide support for sRGB framebuffers. Where both of these extensions to provide support for sRGB framebuffers. When both of these
extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
@section compat_osx OpenGL on macOS @section compat_osx OpenGL on macOS

View File

@ -45,7 +45,7 @@ Linux and FreeBSD you will need a few extra packages.
To compile GLFW for X11, you need to have the X11 development packages To compile GLFW for X11, you need to have the X11 development packages
installed. They are not needed to build or run programs that use GLFW. installed. They are not needed to build or run programs that use GLFW.
On Debian and derivates like Ubuntu and Linux Mint the `xorg-dev` meta-package On Debian and derivatives like Ubuntu and Linux Mint the `xorg-dev` meta-package
pulls in the development packages for all of X11. pulls in the development packages for all of X11.
@code{.sh} @code{.sh}
@ -82,8 +82,9 @@ To compile GLFW for Wayland, you need to have the Wayland and xkbcommon
development packages installed. They are not needed to build or run programs development packages installed. They are not needed to build or run programs
that use GLFW. that use GLFW.
On Debian and derivates like Ubuntu and Linux Mint you will need the `libwayland-dev`, On Debian and derivatives like Ubuntu and Linux Mint you will need the `libwayland-dev`,
`libxkbcommon-dev`, `wayland-protocols` and `extra-cmake-modules` packages. `libxkbcommon-dev`, `wayland-protocols` and `extra-cmake-modules` packages.
These will pull in all other dependencies.
@code{.sh} @code{.sh}
sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules
@ -137,7 +138,7 @@ If you wish change any CMake variables in the list, press _Configure_ and then
_Generate_ to have the new values take effect. The variable list will be _Generate_ to have the new values take effect. The variable list will be
populated after the first configure step. populated after the first configure step.
By default GLFW will use X11 on Linux and other Unix-like systems other By default, GLFW will use X11 on Linux and other Unix-like systems other
than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` option in the than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` option in the
GLFW section of the variable list, then apply the new value as described above. GLFW section of the variable list, then apply the new value as described above.
@ -171,7 +172,7 @@ flag.
cmake -S path/to/glfw -B path/to/build -G Xcode cmake -S path/to/glfw -B path/to/build -G Xcode
@endcode @endcode
By default GLFW will use X11 on Linux and other Unix-like systems other By default, GLFW will use X11 on Linux and other Unix-like systems other
than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` CMake option. than macOS. To use Wayland instead, set the `GLFW_USE_WAYLAND` CMake option.
@code{.sh} @code{.sh}
@ -327,7 +328,7 @@ For more details see the
@section compile_manual Compiling GLFW manually @section compile_manual Compiling GLFW manually
If you wish to compile GLFW without its CMake build environment then you will If you wish to compile GLFW without its CMake build environment then you will
have to do at least some of the platform detection yourself. GLFW needs have to do at least some of the platform-detection yourself. GLFW needs
a configuration macro to be defined in order to know what window system it is a configuration macro to be defined in order to know what window system it is
being compiled for and also has optional, platform-specific ones for various being compiled for and also has optional, platform-specific ones for various
features. features.

View File

@ -61,7 +61,7 @@ information. The name and number of this chapter unfortunately varies between
versions and APIs, but has at times been named _Shared Objects and Multiple versions and APIs, but has at times been named _Shared Objects and Multiple
Contexts_. Contexts_.
GLFW comes with a barebones object sharing example program called `sharing`. GLFW comes with a bare-bones object sharing example program called `sharing`.
@subsection context_offscreen Offscreen contexts @subsection context_offscreen Offscreen contexts
@ -92,9 +92,10 @@ creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
@subsection context_less Windows without contexts @subsection context_less Windows without contexts
You can disable context creation by setting the You can disable context creation by setting the
[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`. Windows [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`.
without contexts must not be passed to @ref glfwMakeContextCurrent or @ref
glfwSwapBuffers. Windows without contexts should not be passed to @ref glfwMakeContextCurrent or
@ref glfwSwapBuffers. Doing this generates a @ref GLFW_NO_WINDOW_CONTEXT error.
@section context_current Current context @section context_current Current context
@ -193,7 +194,7 @@ it suppresses the development environment's OpenGL or OpenGL ES header.
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
Finally you need to initialize glad once you have a suitable current context. Finally, you need to initialize glad once you have a suitable current context.
@code @code
window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
@ -209,7 +210,7 @@ gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
Once glad has been loaded, you have access to all OpenGL core and extension Once glad has been loaded, you have access to all OpenGL core and extension
functions supported by both the context you created and the glad loader you functions supported by both the context you created and the glad loader you
generated and you are ready to start rendering. generated. After that, you are ready to start rendering.
You can specify a minimum required OpenGL or OpenGL ES version with You can specify a minimum required OpenGL or OpenGL ES version with
[context hints](@ref window_hints_ctx). If your needs are more complex, you can [context hints](@ref window_hints_ctx). If your needs are more complex, you can

View File

@ -24,7 +24,7 @@ All input callbacks receive a window handle. By using the
or objects from your callbacks. or objects from your callbacks.
To get a better feel for how the various events callbacks behave, run the To get a better feel for how the various events callbacks behave, run the
`events` test program. It register every callback supported by GLFW and prints `events` test program. It registers every callback supported by GLFW and prints
out all arguments provided for every event, along with time and sequence out all arguments provided for every event, along with time and sequence
information. information.
@ -95,7 +95,7 @@ new size before everything returns back out of the @ref glfwSetWindowSize call.
GLFW divides keyboard input into two categories; key events and character GLFW divides keyboard input into two categories; key events and character
events. Key events relate to actual physical keyboard keys, whereas character events. Key events relate to actual physical keyboard keys, whereas character
events relate to the Unicode code points generated by pressing some of them. events relate to the text that is generated by pressing some of them.
Keys and characters do not map 1:1. A single key press may produce several Keys and characters do not map 1:1. A single key press may produce several
characters, and a single character may require several keys to produce. This characters, and a single character may require several keys to produce. This
@ -123,23 +123,39 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
} }
@endcode @endcode
The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. Events with
will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example `GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press. Most
_E-mail_ and _Play_ keys. keys will also emit events with `GLFW_REPEAT` actions while a key is held down.
Note that many keyboards have a limit on how many keys being simultaneous held
down that they can detect. This limit is called
[key rollover](https://en.wikipedia.org/wiki/Key_rollover).
Key events with `GLFW_REPEAT` actions are intended for text input. They are
emitted at the rate set in the user's keyboard settings. At most one key is
repeated even if several keys are held down. `GLFW_REPEAT` actions should not
be relied on to know which keys are being held down or to drive animation.
Instead you should either save the state of relevant keys based on `GLFW_PRESS`
and `GLFW_RELEASE` actions, or call @ref glfwGetKey, which provides basic cached
key state.
The key will be one of the existing [key tokens](@ref keys), or
`GLFW_KEY_UNKNOWN` if GLFW lacks a token for it, for example _E-mail_ and _Play_
keys.
The scancode is unique for every key, regardless of whether it has a key token. The scancode is unique for every key, regardless of whether it has a key token.
Scancodes are platform-specific but consistent over time, so keys will have Scancodes are platform-specific but consistent over time, so keys will have
different scancodes depending on the platform but they are safe to save to disk. different scancodes depending on the platform but they are safe to save to disk.
You can query the scancode for any [named key](@ref keys) on the current You can query the scancode for any [key token](@ref keys) supported on the
platform with @ref glfwGetKeyScancode. current platform with @ref glfwGetKeyScancode.
@code @code
const int scancode = glfwGetKeyScancode(GLFW_KEY_X); const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
set_key_mapping(scancode, swap_weapons); set_key_mapping(scancode, swap_weapons);
@endcode @endcode
The last reported state for every [named key](@ref keys) is also saved in The last reported state for every physical key with a [key token](@ref keys) is
per-window state arrays that can be polled with @ref glfwGetKey. also saved in per-window state arrays that can be polled with @ref glfwGetKey.
@code @code
int state = glfwGetKey(window, GLFW_KEY_E); int state = glfwGetKey(window, GLFW_KEY_E);
@ -152,7 +168,8 @@ if (state == GLFW_PRESS)
The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
This function only returns cached key event state. It does not poll the This function only returns cached key event state. It does not poll the
system for the current physical state of the key. system for the current state of the physical key. It also does not provide any
key repeat information.
@anchor GLFW_STICKY_KEYS @anchor GLFW_STICKY_KEYS
Whenever you poll state, you risk missing the state change you are looking for. Whenever you poll state, you risk missing the state change you are looking for.
@ -183,15 +200,15 @@ Lock was on when the event occurred and the @ref GLFW_MOD_NUM_LOCK bit set if
Num Lock was on. Num Lock was on.
The `GLFW_KEY_LAST` constant holds the highest value of any The `GLFW_KEY_LAST` constant holds the highest value of any
[named key](@ref keys). [key token](@ref keys).
@subsection input_char Text input @subsection input_char Text input
GLFW supports text input in the form of a stream of GLFW supports text input in the form of a stream of
[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the [Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the
operating system text input system. Unlike key input, text input obeys keyboard operating system text input system. Unlike key input, text input is affected by
layouts and modifier keys and supports composing characters using keyboard layouts and modifier keys and supports composing characters using
[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can [dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
encode the code points into UTF-8 or any other encoding you prefer. encode the code points into UTF-8 or any other encoding you prefer.
@ -370,7 +387,7 @@ sequential rows, starting from the top-left corner.
@subsubsection cursor_standard Standard cursor creation @subsubsection cursor_standard Standard cursor creation
A cursor with a [standard shape](@ref shapes) from the current system cursor A cursor with a [standard shape](@ref shapes) from the current system cursor
theme can be can be created with @ref glfwCreateStandardCursor. theme can be created with @ref glfwCreateStandardCursor.
@code @code
GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR); GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
@ -478,8 +495,9 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
Mouse button states for [named buttons](@ref buttons) are also saved in The last reported state for every [supported mouse button](@ref buttons) is also
per-window state arrays that can be polled with @ref glfwGetMouseButton. saved in per-window state arrays that can be polled with @ref
glfwGetMouseButton.
@code @code
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
@ -512,7 +530,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
otherwise it will remain `GLFW_PRESS`. otherwise it will remain `GLFW_PRESS`.
The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
[named button](@ref buttons). [supported mouse button](@ref buttons).
@subsection scrolling Scroll input @subsection scrolling Scroll input

View File

@ -102,6 +102,30 @@ a nib or manually, when the first window is created, which is when AppKit is
initialized. Set this with @ref glfwInitHint. initialized. Set this with @ref glfwInitHint.
@subsubsection init_hints_wayland Wayland specific init hints
@anchor GLFW_WAYLAND_LIBDECOR_hint
__GLFW_WAYLAND_LIBDECOR__ specifies whether to use
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) for window
decorations where available. Possible values are `GLFW_WAYLAND_PREFER_LIBDECOR`
and `GLFW_WAYLAND_DISABLE_LIBDECOR`. This is ignored on other platforms.
@note This init hint was added in 3.3.9 and is not present in earlier patch releases. It
is safe to attempt to set this hint on earlier versions of GLFW 3.3 but it will emit
a harmless @ref GLFW_INVALID_ENUM error. If you need to avoid causing any errors, you can
check the library version first with @ref glfwGetVersion.
@note To set this hint while also building against earlier versions of GLFW 3.3, you can
use the numerical constants directly.
@note @code
int minor, patch;
glfwGetVersion(NULL, &minor, &patch);
if (minor > 3 || (minor == 3 && patch >= 9))
glfwInitHint(0x00053001 /*GLFW_WAYLAND_LIBDECOR*/, 0x00038002 /*GLFW_WAYLAND_DISABLE_LIBDECOR*/);
@endcode
@subsubsection init_hints_values Supported and default values @subsubsection init_hints_values Supported and default values
Initialization hint | Default value | Supported values Initialization hint | Default value | Supported values
@ -109,6 +133,7 @@ Initialization hint | Default value | Supported values
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_WAYLAND_LIBDECOR | `GLFW_WAYLAND_PREFER_LIBDECOR` | `GLFW_WAYLAND_PREFER_LIBDECOR` or `GLFW_WAYLAND_DISABLE_LIBDECOR`
@subsection intro_init_terminate Terminating GLFW @subsection intro_init_terminate Terminating GLFW
@ -124,9 +149,9 @@ This will destroy any remaining window, monitor and cursor objects, restore any
modified gamma ramps, re-enable the screensaver if it had been disabled and free modified gamma ramps, re-enable the screensaver if it had been disabled and free
any other resources allocated by GLFW. any other resources allocated by GLFW.
Once the library is terminated, it is as if it had never been initialized and Once the library is terminated, it is as if it had never been initialized, therefore
you will need to initialize it again before being able to use GLFW. If the you will need to initialize it again before being able to use GLFW. If the
library was not initialized or had already been terminated, it return library was not initialized or had already been terminated, it returns
immediately. immediately.
@ -246,14 +271,14 @@ which monitor the window is currently considered to be on.
This section describes the conditions under which GLFW can be expected to This section describes the conditions under which GLFW can be expected to
function, barring bugs in the operating system or drivers. Use of GLFW outside function, barring bugs in the operating system or drivers. Use of GLFW outside
of these limits may work on some platforms, or on some machines, or some of the these limits may work on some platforms, or on some machines, or some of the
time, or on some versions of GLFW, but it may break at any time and this will time, or on some versions of GLFW, but it may break at any time and this will
not be considered a bug. not be considered a bug.
@subsection lifetime Pointer lifetimes @subsection lifetime Pointer lifetimes
GLFW will never free any pointer you provide to it and you must never free any GLFW will never free any pointer you provide to it, and you must never free any
pointer it provides to you. pointer it provides to you.
Many GLFW functions return pointers to dynamically allocated structures, strings Many GLFW functions return pointers to dynamically allocated structures, strings
@ -444,11 +469,11 @@ The format of the string is as follows:
- The name of the context creation API - The name of the context creation API
- Any additional options or APIs - Any additional options or APIs
For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL For example, when compiling GLFW 3.3.9 with MinGW for Windows, may result in
back ends, the version string may look something like this: a version string like this:
@code @code
3.0.0 Win32 WGL MinGW 3.3.9 Win32 WGL EGL OSMesa MinGW
@endcode @endcode
*/ */

View File

@ -138,7 +138,7 @@ glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm);
@endcode @endcode
While this can be used to calculate the raw DPI of a monitor, this is often not While this can be used to calculate the raw DPI of a monitor, this is often not
useful. Instead use the [monitor content scale](@ref monitor_scale) and useful. Instead, use the [monitor content scale](@ref monitor_scale) and
[window content scale](@ref window_scale) to scale your content. [window content scale](@ref window_scale) to scale your content.
@ -261,7 +261,7 @@ To experiment with gamma correction via the @ref glfwSetGamma function, run the
`gamma` test program. `gamma` test program.
@note The software controlled gamma ramp is applied _in addition_ to the @note The software controlled gamma ramp is applied _in addition_ to the
hardware gamma correction, which today is usually an approximation of sRGB 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 gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
produce the default (usually sRGB-like) behavior. produce the default (usually sRGB-like) behavior.

View File

@ -243,7 +243,7 @@ while (!glfwWindowShouldClose(window))
@endcode @endcode
The close callback no longer returns a value. Instead, it is called after the The close callback no longer returns a value. Instead, it is called after the
close flag has been set so it can override its value, if it chooses to, before close flag has been set, so it can optionally override its value, before
event processing completes. You may however not call @ref glfwDestroyWindow event processing completes. You may however not call @ref glfwDestroyWindow
from the close callback (or any other window related callback). from the close callback (or any other window related callback).
@ -350,11 +350,11 @@ from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or
GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to
the values generated by the current keyboard layout. The tokens are named the values generated by the current keyboard layout. The tokens are named
according to the values they would have using the standard US layout, but this according to the values they would have in the standard US layout, but this
is only a convenience, as most programmers are assumed to know that layout. is only a convenience, as most programmers are assumed to know that layout.
This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and
is the same key in the same place regardless of what keyboard layouts the users is the same key in the same place regardless of what keyboard layouts the users
of your program has. of your program have.
The key input facility was never meant for text input, although using it that The key input facility was never meant for text input, although using it that
way worked slightly better in GLFW 2. If you were using it to input text, you way worked slightly better in GLFW 2. If you were using it to input text, you

View File

@ -37,6 +37,16 @@ SDK](https://vulkan.lunarg.com/).
For more information see @ref vulkan_guide. For more information see @ref vulkan_guide.
@subsubsection wayland_libdecor_33 Wayland libdecor decorations
GLFW now supports improved fallback window decorations via
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor).
Support for libdecor can be toggled before GLFW is initialized with the
[GLFW_WAYLAND_LIBDECOR](@ref GLFW_WAYLAND_LIBDECOR_hint) init hint. It is
enabled by default.
@subsubsection content_scale_33 Content scale queries for DPI-aware rendering @subsubsection content_scale_33 Content scale queries for DPI-aware rendering
GLFW now provides content scales for windows and monitors, i.e. the ratio GLFW now provides content scales for windows and monitors, i.e. the ratio
@ -312,6 +322,19 @@ Starting with GLFW 3.3.7, events posted with @ref glfwPostEmptyEvent now use a s
unnamed pipe instead of sending an X11 client event to the helper window. unnamed pipe instead of sending an X11 client event to the helper window.
@subsubsection wayland_alpha_34 Frambuffer may lack alpha channel on older Wayland systems
On Wayland, when creating an EGL context on a machine lacking the new
`EGL_EXT_present_opaque` extension, the @ref GLFW_ALPHA_BITS window hint will be
ignored and the framebuffer will have no alpha channel. This is because some
Wayland compositors treat any buffer with an alpha channel as per-pixel
transparent.
If you want a per-pixel transparent window, see the
[GLFW_TRANSPARENT_FRAMEBUFFER](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) window
hint.
@subsection deprecations_33 Deprecations in version 3.3 @subsection deprecations_33 Deprecations in version 3.3
@subsubsection charmods_callback_33 Character with modifiers callback @subsubsection charmods_callback_33 Character with modifiers callback
@ -378,6 +401,13 @@ Existing projects and makefiles that set the `LIB_SUFFIX` option will use the
suffix chosen by the GNUInstallDirs package and the option will be ignored. suffix chosen by the GNUInstallDirs package and the option will be ignored.
@subsubsection wl_shell_33 Support for the wl_shell protocol
Support for the wl_shell protocol has been removed and GLFW now only supports
the XDG-Shell protocol. If your Wayland compositor does not support XDG-Shell
then GLFW will fail to initialize.
@subsubsection mir_removed_33 Mir support @subsubsection mir_removed_33 Mir support
The experimental Mir support has been completely removed as the Mir project has The experimental Mir support has been completely removed as the Mir project has
@ -423,6 +453,9 @@ Use Wayland or X11 instead.
- @ref GLFWwindowmaximizefun - @ref GLFWwindowmaximizefun
- @ref GLFWwindowcontentscalefun - @ref GLFWwindowcontentscalefun
- @ref GLFWgamepadstate - @ref GLFWgamepadstate
- @ref GLFW_WAYLAND_LIBDECOR
- @ref GLFW_WAYLAND_PREFER_LIBDECOR
- @ref GLFW_WAYLAND_DISABLE_LIBDECOR
@subsubsection constants_33 New constants in version 3.3 @subsubsection constants_33 New constants in version 3.3

View File

@ -144,10 +144,6 @@ if (!window)
} }
@endcode @endcode
The window handle is passed to all window related functions and is provided to
along to all window related callbacks, so they can tell which window received
the event.
When a window and context is no longer needed, destroy it. When a window and context is no longer needed, destroy it.
@code @code
@ -233,7 +229,7 @@ events as described below.
@subsection quick_render Rendering with OpenGL @subsection quick_render Rendering with OpenGL
Once you have a current OpenGL context, you can use OpenGL normally. In this Once you have a current OpenGL context, you can use OpenGL normally. In this
tutorial, a multi-colored rotating triangle will be rendered. The framebuffer tutorial, a multicolored rotating triangle will be rendered. The framebuffer
size needs to be retrieved for `glViewport`. size needs to be retrieved for `glViewport`.
@code @code

View File

@ -42,9 +42,9 @@ The @ref GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader
directly instead of dynamically loading it at runtime. Not linking against the directly instead of dynamically loading it at runtime. Not linking against the
Vulkan loader will then be a compile-time error. Vulkan loader will then be a compile-time error.
@macos Because the Vulkan loader and ICD are not installed globally on macOS, @macos To make your application be redistributable you will need to set up the
you need to set up the application bundle according to the LunarG SDK application bundle according to the LunarG SDK documentation. This is explained
documentation. This is explained in more detail in the in more detail in the
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
@ -131,7 +131,7 @@ PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
@endcode @endcode
Device-specific functions may execute a little bit faster, due to not having to Device-specific functions may execute a little faster, due to not having to
dispatch internally based on the device passed to them. For more information dispatch internally based on the device passed to them. For more information
about `vkGetDeviceProcAddr`, see the Vulkan documentation. about `vkGetDeviceProcAddr`, see the Vulkan documentation.
@ -177,6 +177,13 @@ 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 array, as it is an error to specify an extension more than once in the
`VkInstanceCreateInfo` struct. `VkInstanceCreateInfo` struct.
@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
info flags for MoltenVK to show up in the list of physical devices. For more
information, see the Vulkan and MoltenVK documentation.
@section vulkan_present Querying for Vulkan presentation support @section vulkan_present Querying for Vulkan presentation support

View File

@ -471,7 +471,8 @@ should also declare this in its `Info.plist` by setting the
@anchor GLFW_X11_CLASS_NAME_hint @anchor GLFW_X11_CLASS_NAME_hint
@anchor GLFW_X11_INSTANCE_NAME_hint @anchor GLFW_X11_INSTANCE_NAME_hint
__GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired __GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired
ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. Both
hints need to be set to something other than an empty string for them to take effect.
These are set with @ref glfwWindowHintString. These are set with @ref glfwWindowHintString.

View File

@ -262,13 +262,12 @@ extern "C" {
/* We are building GLFW as a Win32 DLL */ /* We are building GLFW as a Win32 DLL */
#define GLFWAPI __declspec(dllexport) #define GLFWAPI __declspec(dllexport)
#elif defined(_WIN32) && defined(GLFW_DLL) #elif defined(_WIN32) && defined(GLFW_DLL)
/* We are calling GLFW as a Win32 DLL */ /* We are calling a GLFW Win32 DLL */
#define GLFWAPI __declspec(dllimport) #define GLFWAPI __declspec(dllimport)
#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
/* We are building GLFW as a shared / dynamic library */ /* We are building GLFW as a Unix shared library */
#define GLFWAPI __attribute__((visibility("default"))) #define GLFWAPI __attribute__((visibility("default")))
#else #else
/* We are building or calling GLFW as a static library */
#define GLFWAPI #define GLFWAPI
#endif #endif
@ -299,7 +298,7 @@ extern "C" {
* release is made that does not contain any API changes. * release is made that does not contain any API changes.
* @ingroup init * @ingroup init
*/ */
#define GLFW_VERSION_REVISION 7 #define GLFW_VERSION_REVISION 9
/*! @} */ /*! @} */
/*! @brief One. /*! @brief One.
@ -362,10 +361,15 @@ extern "C" {
#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) #define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) #define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP)
#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN) #define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
/*! @ingroup input
*/
#define GLFW_KEY_UNKNOWN -1
/*! @} */ /*! @} */
/*! @defgroup keys Keyboard keys /*! @defgroup keys Keyboard key tokens
* @brief Keyboard key IDs. * @brief Keyboard key tokens.
* *
* See [key input](@ref input_key) for how these are used. * See [key input](@ref input_key) for how these are used.
* *
@ -388,9 +392,6 @@ extern "C" {
* @{ * @{
*/ */
/* The unknown key */
#define GLFW_KEY_UNKNOWN -1
/* Printable keys */ /* Printable keys */
#define GLFW_KEY_SPACE 32 #define GLFW_KEY_SPACE 32
#define GLFW_KEY_APOSTROPHE 39 /* ' */ #define GLFW_KEY_APOSTROPHE 39 /* ' */
@ -1075,6 +1076,9 @@ extern "C" {
#define GLFW_EGL_CONTEXT_API 0x00036002 #define GLFW_EGL_CONTEXT_API 0x00036002
#define GLFW_OSMESA_CONTEXT_API 0x00036003 #define GLFW_OSMESA_CONTEXT_API 0x00036003
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
/*! @defgroup shapes Standard cursor shapes /*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes. * @brief Standard system cursor shapes.
* *
@ -1201,6 +1205,11 @@ extern "C" {
* macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint).
*/ */
#define GLFW_COCOA_MENUBAR 0x00051002 #define GLFW_COCOA_MENUBAR 0x00051002
/*! @brief Wayland specific init hint.
*
* Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint).
*/
#define GLFW_WAYLAND_LIBDECOR 0x00053001
/*! @} */ /*! @} */
#define GLFW_DONT_CARE -1 #define GLFW_DONT_CARE -1
@ -2885,8 +2894,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* @param[in] images The images to create the icon from. This is ignored if * @param[in] images The images to create the icon from. This is ignored if
* count is zero. * count is zero.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR. * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
* *
* @pointer_lifetime The specified image data is copied before this function * @pointer_lifetime The specified image data is copied before this function
* returns. * returns.
@ -3296,18 +3305,15 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* previously restored. If the window is already iconified, this function does * previously restored. If the window is already iconified, this function does
* nothing. * nothing.
* *
* If the specified window is a full screen window, the original monitor * If the specified window is a full screen window, GLFW restores the original
* resolution is restored until the window is restored. * video mode of the monitor. The window's desired video mode is set again
* when the window is restored.
* *
* @param[in] window The window to iconify. * @param[in] window The window to iconify.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland There is no concept of iconification in wl_shell, this
* function will emit @ref GLFW_PLATFORM_ERROR when using this deprecated
* protocol.
*
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref window_iconify * @sa @ref window_iconify
@ -3327,8 +3333,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* (minimized) or maximized. If the window is already restored, this function * (minimized) or maximized. If the window is already restored, this function
* does nothing. * does nothing.
* *
* If the specified window is a full screen window, the resolution chosen for * If the specified window is an iconified full screen window, its desired
* the window is restored on the selected monitor. * video mode is set again for its monitor when the window is restored.
* *
* @param[in] window The window to restore. * @param[in] window The window to restore.
* *
@ -3596,6 +3602,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
* errors. However, this function should not fail as long as it is passed * errors. However, this function should not fail as long as it is passed
* valid arguments and the library has been [initialized](@ref intro_init). * valid arguments and the library has been [initialized](@ref intro_init).
* *
* @remark @wayland The Wayland protocol provides no way to check whether a
* window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`.
*
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref window_attribs * @sa @ref window_attribs
@ -3887,8 +3896,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark @wayland The wl_shell protocol has no concept of iconification, * @remark @wayland The XDG-shell protocol has no event for iconification, so
* this callback will never be called when using this deprecated protocol. * this callback will never be called.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
@ -4308,8 +4317,8 @@ GLFWAPI int glfwRawMouseMotionSupported(void);
* @param[in] scancode The scancode of the key to query. * @param[in] scancode The scancode of the key to query.
* @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR. * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
* *
* @remark The contents of the returned string may change when a keyboard * @remark The contents of the returned string may change when a keyboard
* layout change event is received. * layout change event is received.
@ -4331,15 +4340,18 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode);
* *
* This function returns the platform-specific scancode of the specified key. * This function returns the platform-specific scancode of the specified key.
* *
* If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this * If the specified [key token](@ref keys) corresponds to a physical key not
* method will return `-1`. * supported on the current platform then this method will return `-1`.
* Calling this function with anything other than a key token will return `-1`
* and generate a @ref GLFW_INVALID_ENUM error.
* *
* @param[in] key Any [named key](@ref keys). * @param[in] key Any [key token](@ref keys).
* @return The platform-specific scancode for the key, or `-1` if an * @return The platform-specific scancode for the key, or `-1` if the key is
* [error](@ref error_handling) occurred. * not supported on the current platform or an [error](@ref error_handling)
* occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * GLFW_INVALID_ENUM.
* *
* @thread_safety This function may be called from any thread. * @thread_safety This function may be called from any thread.
* *
@ -4356,8 +4368,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
* *
* This function returns the last state reported for the specified key to the * This function returns the last state reported for the specified key to the
* specified window. The returned state is one of `GLFW_PRESS` or * specified window. The returned state is one of `GLFW_PRESS` or
* `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback.
* the key callback.
* *
* If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns
* `GLFW_PRESS` the first time you call it for a key that was pressed, even if * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
@ -4518,8 +4529,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
* @return The handle of the created cursor, or `NULL` if an * @return The handle of the created cursor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR. * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
* *
* @pointer_lifetime The specified image data is copied before this function * @pointer_lifetime The specified image data is copied before this function
* returns. * returns.
@ -4649,9 +4660,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
* [character callback](@ref glfwSetCharCallback) instead. * [character callback](@ref glfwSetCharCallback) instead.
* *
* When a window loses input focus, it will generate synthetic key release * When a window loses input focus, it will generate synthetic key release
* events for all pressed keys. You can tell these events from user-generated * events for all pressed keys with associated key tokens. You can tell these
* events by the fact that the synthetic ones are generated after the focus * events from user-generated events by the fact that the synthetic ones are
* loss event has been processed, i.e. after the * generated after the focus loss event has been processed, i.e. after the
* [window focus callback](@ref glfwSetWindowFocusCallback) has been called. * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
* *
* The scancode of a key is specific to that platform or sometimes even to that * The scancode of a key is specific to that platform or sometimes even to that
@ -5550,12 +5561,15 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
* thread. * thread.
* *
* This function makes the OpenGL or OpenGL ES context of the specified window * This function makes the OpenGL or OpenGL ES context of the specified window
* current on the calling thread. A context must only be made current on * current on the calling thread. It can also detach the current context from
* a single thread at a time and each thread can have only a single current * the calling thread without making a new one current by passing in `NULL`.
* context at a time.
* *
* When moving a context between threads, you must make it non-current on the * A context must only be made current on a single thread at a time and each
* old thread before making it current on the new one. * thread can have only a single current context at a time. Making a context
* current detaches any previously current context on the calling thread.
*
* 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.
* *
* By default, making a context non-current implicitly forces a pipeline flush. * By default, making a context non-current implicitly forces a pipeline flush.
* On machines that support `GL_KHR_context_flush_control`, you can control * On machines that support `GL_KHR_context_flush_control`, you can control
@ -5570,6 +5584,10 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
* @param[in] window The window whose context to make current, or `NULL` to * @param[in] window The window whose context to make current, or `NULL` to
* detach the current context. * detach the current context.
* *
* @remarks If the previously current context was created via a different
* context creation API than the one passed to this function, GLFW will still
* detach the previous one from its API before making the new one current.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
* *
@ -6002,6 +6020,7 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window
*/ */
#ifndef GLAPIENTRY #ifndef GLAPIENTRY
#define GLAPIENTRY APIENTRY #define GLAPIENTRY APIENTRY
#define GLFW_GLAPIENTRY_DEFINED
#endif #endif
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */

View File

@ -74,6 +74,16 @@ extern "C" {
* and which platform-specific headers to include. It is then up your (by * and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be * definition platform-specific) code to handle which of these should be
* defined. * defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/ */
@ -81,26 +91,35 @@ extern "C" {
* System headers and types * System headers and types
*************************************************************************/ *************************************************************************/
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_KHR_debug callback) * example to allow applications to correctly declare a GL_KHR_debug callback)
// but windows.h assumes no one will define APIENTRY before it does * but windows.h assumes no one will define APIENTRY before it does
*/
#if defined(GLFW_APIENTRY_DEFINED) #if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY #undef APIENTRY
#undef GLFW_APIENTRY_DEFINED #undef GLFW_APIENTRY_DEFINED
#endif #endif
#include <windows.h> #include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) #endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__) #if defined(__OBJC__)
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#else #else
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
typedef void* id; #include <objc/objc.h>
#endif #endif
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) #endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) #endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h> #include <wayland-client.h>
#endif #endif
@ -111,15 +130,33 @@ extern "C" {
/* NSGL is declared by Cocoa.h */ /* NSGL is declared by Cocoa.h */
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_GLX) #if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h> #include <GL/glx.h>
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL) #if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h> #include <EGL/egl.h>
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA) #if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h> #include <GL/osmesa.h>
#endif #endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/************************************************************************* /*************************************************************************
* Functions * Functions
@ -475,6 +512,9 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *

View File

@ -168,6 +168,7 @@ if (BUILD_SHARED_LIBS)
# Add a suffix to the import library to avoid naming conflicts # Add a suffix to the import library to avoid naming conflicts
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
endif() endif()
set (GLFW_LIB_NAME_SUFFIX "dll")
target_compile_definitions(glfw INTERFACE GLFW_DLL) target_compile_definitions(glfw INTERFACE GLFW_DLL)
elseif (APPLE) elseif (APPLE)

View File

@ -251,7 +251,7 @@ static void createKeyTables(void)
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10; _glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11; _glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12; _glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
_glfw.ns.keycodes[0x69] = GLFW_KEY_F13; _glfw.ns.keycodes[0x69] = GLFW_KEY_PRINT_SCREEN;
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14; _glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15; _glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16; _glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
@ -475,18 +475,26 @@ void* _glfwLoadLocalVulkanLoaderNS(void)
if (!bundle) if (!bundle)
return NULL; return NULL;
CFURLRef url = CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib")); if (!frameworksUrl)
if (!url)
return NULL; return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX]; char path[PATH_MAX];
void* handle = NULL; void* handle = NULL;
if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1)) if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfw_dlopen(path); handle = _glfw_dlopen(path);
CFRelease(url); CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle; return handle;
} }
@ -607,6 +615,8 @@ void _glfwPlatformTerminate(void)
free(_glfw.ns.clipboardString); free(_glfw.ns.clipboardString);
_glfwTerminateNSGL(); _glfwTerminateNSGL();
_glfwTerminateEGL();
_glfwTerminateOSMesa();
_glfwTerminateJoysticksNS(); _glfwTerminateJoysticksNS();
} // autoreleasepool } // autoreleasepool

View File

@ -98,8 +98,7 @@ static void closeJoystick(_GLFWjoystick* js)
{ {
int i; int i;
if (!js->present) _glfwInputJoystick(js, GLFW_DISCONNECTED);
return;
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
@ -114,7 +113,6 @@ static void closeJoystick(_GLFWjoystick* js)
CFRelease(js->ns.hats); CFRelease(js->ns.hats);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// Callback for user-initiated joystick addition // Callback for user-initiated joystick addition
@ -139,6 +137,14 @@ static void matchCallback(void* context,
return; return;
} }
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
// It is reportedly possible for this to fail on macOS 13 Ventura
// if the application does not have input monitoring permissions
if (!elements)
return;
axes = CFArrayCreateMutable(NULL, 0, NULL); axes = CFArrayCreateMutable(NULL, 0, NULL);
buttons = CFArrayCreateMutable(NULL, 0, NULL); buttons = CFArrayCreateMutable(NULL, 0, NULL);
hats = CFArrayCreateMutable(NULL, 0, NULL); hats = CFArrayCreateMutable(NULL, 0, NULL);
@ -182,9 +188,6 @@ static void matchCallback(void* context,
name[8], name[9], name[10]); name[8], name[9], name[10]);
} }
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
for (i = 0; i < CFArrayGetCount(elements); i++) for (i = 0; i < CFArrayGetCount(elements); i++)
{ {
IOHIDElementRef native = (IOHIDElementRef) IOHIDElementRef native = (IOHIDElementRef)
@ -294,9 +297,9 @@ static void removeCallback(void* context,
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (_glfw.joysticks[jid].ns.device == device) if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
{ {
closeJoystick(_glfw.joysticks + jid); closeJoystick(&_glfw.joysticks[jid]);
break; break;
} }
} }
@ -392,7 +395,10 @@ void _glfwTerminateJoysticksNS(void)
int jid; int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
closeJoystick(_glfw.joysticks + jid); {
if (_glfw.joysticks[jid].connected)
closeJoystick(&_glfw.joysticks[jid]);
}
CFRelease(_glfw.ns.hidManager); CFRelease(_glfw.ns.hidManager);
_glfw.ns.hidManager = NULL; _glfw.ns.hidManager = NULL;
@ -470,7 +476,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
} }
} }
return js->present; return js->connected;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) void _glfwPlatformUpdateGamepadGUID(char* guid)

View File

@ -98,11 +98,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
IOObjectRelease(it); IOObjectRelease(it);
if (!service) if (!service)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find service port for display");
return _glfw_strdup("Display"); return _glfw_strdup("Display");
}
CFDictionaryRef names = CFDictionaryRef names =
CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); CFDictionaryGetValue(info, CFSTR(kDisplayProductName));

View File

@ -31,25 +31,9 @@
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
// Returns the style mask corresponding to the window settings // HACK: This enum value is missing from framework headers on OS X 10.11 despite
// // having been (according to documentation) added in Mac OS X 10.7
static NSUInteger getStyleMask(_GLFWwindow* window) #define NSWindowCollectionBehaviorFullScreenNone (1 << 9)
{
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
if (window->monitor || !window->decorated)
styleMask |= NSWindowStyleMaskBorderless;
else
{
styleMask |= NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable;
if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;
}
return styleMask;
}
// Returns whether the cursor is in the content area of the specified window // Returns whether the cursor is in the content area of the specified window
// //
@ -324,12 +308,17 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
} }
- (void)windowDidChangeOcclusionState:(NSNotification* )notification - (void)windowDidChangeOcclusionState:(NSNotification* )notification
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
if ([window->ns.object respondsToSelector:@selector(occlusionState)])
{ {
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible) if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
window->ns.occluded = GLFW_FALSE; window->ns.occluded = GLFW_FALSE;
else else
window->ns.occluded = GLFW_TRUE; window->ns.occluded = GLFW_TRUE;
} }
#endif
}
@end @end
@ -809,9 +798,21 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
else else
contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height);
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
if (window->monitor || !window->decorated)
styleMask |= NSWindowStyleMaskBorderless;
else
{
styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;
}
window->ns.object = [[GLFWWindow alloc] window->ns.object = [[GLFWWindow alloc]
initWithContentRect:contentRect initWithContentRect:contentRect
styleMask:getStyleMask(window) styleMask:styleMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
@ -837,6 +838,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
NSWindowCollectionBehaviorManaged; NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior]; [window->ns.object setCollectionBehavior:behavior];
} }
else
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenNone;
[window->ns.object setCollectionBehavior:behavior];
}
if (wndconfig->floating) if (wndconfig->floating)
[window->ns.object setLevel:NSFloatingWindowLevel]; [window->ns.object setLevel:NSFloatingWindowLevel];
@ -934,6 +941,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
} }
if (window->monitor) if (window->monitor)
@ -941,6 +951,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformShowWindow(window); _glfwPlatformShowWindow(window);
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
acquireMonitor(window); acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwPlatformShowWindow(window);
if (wndconfig->focused)
_glfwPlatformFocusWindow(window);
}
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1219,9 +1241,10 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
{ {
const NSRect contentRect = const NSRect contentRect =
NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height); NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height);
const NSUInteger styleMask = [window->ns.object styleMask];
const NSRect frameRect = const NSRect frameRect =
[window->ns.object frameRectForContentRect:contentRect [window->ns.object frameRectForContentRect:contentRect
styleMask:getStyleMask(window)]; styleMask:styleMask];
[window->ns.object setFrame:frameRect display:YES]; [window->ns.object setFrame:frameRect display:YES];
} }
@ -1238,7 +1261,27 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
// TODO: Solve this in a less terrible way // TODO: Solve this in a less terrible way
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
const NSUInteger styleMask = getStyleMask(window); NSUInteger styleMask = [window->ns.object styleMask];
if (window->monitor)
{
styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable);
styleMask |= NSWindowStyleMaskBorderless;
}
else
{
if (window->decorated)
{
styleMask &= ~NSWindowStyleMaskBorderless;
styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
}
if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;
else
styleMask &= ~NSWindowStyleMaskResizable;
}
[window->ns.object setStyleMask:styleMask]; [window->ns.object setStyleMask:styleMask];
// HACK: Changing the style mask can cause the first responder to be cleared // HACK: Changing the style mask can cause the first responder to be cleared
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
@ -1284,6 +1327,20 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
else else
[window->ns.object setLevel:NSNormalWindowLevel]; [window->ns.object setLevel:NSNormalWindowLevel];
if (window->resizable)
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenPrimary |
NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior];
}
else
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenNone;
[window->ns.object setCollectionBehavior:behavior];
}
[window->ns.object setHasShadow:YES]; [window->ns.object setHasShadow:YES];
// HACK: Clearing NSWindowStyleMaskTitled resets and disables the window // HACK: Clearing NSWindowStyleMaskTitled resets and disables the window
// title property but the miniwindow title property is unaffected // title property but the miniwindow title property is unaffected
@ -1317,7 +1374,12 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
int _glfwPlatformWindowMaximized(_GLFWwindow* window) int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
if (window->resizable)
return [window->ns.object isZoomed]; return [window->ns.object isZoomed];
else
return GLFW_FALSE;
} // autoreleasepool } // autoreleasepool
} }
@ -1349,15 +1411,46 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object setStyleMask:getStyleMask(window)];
const NSUInteger styleMask = [window->ns.object styleMask];
if (enabled)
{
[window->ns.object setStyleMask:(styleMask | NSWindowStyleMaskResizable)];
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenPrimary |
NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior];
}
else
{
[window->ns.object setStyleMask:(styleMask & ~NSWindowStyleMaskResizable)];
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenNone;
[window->ns.object setCollectionBehavior:behavior];
}
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object setStyleMask:getStyleMask(window)];
NSUInteger styleMask = [window->ns.object styleMask];
if (enabled)
{
styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
styleMask &= ~NSWindowStyleMaskBorderless;
}
else
{
styleMask |= NSWindowStyleMaskBorderless;
styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
}
[window->ns.object setStyleMask:styleMask];
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
} // autoreleasepool } // autoreleasepool
} }

View File

@ -48,16 +48,6 @@
// //
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{ {
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API && if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API && ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API) ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
@ -78,6 +68,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
return GLFW_FALSE; return GLFW_FALSE;
} }
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (ctxconfig->source != ctxconfig->share->context.source)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Context creation APIs do not match between contexts");
return GLFW_FALSE;
}
}
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
@ -356,6 +363,8 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
previous = _glfwPlatformGetTls(&_glfw.contextSlot); previous = _glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window); glfwMakeContextCurrent((GLFWwindow*) window);
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
return GLFW_FALSE;
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
window->context.getProcAddress("glGetIntegerv"); window->context.getProcAddress("glGetIntegerv");
@ -609,10 +618,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* previous;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window && window->context.client == GLFW_NO_API) if (window && window->context.client == GLFW_NO_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, _glfwInputError(GLFW_NO_WINDOW_CONTEXT,

View File

@ -88,13 +88,30 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
// Return the EGLConfig most closely matching the specified hints // Return the EGLConfig most closely matching the specified hints
// //
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* desired, const _GLFWfbconfig* fbconfig,
EGLConfig* result) EGLConfig* result)
{ {
EGLConfig* nativeConfigs; EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount; int i, nativeCount, usableCount, apiBit;
GLFWbool wrongApiAvailable = GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
apiBit = EGL_OPENGL_ES_BIT;
else
apiBit = EGL_OPENGL_ES2_BIT;
}
else
apiBit = EGL_OPENGL_BIT;
if (fbconfig->stereo)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
return GLFW_FALSE;
}
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount) if (!nativeCount)
@ -131,7 +148,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (!vi.visualid) if (!vi.visualid)
continue; continue;
if (desired->transparent) if (fbconfig->transparent)
{ {
int count; int count;
XVisualInfo* vis = XVisualInfo* vis =
@ -145,22 +162,9 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
} }
#endif // _GLFW_X11 #endif // _GLFW_X11
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
{ {
if (ctxconfig->major == 1) wrongApiAvailable = GLFW_TRUE;
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
continue;
}
else
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
continue;
}
}
else if (ctxconfig->client == GLFW_OPENGL_API)
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
continue; continue;
} }
@ -172,16 +176,57 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE); u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE); u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
#if defined(_GLFW_WAYLAND)
// NOTE: The wl_surface opaque region is no guarantee that its buffer
// is presented as opaque, if it also has an alpha channel
// HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
// with an alpha channel to ensure the buffer is opaque
if (!_glfw.egl.EXT_present_opaque)
{
if (!fbconfig->transparent && u->alphaBits > 0)
continue;
}
#endif // _GLFW_WAYLAND
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = desired->doublebuffer; u->doublebuffer = fbconfig->doublebuffer;
u->handle = (uintptr_t) n; u->handle = (uintptr_t) n;
usableCount++; usableCount++;
} }
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
if (closest) if (closest)
*result = (EGLConfig) closest->handle; *result = (EGLConfig) closest->handle;
else
{
if (wrongApiAvailable)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 1.x");
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 2 or later");
}
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL");
}
}
else
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
}
}
free(nativeConfigs); free(nativeConfigs);
free(usableConfigs); free(usableConfigs);
@ -259,6 +304,7 @@ static int extensionSupportedEGL(const char* extension)
static GLFWglproc getProcAddressEGL(const char* procname) static GLFWglproc getProcAddressEGL(const char* procname)
{ {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (window->context.egl.client) if (window->context.egl.client)
{ {
@ -485,11 +531,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
share = ctxconfig->share->context.egl.handle; share = ctxconfig->share->context.egl.handle;
if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE; return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
{ {
@ -546,18 +588,18 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
} }
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
} }
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (mask) if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
@ -609,8 +651,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (!fbconfig->doublebuffer) if (!fbconfig->doublebuffer)
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
#if defined(_GLFW_WAYLAND)
if (_glfw.egl.EXT_present_opaque) if (_glfw.egl.EXT_present_opaque)
setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
#endif // _GLFW_WAYLAND
setAttrib(EGL_NONE, EGL_NONE); setAttrib(EGL_NONE, EGL_NONE);
@ -678,6 +722,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
#elif defined(__OpenBSD__) || defined(__NetBSD__) #elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so", "libGL.so",
#else #else
"libOpenGL.so.0",
"libGL.so.1", "libGL.so.1",
#endif #endif
NULL NULL
@ -740,11 +785,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const long vimask = VisualScreenMask | VisualIDMask; const long vimask = VisualScreenMask | VisualIDMask;
if (!chooseEGLConfig(ctxconfig, fbconfig, &native)) if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE; return GLFW_FALSE;
}
eglGetConfigAttrib(_glfw.egl.display, native, eglGetConfigAttrib(_glfw.egl.display, native,
EGL_NATIVE_VISUAL_ID, &visualID); EGL_NATIVE_VISUAL_ID, &visualID);

View File

@ -8,6 +8,6 @@ Description: A multi-platform library for OpenGL, window and input
Version: @GLFW_VERSION@ Version: @GLFW_VERSION@
URL: https://www.glfw.org/ URL: https://www.glfw.org/
Requires.private: @GLFW_PKG_DEPS@ Requires.private: @GLFW_PKG_DEPS@
Libs: -L${libdir} -l@GLFW_LIB_NAME@ Libs: -L${libdir} -l@GLFW_LIB_NAME@@GLFW_LIB_NAME_SUFFIX@
Libs.private: @GLFW_PKG_LIBS@ Libs.private: @GLFW_PKG_LIBS@
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -190,6 +190,7 @@ static void swapBuffersGLX(_GLFWwindow* window)
static void swapIntervalGLX(int interval) static void swapIntervalGLX(int interval)
{ {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (_glfw.glx.EXT_swap_control) if (_glfw.glx.EXT_swap_control)
{ {
@ -226,8 +227,11 @@ static GLFWglproc getProcAddressGLX(const char* procname)
else if (_glfw.glx.GetProcAddressARB) else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else else
{
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
return _glfw_dlsym(_glfw.glx.handle, procname); return _glfw_dlsym(_glfw.glx.handle, procname);
} }
}
static void destroyContextGLX(_GLFWwindow* window) static void destroyContextGLX(_GLFWwindow* window)
{ {
@ -263,6 +267,7 @@ GLFWbool _glfwInitGLX(void)
#elif defined(__OpenBSD__) || defined(__NetBSD__) #elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so", "libGL.so",
#else #else
"libGLX.so.0",
"libGL.so.1", "libGL.so.1",
"libGL.so", "libGL.so",
#endif #endif

View File

@ -127,7 +127,6 @@ typedef struct _GLFWlibraryGLX
int eventBase; int eventBase;
int errorBase; int errorBase;
// dlopen handle for libGL.so.1
void* handle; void* handle;
// GLX 1.3 functions // GLX 1.3 functions

View File

@ -54,7 +54,10 @@ static _GLFWinitconfig _glfwInitHints =
{ {
GLFW_TRUE, // macOS menu bar GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir GLFW_TRUE // macOS bundle chdir
} },
{
GLFW_WAYLAND_PREFER_LIBDECOR // Wayland libdecor mode
},
}; };
// Terminate the library // Terminate the library
@ -142,6 +145,59 @@ size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
return count; return count;
} }
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
char** _glfwParseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** paths = NULL;
char* line;
*count = 0;
while ((line = strtok(text, "\r\n")))
{
char* path;
text = NULL;
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
{
line += strlen(prefix);
// TODO: Validate hostname
while (*line != '/')
line++;
}
(*count)++;
path = calloc(strlen(line) + 1, 1);
paths = realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*path = (char) strtol(digits, NULL, 16);
line += 2;
}
else
*path = *line;
path++;
line++;
}
}
return paths;
}
char* _glfw_strdup(const char* source) char* _glfw_strdup(const char* source)
{ {
const size_t length = strlen(source); const size_t length = strlen(source);
@ -150,6 +206,16 @@ char* _glfw_strdup(const char* source)
return result; return result;
} }
int _glfw_min(int a, int b)
{
return a < b ? a : b;
}
int _glfw_max(int a, int b)
{
return a > b ? a : b;
}
float _glfw_fminf(float a, float b) float _glfw_fminf(float a, float b)
{ {
if (a != a) if (a != a)
@ -306,6 +372,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
case GLFW_COCOA_MENUBAR: case GLFW_COCOA_MENUBAR:
_glfwInitHints.ns.menubar = value; _glfwInitHints.ns.menubar = value;
return; return;
case GLFW_WAYLAND_LIBDECOR:
_glfwInitHints.wl.libdecorMode = value;
return;
} }
_glfwInputError(GLFW_INVALID_ENUM, _glfwInputError(GLFW_INVALID_ENUM,

View File

@ -360,6 +360,11 @@ void _glfwInputJoystick(_GLFWjoystick* js, int event)
{ {
const int jid = (int) (js - _glfw.joysticks); const int jid = (int) (js - _glfw.joysticks);
if (event == GLFW_CONNECTED)
js->connected = GLFW_TRUE;
else if (event == GLFW_DISCONNECTED)
js->connected = GLFW_FALSE;
if (_glfw.callbacks.joystick) if (_glfw.callbacks.joystick)
_glfw.callbacks.joystick(jid, event); _glfw.callbacks.joystick(jid, event);
} }
@ -415,7 +420,7 @@ void _glfwInitGamepadMappings(void)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
js->mapping = findValidMapping(js); js->mapping = findValidMapping(js);
} }
} }
@ -433,7 +438,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (!_glfw.joysticks[jid].present) if (!_glfw.joysticks[jid].allocated)
break; break;
} }
@ -441,7 +446,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
js->present = GLFW_TRUE; js->allocated = GLFW_TRUE;
js->axes = calloc(axisCount, sizeof(float)); js->axes = calloc(axisCount, sizeof(float));
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1); js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
js->hats = calloc(hatCount, 1); js->hats = calloc(hatCount, 1);
@ -611,6 +616,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
if (key != GLFW_KEY_UNKNOWN) if (key != GLFW_KEY_UNKNOWN)
{ {
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return NULL;
}
if (key != GLFW_KEY_KP_EQUAL && if (key != GLFW_KEY_KP_EQUAL &&
(key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) && (key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
(key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2)) (key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))
@ -631,7 +642,7 @@ GLFWAPI int glfwGetKeyScancode(int key)
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST) if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return GLFW_RELEASE; return -1;
} }
return _glfwPlatformGetKeyScancode(key); return _glfwPlatformGetKeyScancode(key);
@ -743,9 +754,16 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
_GLFWcursor* cursor; _GLFWcursor* cursor;
assert(image != NULL); assert(image != NULL);
assert(image->pixels != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (image->width <= 0 || image->height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image dimensions for cursor");
return NULL;
}
cursor = calloc(1, sizeof(_GLFWcursor)); cursor = calloc(1, sizeof(_GLFWcursor));
cursor->next = _glfw.cursorListHead; cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor; _glfw.cursorListHead = cursor;
@ -941,7 +959,7 @@ GLFWAPI int glfwJoystickPresent(int jid)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return GLFW_FALSE; return GLFW_FALSE;
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
@ -966,7 +984,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
@ -995,7 +1013,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
@ -1028,7 +1046,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
@ -1054,7 +1072,7 @@ GLFWAPI const char* glfwGetJoystickName(int jid)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
@ -1079,7 +1097,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
@ -1098,7 +1116,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->allocated)
return; return;
js->userPointer = pointer; js->userPointer = pointer;
@ -1114,7 +1132,7 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->allocated)
return NULL; return NULL;
return js->userPointer; return js->userPointer;
@ -1180,7 +1198,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
js->mapping = findValidMapping(js); js->mapping = findValidMapping(js);
} }
@ -1203,7 +1221,7 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
@ -1228,7 +1246,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
@ -1260,7 +1278,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
} }
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL)) if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
@ -1369,3 +1387,4 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void)
_GLFW_REQUIRE_INIT_OR_RETURN(0); _GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformGetTimerFrequency(); return _glfwPlatformGetTimerFrequency();
} }

View File

@ -244,6 +244,9 @@ struct _GLFWinitconfig
GLFWbool menubar; GLFWbool menubar;
GLFWbool chdir; GLFWbool chdir;
} ns; } ns;
struct {
int libdecorMode;
} wl;
}; };
// Window configuration // Window configuration
@ -478,7 +481,8 @@ struct _GLFWmapping
// //
struct _GLFWjoystick struct _GLFWjoystick
{ {
GLFWbool present; GLFWbool allocated;
GLFWbool connected;
float* axes; float* axes;
int axisCount; int axisCount;
unsigned char* buttons; unsigned char* buttons;
@ -775,8 +779,11 @@ void _glfwTerminateVulkan(void);
const char* _glfwGetVulkanResultString(VkResult result); const char* _glfwGetVulkanResultString(VkResult result);
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint); size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
char** _glfwParseUriList(char* text, int* count);
char* _glfw_strdup(const char* source); char* _glfw_strdup(const char* source);
int _glfw_min(int a, int b);
int _glfw_max(int a, int b);
float _glfw_fminf(float a, float b); float _glfw_fminf(float a, float b);
float _glfw_fmaxf(float a, float b); float _glfw_fmaxf(float a, float b);

View File

@ -128,7 +128,7 @@ static GLFWbool openJoystickDevice(const char* path)
{ {
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (!_glfw.joysticks[jid].present) if (!_glfw.joysticks[jid].connected)
continue; continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE; return GLFW_FALSE;
@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path)
} }
// Ensure this device supports the events expected of a joystick // Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits)) if (!isBitSet(EV_ABS, evBits))
{ {
close(linjs.fd); close(linjs.fd);
return GLFW_FALSE; return GLFW_FALSE;
@ -245,9 +245,9 @@ static GLFWbool openJoystickDevice(const char* path)
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
_glfwInputJoystick(js, GLFW_DISCONNECTED);
close(js->linjs.fd); close(js->linjs.fd);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// Lexically compare joysticks by name; used by qsort // Lexically compare joysticks by name; used by qsort
@ -283,7 +283,8 @@ GLFWbool _glfwInitJoysticksLinux(void)
// Continue without device connection notifications if inotify fails // Continue without device connection notifications if inotify fails
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0) _glfw.linjs.regexCompiled = (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) == 0);
if (!_glfw.linjs.regexCompiled)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
return GLFW_FALSE; return GLFW_FALSE;
@ -329,7 +330,7 @@ void _glfwTerminateJoysticksLinux(void)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
closeJoystick(js); closeJoystick(js);
} }
@ -342,6 +343,9 @@ void _glfwTerminateJoysticksLinux(void)
close(_glfw.linjs.inotify); close(_glfw.linjs.inotify);
} }
if (_glfw.linjs.regexCompiled)
regfree(&_glfw.linjs.regex);
} }
void _glfwDetectJoystickConnectionLinux(void) void _glfwDetectJoystickConnectionLinux(void)
@ -424,7 +428,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
handleAbsEvent(js, e.code, e.value); handleAbsEvent(js, e.code, e.value);
} }
return js->present; return js->connected;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) void _glfwPlatformUpdateGamepadGUID(char* guid)

View File

@ -53,6 +53,7 @@ typedef struct _GLFWlibraryLinux
int inotify; int inotify;
int watch; int watch;
regex_t regex; regex_t regex;
GLFWbool regexCompiled;
GLFWbool dropped; GLFWbool dropped;
} _GLFWlibraryLinux; } _GLFWlibraryLinux;

View File

@ -521,6 +521,8 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
assert(ramp->green != NULL); assert(ramp->green != NULL);
assert(ramp->blue != NULL); assert(ramp->blue != NULL);
_GLFW_REQUIRE_INIT();
if (ramp->size <= 0) if (ramp->size <= 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,
@ -529,8 +531,6 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
return; return;
} }
_GLFW_REQUIRE_INIT();
if (!monitor->originalRamp.size) if (!monitor->originalRamp.size)
{ {
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))

View File

@ -81,11 +81,10 @@ static void swapIntervalNSGL(int interval)
@autoreleasepool { @autoreleasepool {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window) assert(window != NULL);
{
[window->context.nsgl.object setValues:&interval [window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval]; forParameter:NSOpenGLContextParameterSwapInterval];
}
} // autoreleasepool } // autoreleasepool
} }

View File

@ -67,6 +67,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available"); _glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
} }
return GLFW_TRUE; return GLFW_TRUE;

View File

@ -73,18 +73,13 @@ static int choosePixelFormat(_GLFWwindow* window,
int attribs[40]; int attribs[40];
int values[sizeof(attribs) / sizeof(attribs[0])]; int values[sizeof(attribs) / sizeof(attribs[0])];
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
1, 0, 1, &attrib, &nativeCount))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
addAttrib(WGL_SUPPORT_OPENGL_ARB); addAttrib(WGL_SUPPORT_OPENGL_ARB);
addAttrib(WGL_DRAW_TO_WINDOW_ARB); addAttrib(WGL_DRAW_TO_WINDOW_ARB);
addAttrib(WGL_PIXEL_TYPE_ARB); addAttrib(WGL_PIXEL_TYPE_ARB);
@ -122,13 +117,6 @@ static int choosePixelFormat(_GLFWwindow* window,
addAttrib(WGL_COLORSPACE_EXT); addAttrib(WGL_COLORSPACE_EXT);
} }
} }
else
{
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
@ -345,6 +333,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
static void swapIntervalWGL(int interval) static void swapIntervalWGL(int interval)
{ {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
window->context.wgl.interval = interval; window->context.wgl.interval = interval;

View File

@ -72,6 +72,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
// //
static GLFWbool loadLibraries(void) static GLFWbool loadLibraries(void)
{ {
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(const WCHAR*) &_glfw,
(HMODULE*) &_glfw.win32.instance))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve own module handle");
return GLFW_FALSE;
}
_glfw.win32.user32.instance = LoadLibraryA("user32.dll"); _glfw.win32.user32.instance = LoadLibraryA("user32.dll");
if (!_glfw.win32.user32.instance) if (!_glfw.win32.user32.instance)
{ {
@ -254,7 +264,6 @@ static void createKeyTables(void)
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN; _glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP; _glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE; _glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE; _glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB; _glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK; _glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
@ -336,7 +345,7 @@ static GLFWbool createHelperWindow(void)
WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1, 0, 0, 1, 1,
NULL, NULL, NULL, NULL,
GetModuleHandleW(NULL), _glfw.win32.instance,
NULL); NULL);
if (!_glfw.win32.helperWindowHandle) if (!_glfw.win32.helperWindowHandle)
@ -494,6 +503,8 @@ void _glfwUpdateKeyNamesWin32(void)
if (length == -1) if (length == -1)
{ {
// This is a dead key, so we need a second simulated key press
// to make it output its own character (usually a diacritic)
length = ToUnicode(vk, scancode, state, length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR), chars, sizeof(chars) / sizeof(WCHAR),
0); 0);
@ -601,6 +612,7 @@ void _glfwPlatformTerminate(void)
_glfwTerminateWGL(); _glfwTerminateWGL();
_glfwTerminateEGL(); _glfwTerminateEGL();
_glfwTerminateOSMesa();
_glfwTerminateJoysticksWin32(); _glfwTerminateJoysticksWin32();

View File

@ -256,6 +256,8 @@ static GLFWbool supportsXInput(const GUID* guid)
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
_glfwInputJoystick(js, GLFW_DISCONNECTED);
if (js->win32.device) if (js->win32.device)
{ {
IDirectInputDevice8_Unacquire(js->win32.device); IDirectInputDevice8_Unacquire(js->win32.device);
@ -263,9 +265,7 @@ static void closeJoystick(_GLFWjoystick* js)
} }
free(js->win32.objects); free(js->win32.objects);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// DirectInput device object enumeration callback // DirectInput device object enumeration callback
@ -357,7 +357,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
{ {
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0) if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
@ -497,7 +497,7 @@ void _glfwInitJoysticksWin32(void)
{ {
if (_glfw.win32.dinput8.instance) if (_glfw.win32.dinput8.instance)
{ {
if (FAILED(DirectInput8Create(GetModuleHandleW(NULL), if (FAILED(DirectInput8Create(_glfw.win32.instance,
DIRECTINPUT_VERSION, DIRECTINPUT_VERSION,
&IID_IDirectInput8W, &IID_IDirectInput8W,
(void**) &_glfw.win32.dinput8.api, (void**) &_glfw.win32.dinput8.api,
@ -541,7 +541,7 @@ void _glfwDetectJoystickConnectionWin32(void)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (_glfw.joysticks[jid].present && if (_glfw.joysticks[jid].connected &&
_glfw.joysticks[jid].win32.device == NULL && _glfw.joysticks[jid].win32.device == NULL &&
_glfw.joysticks[jid].win32.index == index) _glfw.joysticks[jid].win32.index == index)
{ {
@ -593,7 +593,7 @@ void _glfwDetectJoystickDisconnectionWin32(void)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
} }
} }
@ -609,7 +609,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{ {
int i, ai = 0, bi = 0, pi = 0; int i, ai = 0, bi = 0, pi = 0;
HRESULT result; HRESULT result;
DIJOYSTATE state; DIJOYSTATE state = {0};
IDirectInputDevice8_Poll(js->win32.device); IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device, result = IDirectInputDevice8_GetDeviceState(js->win32.device,
@ -736,6 +736,13 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
dpad |= GLFW_HAT_LEFT; dpad |= GLFW_HAT_LEFT;
// Treat invalid combinations as neither being pressed
// while preserving what data can be preserved
if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT))
dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT);
if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN))
dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN);
_glfwInputJoystickHat(js, 0, dpad); _glfwInputJoystickHat(js, 0, dpad);
} }

View File

@ -334,6 +334,7 @@ typedef struct _GLFWwindowWin32
// //
typedef struct _GLFWlibraryWin32 typedef struct _GLFWlibraryWin32
{ {
HINSTANCE instance;
HWND helperWindowHandle; HWND helperWindowHandle;
HDEVNOTIFY deviceNotificationHandle; HDEVNOTIFY deviceNotificationHandle;
DWORD foregroundLockTimeout; DWORD foregroundLockTimeout;
@ -346,6 +347,8 @@ typedef struct _GLFWlibraryWin32
double restoreCursorPosX, restoreCursorPosY; double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active // The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow; _GLFWwindow* disabledCursorWindow;
// The window the cursor is captured in
_GLFWwindow* capturedCursorWindow;
RAWINPUT* rawInput; RAWINPUT* rawInput;
int rawInputSize; int rawInputSize;
UINT mouseTrailSize; UINT mouseTrailSize;

View File

@ -186,53 +186,38 @@ static HICON createIcon(const GLFWimage* image,
return handle; return handle;
} }
// Translate content area size to full window size according to styles and DPI
//
static void getFullWindowSize(DWORD style, DWORD exStyle,
int contentWidth, int contentHeight,
int* fullWidth, int* fullHeight,
UINT dpi)
{
RECT rect = { 0, 0, contentWidth, contentHeight };
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
else
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
*fullWidth = rect.right - rect.left;
*fullHeight = rect.bottom - rect.top;
}
// Enforce the content area aspect ratio based on which edge is being dragged // Enforce the content area aspect ratio based on which edge is being dragged
// //
static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
{ {
int xoff, yoff; RECT frame = {0};
UINT dpi = USER_DEFAULT_SCREEN_DPI;
const float ratio = (float) window->numer / (float) window->denom; const float ratio = (float) window->numer / (float) window->denom;
const DWORD style = getWindowStyle(window);
const DWORD exStyle = getWindowExStyle(window);
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
dpi = GetDpiForWindow(window->win32.handle); {
AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), GetDpiForWindow(window->win32.handle));
0, 0, &xoff, &yoff, dpi); }
else
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
{ {
area->bottom = area->top + yoff + area->bottom = area->top + (frame.bottom - frame.top) +
(int) ((area->right - area->left - xoff) / ratio); (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio);
} }
else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT) else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)
{ {
area->top = area->bottom - yoff - area->top = area->bottom - (frame.bottom - frame.top) -
(int) ((area->right - area->left - xoff) / ratio); (int) (((area->right - area->left) - (frame.right - frame.left)) / ratio);
} }
else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM) else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM)
{ {
area->right = area->left + xoff + area->right = area->left + (frame.right - frame.left) +
(int) ((area->bottom - area->top - yoff) * ratio); (int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio);
} }
} }
@ -251,20 +236,24 @@ static void updateCursorImage(_GLFWwindow* window)
SetCursor(NULL); SetCursor(NULL);
} }
// Updates the cursor clip rect // Sets the cursor clip rect to the window content area
// //
static void updateClipRect(_GLFWwindow* window) static void captureCursor(_GLFWwindow* window)
{
if (window)
{ {
RECT clipRect; RECT clipRect;
GetClientRect(window->win32.handle, &clipRect); GetClientRect(window->win32.handle, &clipRect);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left); ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
ClipCursor(&clipRect); ClipCursor(&clipRect);
_glfw.win32.capturedCursorWindow = window;
} }
else
// Disabled clip cursor
//
static void releaseCursor(void)
{
ClipCursor(NULL); ClipCursor(NULL);
_glfw.win32.capturedCursorWindow = NULL;
} }
// Enables WM_INPUT messages for the mouse for the specified window // Enables WM_INPUT messages for the mouse for the specified window
@ -303,7 +292,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.win32.restoreCursorPosY); &_glfw.win32.restoreCursorPosY);
updateCursorImage(window); updateCursorImage(window);
_glfwCenterCursorInContentArea(window); _glfwCenterCursorInContentArea(window);
updateClipRect(window); captureCursor(window);
if (window->rawMouseMotion) if (window->rawMouseMotion)
enableRawMouseMotion(window); enableRawMouseMotion(window);
@ -317,7 +306,7 @@ static void enableCursor(_GLFWwindow* window)
disableRawMouseMotion(window); disableRawMouseMotion(window);
_glfw.win32.disabledCursorWindow = NULL; _glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL); releaseCursor();
_glfwPlatformSetCursorPos(window, _glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX, _glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY); _glfw.win32.restoreCursorPosY);
@ -504,10 +493,8 @@ static void maximizeWindowManually(_GLFWwindow* window)
if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE) if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE)
{ {
if (rect.right - rect.left > window->maxwidth) rect.right = _glfw_min(rect.right, rect.left + window->maxwidth);
rect.right = rect.left + window->maxwidth; rect.bottom = _glfw_min(rect.bottom, rect.top + window->maxheight);
if (rect.bottom - rect.top > window->maxheight)
rect.bottom = rect.top + window->maxheight;
} }
style = GetWindowLongW(window->win32.handle, GWL_STYLE); style = GetWindowLongW(window->win32.handle, GWL_STYLE);
@ -530,8 +517,7 @@ static void maximizeWindowManually(_GLFWwindow* window)
OffsetRect(&rect, 0, GetSystemMetrics(SM_CYCAPTION)); OffsetRect(&rect, 0, GetSystemMetrics(SM_CYCAPTION));
} }
if (rect.bottom > mi.rcWork.bottom) rect.bottom = _glfw_min(rect.bottom, mi.rcWork.bottom);
rect.bottom = mi.rcWork.bottom;
} }
SetWindowPos(window->win32.handle, HWND_TOP, SetWindowPos(window->win32.handle, HWND_TOP,
@ -751,6 +737,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC); scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
} }
// HACK: Alt+PrtSc has a different scancode than just PrtSc
if (scancode == 0x54)
scancode = 0x137;
// HACK: Ctrl+Pause has a different scancode than just Pause
if (scancode == 0x146)
scancode = 0x45;
// HACK: CJK IME sets the extended bit for right Shift
if (scancode == 0x136)
scancode = 0x36;
key = _glfw.win32.keycodes[scancode]; key = _glfw.win32.keycodes[scancode];
// The Ctrl keys require special handling // The Ctrl keys require special handling
@ -1024,8 +1022,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
(window->win32.maximized && (window->win32.maximized &&
wParam != SIZE_RESTORED); wParam != SIZE_RESTORED);
if (_glfw.win32.disabledCursorWindow == window) if (_glfw.win32.capturedCursorWindow == window)
updateClipRect(window); captureCursor(window);
if (window->win32.iconified != iconified) if (window->win32.iconified != iconified)
_glfwInputWindowIconify(window, iconified); _glfwInputWindowIconify(window, iconified);
@ -1060,8 +1058,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOVE: case WM_MOVE:
{ {
if (_glfw.win32.disabledCursorWindow == window) if (_glfw.win32.capturedCursorWindow == window)
updateClipRect(window); captureCursor(window);
// NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
// those macros do not handle negative window positions correctly // those macros do not handle negative window positions correctly
@ -1085,31 +1083,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_GETMINMAXINFO: case WM_GETMINMAXINFO:
{ {
int xoff, yoff; RECT frame = {0};
UINT dpi = USER_DEFAULT_SCREEN_DPI;
MINMAXINFO* mmi = (MINMAXINFO*) lParam; MINMAXINFO* mmi = (MINMAXINFO*) lParam;
const DWORD style = getWindowStyle(window);
const DWORD exStyle = getWindowExStyle(window);
if (window->monitor) if (window->monitor)
break; break;
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
dpi = GetDpiForWindow(window->win32.handle); {
AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), GetDpiForWindow(window->win32.handle));
0, 0, &xoff, &yoff, dpi); }
else
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
if (window->minwidth != GLFW_DONT_CARE && if (window->minwidth != GLFW_DONT_CARE &&
window->minheight != GLFW_DONT_CARE) window->minheight != GLFW_DONT_CARE)
{ {
mmi->ptMinTrackSize.x = window->minwidth + xoff; mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left;
mmi->ptMinTrackSize.y = window->minheight + yoff; mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top;
} }
if (window->maxwidth != GLFW_DONT_CARE && if (window->maxwidth != GLFW_DONT_CARE &&
window->maxheight != GLFW_DONT_CARE) window->maxheight != GLFW_DONT_CARE)
{ {
mmi->ptMaxTrackSize.x = window->maxwidth + xoff; mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left;
mmi->ptMaxTrackSize.y = window->maxheight + yoff; mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top;
} }
if (!window->decorated) if (!window->decorated)
@ -1268,36 +1269,38 @@ static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig, const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
int xpos, ypos, fullWidth, fullHeight; int frameX, frameY, frameWidth, frameHeight;
WCHAR* wideTitle; WCHAR* wideTitle;
DWORD style = getWindowStyle(window); DWORD style = getWindowStyle(window);
DWORD exStyle = getWindowExStyle(window); DWORD exStyle = getWindowExStyle(window);
if (window->monitor) if (window->monitor)
{ {
GLFWvidmode mode; MONITORINFO mi = { sizeof(mi) };
GetMonitorInfoW(window->monitor->win32.handle, &mi);
// NOTE: This window placement is temporary and approximate, as the // NOTE: This window placement is temporary and approximate, as the
// correct position and size cannot be known until the monitor // correct position and size cannot be known until the monitor
// video mode has been picked in _glfwSetVideoModeWin32 // video mode has been picked in _glfwSetVideoModeWin32
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); frameX = mi.rcMonitor.left;
_glfwPlatformGetVideoMode(window->monitor, &mode); frameY = mi.rcMonitor.top;
fullWidth = mode.width; frameWidth = mi.rcMonitor.right - mi.rcMonitor.left;
fullHeight = mode.height; frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;
} }
else else
{ {
xpos = CW_USEDEFAULT; RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
ypos = CW_USEDEFAULT;
window->win32.maximized = wndconfig->maximized; window->win32.maximized = wndconfig->maximized;
if (wndconfig->maximized) if (wndconfig->maximized)
style |= WS_MAXIMIZE; style |= WS_MAXIMIZE;
getFullWindowSize(style, exStyle, AdjustWindowRectEx(&rect, style, FALSE, exStyle);
wndconfig->width, wndconfig->height,
&fullWidth, &fullHeight, frameX = CW_USEDEFAULT;
USER_DEFAULT_SCREEN_DPI); frameY = CW_USEDEFAULT;
frameWidth = rect.right - rect.left;
frameHeight = rect.bottom - rect.top;
} }
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title); wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
@ -1308,11 +1311,11 @@ static int createNativeWindow(_GLFWwindow* window,
_GLFW_WNDCLASSNAME, _GLFW_WNDCLASSNAME,
wideTitle, wideTitle,
style, style,
xpos, ypos, frameX, frameY,
fullWidth, fullHeight, frameWidth, frameHeight,
NULL, // No parent window NULL, // No parent window
NULL, // No window menu NULL, // No window menu
GetModuleHandleW(NULL), _glfw.win32.instance,
(LPVOID) wndconfig); (LPVOID) wndconfig);
free(wideTitle); free(wideTitle);
@ -1423,8 +1426,8 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
ZeroMemory(&wc, sizeof(wc)); ZeroMemory(&wc, sizeof(wc));
wc.cbSize = sizeof(wc); wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) windowProc; wc.lpfnWndProc = windowProc;
wc.hInstance = GetModuleHandleW(NULL); wc.hInstance = _glfw.win32.instance;
wc.hCursor = LoadCursorW(NULL, IDC_ARROW); wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.lpszClassName = _GLFW_WNDCLASSNAME; wc.lpszClassName = _GLFW_WNDCLASSNAME;
@ -1454,7 +1457,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
// //
void _glfwUnregisterWindowClassWin32(void) void _glfwUnregisterWindowClassWin32(void)
{ {
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL)); UnregisterClassW(_GLFW_WNDCLASSNAME, _glfw.win32.instance);
} }
@ -1493,6 +1496,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
} }
if (window->monitor) if (window->monitor)
@ -1501,6 +1507,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
acquireMonitor(window); acquireMonitor(window);
fitToMonitor(window); fitToMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwPlatformShowWindow(window);
if (wndconfig->focused)
_glfwPlatformFocusWindow(window);
}
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1515,7 +1533,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->context.destroy(window); window->context.destroy(window);
if (_glfw.win32.disabledCursorWindow == window) if (_glfw.win32.disabledCursorWindow == window)
_glfw.win32.disabledCursorWindow = NULL; enableCursor(window);
if (_glfw.win32.capturedCursorWindow == window)
releaseCursor();
if (window->win32.handle) if (window->win32.handle)
{ {
@ -2092,7 +2113,7 @@ void _glfwPlatformWaitEvents(void)
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS); MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLINPUT);
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} }
@ -2130,15 +2151,41 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
} }
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (_glfwPlatformWindowFocused(window))
{ {
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{ {
if (_glfwPlatformWindowFocused(window)) _glfwPlatformGetCursorPos(window,
disableCursor(window); &_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
} }
else if (_glfw.win32.disabledCursorWindow == window) else if (_glfw.win32.disabledCursorWindow == window)
enableCursor(window); {
else if (cursorInContentArea(window)) if (window->rawMouseMotion)
disableRawMouseMotion(window);
}
if (mode == GLFW_CURSOR_DISABLED)
captureCursor(window);
else
releaseCursor();
if (mode == GLFW_CURSOR_DISABLED)
_glfw.win32.disabledCursorWindow = window;
else if (_glfw.win32.disabledCursorWindow == window)
{
_glfw.win32.disabledCursorWindow = NULL;
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
}
}
if (cursorInContentArea(window))
updateCursorImage(window); updateCursorImage(window);
} }
@ -2354,7 +2401,7 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
memset(&sci, 0, sizeof(sci)); memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
sci.hinstance = GetModuleHandleW(NULL); sci.hinstance = _glfw.win32.instance;
sci.hwnd = window->win32.handle; sci.hwnd = window->win32.handle;
err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface); err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);

View File

@ -221,30 +221,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
return NULL; return NULL;
} }
if (ctxconfig.client != GLFW_NO_API)
{
if (!_glfwRefreshContextAttribs(window, &ctxconfig))
{
glfwDestroyWindow((GLFWwindow*) window);
return NULL;
}
}
if (window->monitor)
{
if (wndconfig.centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig.visible)
{
_glfwPlatformShowWindow(window);
if (wndconfig.focused)
_glfwPlatformFocusWindow(window);
}
}
return (GLFWwindow*) window; return (GLFWwindow*) window;
} }
@ -504,12 +480,33 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
int count, const GLFWimage* images) int count, const GLFWimage* images)
{ {
int i;
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
assert(count >= 0); assert(count >= 0);
assert(count == 0 || images != NULL); assert(count == 0 || images != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (count < 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon");
return;
}
for (i = 0; i < count; i++)
{
assert(images[i].pixels != NULL);
if (images[i].width <= 0 || images[i].height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid image dimensions for window icon");
return;
}
}
_glfwPlatformSetWindowIcon(window, count, images); _glfwPlatformSetWindowIcon(window, count, images);
} }

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@
#include <math.h> #include <math.h>
static void outputHandleGeometry(void* data, static void outputHandleGeometry(void* userData,
struct wl_output* output, struct wl_output* output,
int32_t x, int32_t x,
int32_t y, int32_t y,
@ -46,24 +46,25 @@ static void outputHandleGeometry(void* data,
const char* model, const char* model,
int32_t transform) int32_t transform)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
monitor->wl.x = x; monitor->wl.x = x;
monitor->wl.y = y; monitor->wl.y = y;
monitor->widthMM = physicalWidth; monitor->widthMM = physicalWidth;
monitor->heightMM = physicalHeight; monitor->heightMM = physicalHeight;
if (strlen(monitor->name) == 0)
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model); snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
} }
static void outputHandleMode(void* data, static void outputHandleMode(void* userData,
struct wl_output* output, struct wl_output* output,
uint32_t flags, uint32_t flags,
int32_t width, int32_t width,
int32_t height, int32_t height,
int32_t refresh) int32_t refresh)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
GLFWvidmode mode; GLFWvidmode mode;
mode.width = width; mode.width = width;
@ -82,9 +83,9 @@ static void outputHandleMode(void* data,
monitor->wl.currentMode = monitor->modeCount - 1; monitor->wl.currentMode = monitor->modeCount - 1;
} }
static void outputHandleDone(void* data, struct wl_output* output) static void outputHandleDone(void* userData, struct wl_output* output)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
if (monitor->widthMM <= 0 || monitor->heightMM <= 0) if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{ {
@ -94,23 +95,64 @@ static void outputHandleDone(void* data, struct wl_output* output)
monitor->heightMM = (int) (mode->height * 25.4f / 96.f); monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
} }
for (int i = 0; i < _glfw.monitorCount; i++)
{
if (_glfw.monitors[i] == monitor)
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
} }
static void outputHandleScale(void* data, static void outputHandleScale(void* userData,
struct wl_output* output, struct wl_output* output,
int32_t factor) int32_t factor)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
monitor->wl.scale = factor; monitor->wl.contentScale = factor;
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
{
for (int i = 0; i < window->wl.scaleCount; i++)
{
if (window->wl.scales[i].output == monitor->wl.output)
{
window->wl.scales[i].factor = monitor->wl.contentScale;
_glfwUpdateContentScaleWayland(window);
break;
}
}
}
} }
static const struct wl_output_listener outputListener = { #ifdef WL_OUTPUT_NAME_SINCE_VERSION
void outputHandleName(void* userData, struct wl_output* wl_output, const char* name)
{
struct _GLFWmonitor* monitor = userData;
strncpy(monitor->name, name, sizeof(monitor->name) - 1);
}
void outputHandleDescription(void* userData,
struct wl_output* wl_output,
const char* description)
{
}
#endif // WL_OUTPUT_NAME_SINCE_VERSION
static const struct wl_output_listener outputListener =
{
outputHandleGeometry, outputHandleGeometry,
outputHandleMode, outputHandleMode,
outputHandleDone, outputHandleDone,
outputHandleScale, outputHandleScale,
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
outputHandleName,
outputHandleDescription,
#endif
}; };
@ -120,9 +162,6 @@ static const struct wl_output_listener outputListener = {
void _glfwAddOutputWayland(uint32_t name, uint32_t version) void _glfwAddOutputWayland(uint32_t name, uint32_t version)
{ {
_GLFWmonitor *monitor;
struct wl_output *output;
if (version < 2) if (version < 2)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -130,23 +169,26 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
return; return;
} }
// The actual name of this output will be set in the geometry handler. #ifdef WL_OUTPUT_NAME_SINCE_VERSION
monitor = _glfwAllocMonitor("", 0, 0); version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
#else
version = 2;
#endif
output = wl_registry_bind(_glfw.wl.registry, struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
name, name,
&wl_output_interface, &wl_output_interface,
2); version);
if (!output) if (!output)
{
_glfwFreeMonitor(monitor);
return; return;
}
monitor->wl.scale = 1; // The actual name of this output will be set in the geometry handler
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
monitor->wl.contentScale = 1;
monitor->wl.output = output; monitor->wl.output = output;
monitor->wl.name = name; monitor->wl.name = name;
wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag);
wl_output_add_listener(output, &outputListener, monitor); wl_output_add_listener(output, &outputListener, monitor);
} }
@ -173,9 +215,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = (float) monitor->wl.scale; *xscale = (float) monitor->wl.contentScale;
if (yscale) if (yscale)
*yscale = (float) monitor->wl.scale; *yscale = (float) monitor->wl.contentScale;
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,

View File

@ -29,6 +29,8 @@
#include <xkbcommon/xkbcommon-compose.h> #include <xkbcommon/xkbcommon-compose.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <stdbool.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR typedef struct VkWaylandSurfaceCreateInfoKHR
@ -65,7 +67,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
#define _glfw_dlclose(handle) dlclose(handle) #define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name) #define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native) #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.egl.window)
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display) #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl
@ -115,8 +117,8 @@ typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
typedef void (* PFN_xkb_state_unref)(struct xkb_state*); typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**); typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component);
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t); typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
#define xkb_context_new _glfw.wl.xkb.context_new #define xkb_context_new _glfw.wl.xkb.context_new
#define xkb_context_unref _glfw.wl.xkb.context_unref #define xkb_context_unref _glfw.wl.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string #define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
@ -128,8 +130,8 @@ typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xk
#define xkb_state_unref _glfw.wl.xkb.state_unref #define xkb_state_unref _glfw.wl.xkb.state_unref
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms #define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask #define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
#define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout #define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*); typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
@ -146,18 +148,129 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status #define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym #define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
#define _GLFW_DECORATION_WIDTH 4 struct libdecor;
#define _GLFW_DECORATION_TOP 24 struct libdecor_frame;
#define _GLFW_DECORATION_VERTICAL (_GLFW_DECORATION_TOP + _GLFW_DECORATION_WIDTH) struct libdecor_state;
#define _GLFW_DECORATION_HORIZONTAL (2 * _GLFW_DECORATION_WIDTH) struct libdecor_configuration;
enum libdecor_error
{
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
};
enum libdecor_window_state
{
LIBDECOR_WINDOW_STATE_NONE = 0,
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
};
enum libdecor_capabilities
{
LIBDECOR_ACTION_MOVE = 1,
LIBDECOR_ACTION_RESIZE = 2,
LIBDECOR_ACTION_MINIMIZE = 4,
LIBDECOR_ACTION_FULLSCREEN = 8,
LIBDECOR_ACTION_CLOSE = 16
};
struct libdecor_interface
{
void (* error)(struct libdecor*,enum libdecor_error,const char*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
struct libdecor_frame_interface
{
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
void (* close)(struct libdecor_frame*,void*);
void (* commit)(struct libdecor_frame*,void*);
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
typedef void (* PFN_libdecor_unref)(struct libdecor*);
typedef int (* PFN_libdecor_get_fd)(struct libdecor*);
typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int);
typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*);
typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*);
typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*);
typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*);
typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*);
typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int);
typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int);
typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);
typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);
typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);
typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);
typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int);
typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
#define libdecor_new _glfw.wl.libdecor.libdecor_new_
#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_
#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_
#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_
#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_
#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_
#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_
#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_
#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_
#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_
#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_
#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_
#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_
#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_
#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_
#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_
#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_
#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_
#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_
#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_
#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_
#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_
#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_
#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_
#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_
typedef enum _GLFWdecorationSideWayland typedef enum _GLFWdecorationSideWayland
{ {
mainWindow, GLFW_MAIN_WINDOW,
topDecoration, GLFW_TOP_DECORATION,
leftDecoration, GLFW_LEFT_DECORATION,
rightDecoration, GLFW_RIGHT_DECORATION,
bottomDecoration, GLFW_BOTTOM_DECORATION
} _GLFWdecorationSideWayland; } _GLFWdecorationSideWayland;
typedef struct _GLFWdecorationWayland typedef struct _GLFWdecorationWayland
@ -167,6 +280,19 @@ typedef struct _GLFWdecorationWayland
struct wp_viewport* viewport; struct wp_viewport* viewport;
} _GLFWdecorationWayland; } _GLFWdecorationWayland;
typedef struct _GLFWofferWayland
{
struct wl_data_offer* offer;
GLFWbool text_plain_utf8;
GLFWbool text_uri_list;
} _GLFWofferWayland;
typedef struct _GLFWscaleWayland
{
struct wl_output* output;
int factor;
} _GLFWscaleWayland;
// Wayland-specific per-window data // Wayland-specific per-window data
// //
typedef struct _GLFWwindowWayland typedef struct _GLFWwindowWayland
@ -174,19 +300,37 @@ typedef struct _GLFWwindowWayland
int width, height; int width, height;
GLFWbool visible; GLFWbool visible;
GLFWbool maximized; GLFWbool maximized;
GLFWbool activated;
GLFWbool fullscreen;
GLFWbool hovered; GLFWbool hovered;
GLFWbool transparent; GLFWbool transparent;
struct wl_surface* surface; struct wl_surface* surface;
struct wl_egl_window* native;
struct wl_shell_surface* shellSurface;
struct wl_callback* callback; struct wl_callback* callback;
struct {
struct wl_egl_window* window;
} egl;
struct {
int width, height;
GLFWbool maximized;
GLFWbool iconified;
GLFWbool activated;
GLFWbool fullscreen;
} pending;
struct { struct {
struct xdg_surface* surface; struct xdg_surface* surface;
struct xdg_toplevel* toplevel; struct xdg_toplevel* toplevel;
struct zxdg_toplevel_decoration_v1* decoration; struct zxdg_toplevel_decoration_v1* decoration;
uint32_t decorationMode;
} xdg; } xdg;
struct {
struct libdecor_frame* frame;
int mode;
} libdecor;
_GLFWcursor* currentCursor; _GLFWcursor* currentCursor;
double cursorPosX, cursorPosY; double cursorPosX, cursorPosY;
@ -194,25 +338,20 @@ typedef struct _GLFWwindowWayland
// We need to track the monitors the window spans on to calculate the // We need to track the monitors the window spans on to calculate the
// optimal scaling factor. // optimal scaling factor.
int scale; int contentScale;
_GLFWmonitor** monitors; _GLFWscaleWayland* scales;
int monitorsCount; int scaleCount;
int monitorsSize; int scaleSize;
struct {
struct zwp_relative_pointer_v1* relativePointer; struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer; struct zwp_locked_pointer_v1* lockedPointer;
} pointerLock;
struct zwp_idle_inhibitor_v1* idleInhibitor; struct zwp_idle_inhibitor_v1* idleInhibitor;
GLFWbool wasFullscreen;
struct { struct {
GLFWbool serverSide;
struct wl_buffer* buffer; struct wl_buffer* buffer;
_GLFWdecorationWayland top, left, right, bottom; _GLFWdecorationWayland top, left, right, bottom;
int focus; _GLFWdecorationSideWayland focus;
} decorations; } decorations;
} _GLFWwindowWayland; } _GLFWwindowWayland;
@ -224,15 +363,12 @@ typedef struct _GLFWlibraryWayland
struct wl_registry* registry; struct wl_registry* registry;
struct wl_compositor* compositor; struct wl_compositor* compositor;
struct wl_subcompositor* subcompositor; struct wl_subcompositor* subcompositor;
struct wl_shell* shell;
struct wl_shm* shm; struct wl_shm* shm;
struct wl_seat* seat; struct wl_seat* seat;
struct wl_pointer* pointer; struct wl_pointer* pointer;
struct wl_keyboard* keyboard; struct wl_keyboard* keyboard;
struct wl_data_device_manager* dataDeviceManager; struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice; struct wl_data_device* dataDevice;
struct wl_data_offer* dataOffer;
struct wl_data_source* dataSource;
struct xdg_wm_base* wmBase; struct xdg_wm_base* wmBase;
struct zxdg_decoration_manager_v1* decorationManager; struct zxdg_decoration_manager_v1* decorationManager;
struct wp_viewporter* viewporter; struct wp_viewporter* viewporter;
@ -240,8 +376,17 @@ typedef struct _GLFWlibraryWayland
struct zwp_pointer_constraints_v1* pointerConstraints; struct zwp_pointer_constraints_v1* pointerConstraints;
struct zwp_idle_inhibit_manager_v1* idleInhibitManager; struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
int compositorVersion; _GLFWofferWayland* offers;
int seatVersion; unsigned int offerCount;
struct wl_data_offer* selectionOffer;
struct wl_data_source* selectionSource;
struct wl_data_offer* dragOffer;
_GLFWwindow* dragFocus;
uint32_t dragSerial;
const char* tag;
struct wl_cursor_theme* cursorTheme; struct wl_cursor_theme* cursorTheme;
struct wl_cursor_theme* cursorThemeHiDPI; struct wl_cursor_theme* cursorThemeHiDPI;
@ -251,15 +396,12 @@ typedef struct _GLFWlibraryWayland
uint32_t serial; uint32_t serial;
uint32_t pointerEnterSerial; uint32_t pointerEnterSerial;
int32_t keyboardRepeatRate; int keyRepeatTimerfd;
int32_t keyboardRepeatDelay; int32_t keyRepeatRate;
int keyboardLastKey; int32_t keyRepeatDelay;
int keyboardLastScancode; int keyRepeatScancode;
char* clipboardString; char* clipboardString;
size_t clipboardSize;
char* clipboardSendString;
size_t clipboardSendSize;
int timerfd;
short int keycodes[256]; short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1]; short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5]; char keynames[GLFW_KEY_LAST + 1][5];
@ -271,12 +413,12 @@ typedef struct _GLFWlibraryWayland
struct xkb_state* state; struct xkb_state* state;
struct xkb_compose_state* composeState; struct xkb_compose_state* composeState;
xkb_mod_mask_t controlMask; xkb_mod_index_t controlIndex;
xkb_mod_mask_t altMask; xkb_mod_index_t altIndex;
xkb_mod_mask_t shiftMask; xkb_mod_index_t shiftIndex;
xkb_mod_mask_t superMask; xkb_mod_index_t superIndex;
xkb_mod_mask_t capsLockMask; xkb_mod_index_t capsLockIndex;
xkb_mod_mask_t numLockMask; xkb_mod_index_t numLockIndex;
unsigned int modifiers; unsigned int modifiers;
PFN_xkb_context_new context_new; PFN_xkb_context_new context_new;
@ -290,8 +432,8 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_state_unref state_unref; PFN_xkb_state_unref state_unref;
PFN_xkb_state_key_get_syms state_key_get_syms; PFN_xkb_state_key_get_syms state_key_get_syms;
PFN_xkb_state_update_mask state_update_mask; PFN_xkb_state_update_mask state_update_mask;
PFN_xkb_state_serialize_mods state_serialize_mods;
PFN_xkb_state_key_get_layout state_key_get_layout; PFN_xkb_state_key_get_layout state_key_get_layout;
PFN_xkb_state_mod_index_is_active state_mod_index_is_active;
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
PFN_xkb_compose_table_unref compose_table_unref; PFN_xkb_compose_table_unref compose_table_unref;
@ -321,6 +463,38 @@ typedef struct _GLFWlibraryWayland
PFN_wl_egl_window_destroy window_destroy; PFN_wl_egl_window_destroy window_destroy;
PFN_wl_egl_window_resize window_resize; PFN_wl_egl_window_resize window_resize;
} egl; } egl;
struct {
void* handle;
struct libdecor* context;
struct wl_callback* callback;
GLFWbool ready;
PFN_libdecor_new libdecor_new_;
PFN_libdecor_unref libdecor_unref_;
PFN_libdecor_get_fd libdecor_get_fd_;
PFN_libdecor_dispatch libdecor_dispatch_;
PFN_libdecor_decorate libdecor_decorate_;
PFN_libdecor_frame_unref libdecor_frame_unref_;
PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_;
PFN_libdecor_frame_set_title libdecor_frame_set_title_;
PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_;
PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_;
PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_;
PFN_libdecor_frame_map libdecor_frame_map_;
PFN_libdecor_frame_commit libdecor_frame_commit_;
PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_;
PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_;
PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_;
PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_;
PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;
PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;
PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;
PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;
PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;
PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;
PFN_libdecor_state_new libdecor_state_new_;
PFN_libdecor_state_free libdecor_state_free_;
} libdecor;
} _GLFWlibraryWayland; } _GLFWlibraryWayland;
// Wayland-specific per-monitor data // Wayland-specific per-monitor data
@ -333,7 +507,7 @@ typedef struct _GLFWmonitorWayland
int x; int x;
int y; int y;
int scale; int contentScale;
} _GLFWmonitorWayland; } _GLFWmonitorWayland;
// Wayland-specific per-cursor data // Wayland-specific per-cursor data
@ -348,7 +522,9 @@ typedef struct _GLFWcursorWayland
int currentImage; int currentImage;
} _GLFWcursorWayland; } _GLFWcursorWayland;
void _glfwAddOutputWayland(uint32_t name, uint32_t version); void _glfwAddOutputWayland(uint32_t name, uint32_t version);
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode); void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,7 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
// Translate the X11 KeySyms for a key to a GLFW key code // Translate the X11 KeySyms for a key to a GLFW key code
@ -1028,8 +1029,9 @@ static int errorHandler(Display *display, XErrorEvent* event)
// //
void _glfwGrabErrorHandlerX11(void) void _glfwGrabErrorHandlerX11(void)
{ {
assert(_glfw.x11.errorHandler == NULL);
_glfw.x11.errorCode = Success; _glfw.x11.errorCode = Success;
XSetErrorHandler(errorHandler); _glfw.x11.errorHandler = XSetErrorHandler(errorHandler);
} }
// Clears the X error handler callback // Clears the X error handler callback
@ -1038,7 +1040,8 @@ void _glfwReleaseErrorHandlerX11(void)
{ {
// Synchronize to make sure all commands are processed // Synchronize to make sure all commands are processed
XSync(_glfw.x11.display, False); XSync(_glfw.x11.display, False);
XSetErrorHandler(NULL); XSetErrorHandler(_glfw.x11.errorHandler);
_glfw.x11.errorHandler = NULL;
} }
// Reports the specified error, appending information about the last X error // Reports the specified error, appending information about the last X error
@ -1241,6 +1244,7 @@ void _glfwPlatformTerminate(void)
_glfw.x11.xi.handle = NULL; _glfw.x11.xi.handle = NULL;
} }
_glfwTerminateOSMesa();
// NOTE: These need to be unloaded after XCloseDisplay, as they register // NOTE: These need to be unloaded after XCloseDisplay, as they register
// cleanup callbacks that get called by that function // cleanup callbacks that get called by that function
_glfwTerminateEGL(); _glfwTerminateEGL();

View File

@ -228,6 +228,8 @@ typedef struct _GLFWlibraryX11
XContext context; XContext context;
// XIM input method // XIM input method
XIM im; XIM im;
// The previous X error handler, to be restored later
XErrorHandler errorHandler;
// Most recent error code received by X error handler // Most recent error code received by X error handler
int errorCode; int errorCode;
// Primary selection string (while the primary selection is owned) // Primary selection string (while the primary selection is owned)

View File

@ -164,7 +164,7 @@ static void writeEmptyEvent(void)
for (;;) for (;;)
{ {
const char byte = 0; const char byte = 0;
const int result = write(_glfw.x11.emptyEventPipe[1], &byte, 1); const ssize_t result = write(_glfw.x11.emptyEventPipe[1], &byte, 1);
if (result == 1 || (result == -1 && errno != EINTR)) if (result == 1 || (result == -1 && errno != EINTR))
break; break;
} }
@ -177,7 +177,7 @@ static void drainEmptyEvents(void)
for (;;) for (;;)
{ {
char dummy[64]; char dummy[64];
const int result = read(_glfw.x11.emptyEventPipe[0], dummy, sizeof(dummy)); const ssize_t result = read(_glfw.x11.emptyEventPipe[0], dummy, sizeof(dummy));
if (result == -1 && errno != EINTR) if (result == -1 && errno != EINTR)
break; break;
} }
@ -321,6 +321,11 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
{ {
XSizeHints* hints = XAllocSizeHints(); XSizeHints* hints = XAllocSizeHints();
long supplied;
XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied);
hints->flags &= ~(PMinSize | PMaxSize | PAspect);
if (!window->monitor) if (!window->monitor)
{ {
if (window->resizable) if (window->resizable)
@ -357,9 +362,6 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
} }
} }
hints->flags |= PWinGravity;
hints->win_gravity = StaticGravity;
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
XFree(hints); XFree(hints);
} }
@ -458,57 +460,6 @@ static void updateWindowMode(_GLFWwindow* window)
} }
} }
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
static char** parseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** paths = NULL;
char* line;
*count = 0;
while ((line = strtok(text, "\r\n")))
{
text = NULL;
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
{
line += strlen(prefix);
// TODO: Validate hostname
while (*line != '/')
line++;
}
(*count)++;
char* path = calloc(strlen(line) + 1, 1);
paths = realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*path = strtol(digits, NULL, 16);
line += 2;
}
else
*path = *line;
path++;
line++;
}
}
return paths;
}
// Decode a Unicode code point from a UTF-8 stream // Decode a Unicode code point from a UTF-8 stream
// Based on cutef8 by Jeff Bezanson (Public Domain) // Based on cutef8 by Jeff Bezanson (Public Domain)
// //
@ -574,6 +525,25 @@ static void updateCursorImage(_GLFWwindow* window)
} }
} }
// Grabs the cursor and confines it to the window
//
static void captureCursor(_GLFWwindow* window)
{
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
window->x11.handle,
None,
CurrentTime);
}
// Ungrabs the cursor
//
static void releaseCursor(void)
{
XUngrabPointer(_glfw.x11.display, CurrentTime);
}
// Enable XI2 raw mouse motion events // Enable XI2 raw mouse motion events
// //
static void enableRawMouseMotion(_GLFWwindow* window) static void enableRawMouseMotion(_GLFWwindow* window)
@ -616,12 +586,7 @@ static void disableCursor(_GLFWwindow* window)
&_glfw.x11.restoreCursorPosY); &_glfw.x11.restoreCursorPosY);
updateCursorImage(window); updateCursorImage(window);
_glfwCenterCursorInContentArea(window); _glfwCenterCursorInContentArea(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True, captureCursor(window);
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync,
window->x11.handle,
_glfw.x11.hiddenCursorHandle,
CurrentTime);
} }
// Exit disabled cursor mode for the specified window // Exit disabled cursor mode for the specified window
@ -632,7 +597,7 @@ static void enableCursor(_GLFWwindow* window)
disableRawMouseMotion(window); disableRawMouseMotion(window);
_glfw.x11.disabledCursorWindow = NULL; _glfw.x11.disabledCursorWindow = NULL;
XUngrabPointer(_glfw.x11.display, CurrentTime); releaseCursor();
_glfwPlatformSetCursorPos(window, _glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX, _glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY); _glfw.x11.restoreCursorPosY);
@ -777,7 +742,28 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
XFree(hints); XFree(hints);
} }
updateNormalHints(window, width, height); // Set ICCCM WM_NORMAL_HINTS property
{
XSizeHints* hints = XAllocSizeHints();
if (!hints)
{
_glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate size hints");
return GLFW_FALSE;
}
if (!wndconfig->resizable)
{
hints->flags |= (PMinSize | PMaxSize);
hints->min_width = hints->max_width = width;
hints->min_height = hints->max_height = height;
}
hints->flags |= PWinGravity;
hints->win_gravity = StaticGravity;
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
XFree(hints);
}
// Set ICCCM WM_CLASS property // Set ICCCM WM_CLASS property
{ {
@ -980,20 +966,6 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
return None; return None;
} }
static void handleSelectionClear(XEvent* event)
{
if (event->xselectionclear.selection == _glfw.x11.PRIMARY)
{
free(_glfw.x11.primarySelectionString);
_glfw.x11.primarySelectionString = NULL;
}
else
{
free(_glfw.x11.clipboardString);
_glfw.x11.clipboardString = NULL;
}
}
static void handleSelectionRequest(XEvent* event) static void handleSelectionRequest(XEvent* event)
{ {
const XSelectionRequestEvent* request = &event->xselectionrequest; const XSelectionRequestEvent* request = &event->xselectionrequest;
@ -1113,6 +1085,8 @@ static const char* getSelectionString(Atom selection)
} }
if (!itemCount) if (!itemCount)
{
if (string)
{ {
if (targets[i] == XA_STRING) if (targets[i] == XA_STRING)
{ {
@ -1121,6 +1095,7 @@ static const char* getSelectionString(Atom selection)
} }
else else
*selectionString = string; *selectionString = string;
}
break; break;
} }
@ -1287,12 +1262,7 @@ static void processEvent(XEvent *event)
return; return;
} }
if (event->type == SelectionClear) if (event->type == SelectionRequest)
{
handleSelectionClear(event);
return;
}
else if (event->type == SelectionRequest)
{ {
handleSelectionRequest(event); handleSelectionRequest(event);
return; return;
@ -1808,7 +1778,7 @@ static void processEvent(XEvent *event)
if (result) if (result)
{ {
int i, count; int i, count;
char** paths = parseUriList(data, &count); char** paths = _glfwParseUriList(data, &count);
_glfwInputDrop(window, count, (const char**) paths); _glfwInputDrop(window, count, (const char**) paths);
@ -1997,10 +1967,6 @@ void _glfwPushSelectionToManagerX11(void)
handleSelectionRequest(&event); handleSelectionRequest(&event);
break; break;
case SelectionClear:
handleSelectionClear(&event);
break;
case SelectionNotify: case SelectionNotify:
{ {
if (event.xselection.target == _glfw.x11.SAVE_TARGETS) if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
@ -2084,6 +2050,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
} }
if (window->monitor) if (window->monitor)
@ -2091,6 +2060,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformShowWindow(window); _glfwPlatformShowWindow(window);
updateWindowMode(window); updateWindowMode(window);
acquireMonitor(window); acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwPlatformShowWindow(window);
if (wndconfig->focused)
_glfwPlatformFocusWindow(window);
}
} }
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
@ -2100,7 +2081,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{ {
if (_glfw.x11.disabledCursorWindow == window) if (_glfw.x11.disabledCursorWindow == window)
_glfw.x11.disabledCursorWindow = NULL; enableCursor(window);
if (window->monitor) if (window->monitor)
releaseMonitor(window); releaseMonitor(window);
@ -2906,17 +2887,41 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
} }
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (_glfwPlatformWindowFocused(window))
{ {
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{ {
if (_glfwPlatformWindowFocused(window)) _glfwPlatformGetCursorPos(window,
disableCursor(window); &_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
if (window->rawMouseMotion)
enableRawMouseMotion(window);
} }
else if (_glfw.x11.disabledCursorWindow == window) else if (_glfw.x11.disabledCursorWindow == window)
enableCursor(window); {
else if (window->rawMouseMotion)
updateCursorImage(window); disableRawMouseMotion(window);
}
if (mode == GLFW_CURSOR_DISABLED)
captureCursor(window);
else
releaseCursor();
if (mode == GLFW_CURSOR_DISABLED)
_glfw.x11.disabledCursorWindow = window;
else if (_glfw.x11.disabledCursorWindow == window)
{
_glfw.x11.disabledCursorWindow = NULL;
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
}
}
updateCursorImage(window);
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
} }

View File

@ -621,7 +621,7 @@ int main(int argc, char** argv)
glfwMakeContextCurrent(slots[i].window); glfwMakeContextCurrent(slots[i].window);
gladLoadGL(glfwGetProcAddress); gladLoadGL(glfwGetProcAddress);
glfwSwapInterval(1); glfwSwapBuffers(slots[i].window);
} }
printf("Main loop starting\n"); printf("Main loop starting\n");

View File

@ -210,30 +210,6 @@ static void list_context_extensions(int client, int major, int minor)
} }
} }
static void list_vulkan_instance_extensions(void)
{
uint32_t i, ep_count = 0;
VkExtensionProperties* ep;
printf("Vulkan instance extensions:\n");
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS)
return;
ep = calloc(ep_count, sizeof(VkExtensionProperties));
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS)
{
free(ep);
return;
}
for (i = 0; i < ep_count; i++)
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
free(ep);
}
static void list_vulkan_instance_layers(void) static void list_vulkan_instance_layers(void)
{ {
uint32_t i, lp_count = 0; uint32_t i, lp_count = 0;
@ -254,39 +230,16 @@ static void list_vulkan_instance_layers(void)
for (i = 0; i < lp_count; i++) for (i = 0; i < lp_count; i++)
{ {
printf(" %s (v%u) \"%s\"\n", printf(" %s (spec version %u.%u) \"%s\"\n",
lp[i].layerName, lp[i].layerName,
lp[i].specVersion >> 22, VK_VERSION_MAJOR(lp[i].specVersion),
VK_VERSION_MINOR(lp[i].specVersion),
lp[i].description); lp[i].description);
} }
free(lp); free(lp);
} }
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
{
uint32_t i, ep_count;
VkExtensionProperties* ep;
printf("Vulkan device extensions:\n");
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS)
return;
ep = calloc(ep_count, sizeof(VkExtensionProperties));
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS)
{
free(ep);
return;
}
for (i = 0; i < ep_count; i++)
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
free(ep);
}
static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device) static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device)
{ {
uint32_t i, lp_count; uint32_t i, lp_count;
@ -307,9 +260,10 @@ static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice devi
for (i = 0; i < lp_count; i++) for (i = 0; i < lp_count; i++)
{ {
printf(" %s (v%u) \"%s\"\n", printf(" %s (spec version %u.%u) \"%s\"\n",
lp[i].layerName, lp[i].layerName,
lp[i].specVersion >> 22, VK_VERSION_MAJOR(lp[i].specVersion),
VK_VERSION_MINOR(lp[i].specVersion),
lp[i].description); lp[i].description);
} }
@ -346,11 +300,6 @@ static void print_version(void)
printf("GLFW library version string: \"%s\"\n", glfwGetVersionString()); printf("GLFW library version string: \"%s\"\n", glfwGetVersionString());
} }
static GLADapiproc glad_vulkan_callback(const char* name, void* user)
{
return glfwGetInstanceProcAddress((VkInstance) user, name);
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ch, client, major, minor, revision, profile; int ch, client, major, minor, revision, profile;
@ -806,20 +755,33 @@ int main(int argc, char** argv)
if (list_extensions) if (list_extensions)
list_context_extensions(client, major, minor); list_context_extensions(client, major, minor);
glfwDestroyWindow(window);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
printf("Vulkan loader: %s\n", printf("Vulkan loader: %s\n",
glfwVulkanSupported() ? "available" : "missing"); glfwVulkanSupported() ? "available" : "missing");
if (glfwVulkanSupported()) if (glfwVulkanSupported())
{ {
uint32_t loader_version = VK_API_VERSION_1_0; uint32_t loader_version = VK_API_VERSION_1_0;
uint32_t i, re_count, pd_count; int portability_enumeration = GLFW_FALSE;
uint32_t i, j, glfw_re_count, re_count, pd_count, ep_count;
const char** glfw_re;
const char** re; const char** re;
VkApplicationInfo ai = {0}; VkApplicationInfo ai = {0};
VkInstanceCreateInfo ici = {0}; VkInstanceCreateInfo ici = {0};
VkInstance instance; VkInstance instance;
VkPhysicalDevice* pd; VkPhysicalDevice* pd;
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL); gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL);
if (vkEnumerateInstanceVersion) if (vkEnumerateInstanceVersion)
{ {
@ -832,20 +794,47 @@ int main(int argc, char** argv)
VK_VERSION_MAJOR(loader_version), VK_VERSION_MAJOR(loader_version),
VK_VERSION_MINOR(loader_version)); VK_VERSION_MINOR(loader_version));
re = glfwGetRequiredInstanceExtensions(&re_count); glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count);
printf("Vulkan required instance extensions:"); re_count = glfw_re_count;
if (re) re = calloc(glfw_re_count, sizeof(char*));
printf("Vulkan window surface required instance extensions:\n");
if (glfw_re)
{ {
for (i = 0; i < re_count; i++) for (i = 0; i < glfw_re_count; i++)
printf(" %s", re[i]); {
putchar('\n'); printf(" %s\n", glfw_re[i]);
re[i] = glfw_re[i];
}
} }
else else
printf(" missing\n"); printf(" missing\n");
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL);
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep);
if (list_extensions) if (list_extensions)
list_vulkan_instance_extensions(); {
printf("Vulkan instance extensions:\n");
for (i = 0; i < ep_count; i++)
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
}
for (i = 0; i < ep_count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_portability_enumeration") != 0)
continue;
re_count++;
re = realloc((void*) re, sizeof(char*) * re_count);
re[re_count - 1] = "VK_KHR_portability_enumeration";
portability_enumeration = GLFW_TRUE;
}
free(ep);
if (list_layers) if (list_layers)
list_vulkan_instance_layers(); list_vulkan_instance_layers();
@ -866,34 +855,40 @@ int main(int argc, char** argv)
ici.enabledExtensionCount = re_count; ici.enabledExtensionCount = re_count;
ici.ppEnabledExtensionNames = re; ici.ppEnabledExtensionNames = re;
if (portability_enumeration)
ici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS) if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
{ {
glfwTerminate(); glfwTerminate();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, instance); if (re)
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
{ {
vkDestroyInstance(instance, NULL); VkSurfaceKHR surface = VK_NULL_HANDLE;
glfwTerminate();
exit(EXIT_FAILURE); if (glfwCreateWindowSurface(instance, window, NULL, &surface) == VK_SUCCESS)
{
printf("Vulkan window surface created successfully\n");
vkDestroySurfaceKHR(instance, surface, NULL);
}
else
printf("Failed to create Vulkan window surface\n");
} }
free((void*) re);
gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance);
vkEnumeratePhysicalDevices(instance, &pd_count, NULL);
pd = calloc(pd_count, sizeof(VkPhysicalDevice)); pd = calloc(pd_count, sizeof(VkPhysicalDevice));
vkEnumeratePhysicalDevices(instance, &pd_count, pd);
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
{
free(pd);
vkDestroyInstance(instance, NULL);
glfwTerminate();
exit(EXIT_FAILURE);
}
for (i = 0; i < pd_count; i++) for (i = 0; i < pd_count; i++)
{ {
VkPhysicalDeviceProperties pdp; VkPhysicalDeviceProperties pdp;
uint32_t qfp_count, ep_count;
vkGetPhysicalDeviceProperties(pd[i], &pdp); vkGetPhysicalDeviceProperties(pd[i], &pdp);
@ -903,8 +898,62 @@ int main(int argc, char** argv)
VK_VERSION_MAJOR(pdp.apiVersion), VK_VERSION_MAJOR(pdp.apiVersion),
VK_VERSION_MINOR(pdp.apiVersion)); VK_VERSION_MINOR(pdp.apiVersion));
vkGetPhysicalDeviceQueueFamilyProperties(pd[i], &qfp_count, NULL);
vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, NULL);
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, ep);
if (portability_enumeration)
{
int conformant = GLFW_TRUE;
for (j = 0; j < ep_count; j++)
{
if (strcmp(ep[j].extensionName, "VK_KHR_portability_subset") == 0)
{
conformant = GLFW_FALSE;
break;
}
}
printf("Vulkan %s %s device: \"%s\" (API version %i.%i)\n",
conformant ? "conformant" : "non-conformant",
get_device_type_name(pdp.deviceType),
pdp.deviceName,
VK_VERSION_MAJOR(pdp.apiVersion),
VK_VERSION_MINOR(pdp.apiVersion));
}
else
{
printf("Vulkan %s device: \"%s\" (API version %i.%i)\n",
get_device_type_name(pdp.deviceType),
pdp.deviceName,
VK_VERSION_MAJOR(pdp.apiVersion),
VK_VERSION_MINOR(pdp.apiVersion));
}
if (glfw_re_count)
{
printf("Vulkan device queue family presentation support:\n");
for (j = 0; j < qfp_count; j++)
{
printf(" %u: ", j);
if (glfwGetPhysicalDevicePresentationSupport(instance, pd[i], j))
printf("supported\n");
else
printf("no\n");
}
}
if (list_extensions) if (list_extensions)
list_vulkan_device_extensions(instance, pd[i]); {
printf("Vulkan device extensions:\n");
for (j = 0; j < ep_count; j++)
printf(" %s (spec version %u)\n", ep[j].extensionName, ep[j].specVersion);
}
free(ep);
if (list_layers) if (list_layers)
list_vulkan_device_layers(instance, pd[i]); list_vulkan_device_layers(instance, pd[i]);
@ -914,6 +963,8 @@ int main(int argc, char** argv)
vkDestroyInstance(instance, NULL); vkDestroyInstance(instance, NULL);
} }
glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }

View File

@ -65,11 +65,6 @@
exit(1); \ exit(1); \
} while (0) } while (0)
static GLADapiproc glad_vulkan_callback(const char* name, void* user)
{
return glfwGetInstanceProcAddress((VkInstance) user, name);
}
static const uint32_t fragShaderCode[] = { static const uint32_t fragShaderCode[] = {
0x07230203,0x00010000,0x00080007,0x00000014,0x00000000,0x00020011,0x00000001,0x0006000b, 0x07230203,0x00010000,0x00080007,0x00000014,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
@ -1251,7 +1246,7 @@ static void demo_prepare_pipeline(struct demo *demo) {
VkPipelineDepthStencilStateCreateInfo ds; VkPipelineDepthStencilStateCreateInfo ds;
VkPipelineViewportStateCreateInfo vp; VkPipelineViewportStateCreateInfo vp;
VkPipelineMultisampleStateCreateInfo ms; VkPipelineMultisampleStateCreateInfo ms;
VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; VkDynamicState dynamicStateEnables[2];
VkPipelineDynamicStateCreateInfo dynamicState; VkPipelineDynamicStateCreateInfo dynamicState;
VkResult U_ASSERT_ONLY err; VkResult U_ASSERT_ONLY err;
@ -1565,6 +1560,7 @@ static VkBool32 demo_check_layers(uint32_t check_count, const char **check_names
static void demo_init_vk(struct demo *demo) { static void demo_init_vk(struct demo *demo) {
VkResult err; VkResult err;
VkBool32 portability_enumeration = VK_FALSE;
uint32_t i = 0; uint32_t i = 0;
uint32_t required_extension_count = 0; uint32_t required_extension_count = 0;
uint32_t instance_extension_count = 0; uint32_t instance_extension_count = 0;
@ -1672,6 +1668,13 @@ static void demo_init_vk(struct demo *demo) {
} }
} }
assert(demo->enabled_extension_count < 64); assert(demo->enabled_extension_count < 64);
if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
instance_extensions[i].extensionName)) {
demo->extension_names[demo->enabled_extension_count++] =
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
portability_enumeration = VK_TRUE;
}
assert(demo->enabled_extension_count < 64);
} }
free(instance_extensions); free(instance_extensions);
@ -1696,6 +1699,9 @@ static void demo_init_vk(struct demo *demo) {
.ppEnabledExtensionNames = (const char *const *)demo->extension_names, .ppEnabledExtensionNames = (const char *const *)demo->extension_names,
}; };
if (portability_enumeration)
inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
uint32_t gpu_count; uint32_t gpu_count;
err = vkCreateInstance(&inst_info, NULL, &demo->inst); err = vkCreateInstance(&inst_info, NULL, &demo->inst);
@ -1715,7 +1721,7 @@ static void demo_init_vk(struct demo *demo) {
"vkCreateInstance Failure"); "vkCreateInstance Failure");
} }
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, demo->inst); gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, demo->inst);
/* Make initial call to query gpu_count, then second call for gpu info*/ /* Make initial call to query gpu_count, then second call for gpu info*/
err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL); err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL);
@ -1738,7 +1744,7 @@ static void demo_init_vk(struct demo *demo) {
"vkEnumeratePhysicalDevices Failure"); "vkEnumeratePhysicalDevices Failure");
} }
gladLoadVulkanUserPtr(demo->gpu, glad_vulkan_callback, demo->inst); gladLoadVulkanUserPtr(demo->gpu, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, demo->inst);
/* Look for device extensions */ /* Look for device extensions */
uint32_t device_extension_count = 0; uint32_t device_extension_count = 0;
@ -1966,7 +1972,7 @@ static void demo_init_connection(struct demo *demo) {
exit(1); exit(1);
} }
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL); gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL);
} }
static void demo_init(struct demo *demo, const int argc, const char *argv[]) static void demo_init(struct demo *demo, const int argc, const char *argv[])