mirror of
https://github.com/glfw/glfw.git
synced 2026-09-17 22:32:50 +00:00
Compare commits
334 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e91fa399f1 | |||
| dc46d3f812 | |||
| 07efe9068e | |||
| 3af1a1f514 | |||
| a7c3e95980 | |||
| 0cac1ad41f | |||
| 2d51e650be | |||
| bc788a9333 | |||
| ae44e10b33 | |||
| 438cd224d7 | |||
| 8d95aeac69 | |||
| a1090c867d | |||
| 15b771759d | |||
| d172fec64b | |||
| bfa24c9f2d | |||
| 20bd0329a5 | |||
| fafcba3824 | |||
| 7554375d6d | |||
| dbe2d7cb4a | |||
| 76227fa519 | |||
| 0161cde6f3 | |||
| c710d2c05d | |||
| a943d9ac17 | |||
| 7998629ad2 | |||
| 9ba47ca13a | |||
| dd288eabf6 | |||
| e2c9264546 | |||
| 7b60753aeb | |||
| 628385e99e | |||
| 217c269d66 | |||
| 6ea5bf9032 | |||
| 1fab407e44 | |||
| 7cdd41170b | |||
| e0de6ea513 | |||
| 79d957ca18 | |||
| 63bba49e31 | |||
| 80d45cdfd7 | |||
| 683b7524d2 | |||
| 356f56a166 | |||
| 5f936a6276 | |||
| 1c989eace3 | |||
| c98860db9e | |||
| cb0dafa7c0 | |||
| 11f517e557 | |||
| 2a4e26870b | |||
| 31f08cc7fc | |||
| 9809035ed2 | |||
| 7cc8879ab9 | |||
| 89b149a56f | |||
| b52b074be5 | |||
| b211975131 | |||
| 2c09407bff | |||
| 7c7cc59889 | |||
| 6f9686f1f4 | |||
| 89bea58b18 | |||
| ff156743ab | |||
| 489339b837 | |||
| af93f06259 | |||
| 8ef347157a | |||
| c754de5deb | |||
| bf429fb628 | |||
| 8da6223c90 | |||
| c3f15da23a | |||
| 1d766c8b39 | |||
| 67d722788d | |||
| 06a2ed38ea | |||
| 0c2db4a23e | |||
| 1ad5df8032 | |||
| 95b35c43c2 | |||
| e5d19c9fac | |||
| 5ac970120a | |||
| 677fbb0f82 | |||
| a29b5f38c6 | |||
| 1de73c0dc5 | |||
| a6e3efbafc | |||
| ba99e20f6a | |||
| 8522447792 | |||
| ba80e23dab | |||
| 2178c3e536 | |||
| 1b4e126dc0 | |||
| 71dfc3f65c | |||
| 4a33051456 | |||
| b06a91e92b | |||
| c7a5333873 | |||
| 05e28537a3 | |||
| af3e14fbc2 | |||
| d36d062d72 | |||
| 493df4a0b5 | |||
| 31b038663a | |||
| 6fb86c089e | |||
| bc36010350 | |||
| bd13f55ca8 | |||
| 8b4f1ebbea | |||
| 1f675ab62f | |||
| ed55529ce8 | |||
| 426c6ed6b1 | |||
| 1fe29e2c19 | |||
| 34bfb52641 | |||
| 3670cd0561 | |||
| 0ee9b7281b | |||
| 5f3e5542cf | |||
| 632d35e0d4 | |||
| 5189d52ae3 | |||
| 78edf2516e | |||
| 74090d30cd | |||
| ad206bdaee | |||
| b08271d315 | |||
| 2ca3bda1cc | |||
| 388d0cf7c2 | |||
| 4affd2207c | |||
| dea9914692 | |||
| 1acd67eeb6 | |||
| a8d543f1f8 | |||
| ca5ccd819d | |||
| 41bb7b8617 | |||
| ccbbada181 | |||
| fe2ac5027b | |||
| 7482de6071 | |||
| 0f341802e1 | |||
| 935d7098b6 | |||
| 5937eec914 | |||
| 20d11f7f97 | |||
| 8d989cdc41 | |||
| 5324177d90 | |||
| 2f3c6aa150 | |||
| 8c63c935ea | |||
| 876a177f6c | |||
| 1e49024e76 | |||
| 109f836675 | |||
| 2568d703cd | |||
| 9950cc52df | |||
| e50ee39eac | |||
| 70a024232a | |||
| 0cd8813e82 | |||
| e541b7969a | |||
| be333cf0fd | |||
| 758d4b1987 | |||
| 1ac6fbc499 | |||
| 75b37bd2d7 | |||
| 7b65ecf77c | |||
| aef1d4584f | |||
| 17959aad33 | |||
| 8f9ddfe3c2 | |||
| 4c7f6ada0c | |||
| c807f386c2 | |||
| fae1d349d3 | |||
| 593b85380e | |||
| a0259b9426 | |||
| e79d6fe40a | |||
| 498a4d0635 | |||
| 35fd90aff1 | |||
| 6b9087c575 | |||
| 48e0e0acf5 | |||
| 557da4cdc4 | |||
| 50ea41cb04 | |||
| 2529e663d7 | |||
| 8b26801a30 | |||
| e04a7d152a | |||
| 8de0c1cdc1 | |||
| fead23153e | |||
| cdbcb8c5a7 | |||
| 4ba1208239 | |||
| 941744a59a | |||
| f454410b79 | |||
| 5feaa33529 | |||
| e894bf71a2 | |||
| ebe2b648ea | |||
| 51018f19d0 | |||
| 1ad9c2d5dd | |||
| 1c4284e449 | |||
| 608007673f | |||
| 589385aada | |||
| 15050f5711 | |||
| 562eca6f28 | |||
| dea602623d | |||
| 581fed38be | |||
| 9f8ec83411 | |||
| 3ec59687f1 | |||
| aa1efada52 | |||
| b86fcd7cd0 | |||
| 631da8cc2f | |||
| 416f7828ff | |||
| 6de6446aca | |||
| 2a6d25d1aa | |||
| f4e36e5389 | |||
| f001aa3490 | |||
| b9ea733ca8 | |||
| c8be8606f0 | |||
| 1b3b2108e3 | |||
| af9eb79de4 | |||
| 65b8c4a46b | |||
| 946312fe93 | |||
| bf5529512c | |||
| 0052ddc5e3 | |||
| 53d40878c8 | |||
| 6dd9bf0bef | |||
| 6d08e52bcf | |||
| 3d9d4e311c | |||
| af612103d0 | |||
| 4143d96228 | |||
| 05422e2824 | |||
| 2b504e41d5 | |||
| 50d5de7cd4 | |||
| 4d0e98d90c | |||
| c0c0d172a1 | |||
| 9e852ec39e | |||
| 4d68daedc9 | |||
| ea1b6b9638 | |||
| f145e1f930 | |||
| 915e43885c | |||
| 857fae4920 | |||
| a31c648127 | |||
| c89899a428 | |||
| 75b27849f6 | |||
| f51ec79951 | |||
| 3599fe4a78 | |||
| 1ee540bf48 | |||
| 32bedd9a94 | |||
| 25db8f8014 | |||
| 2430d6b7f7 | |||
| 53bd67ccfe | |||
| 22f718dcf4 | |||
| f93751ce68 | |||
| 8897c8a1cb | |||
| 307ccd68a5 | |||
| de550b60e5 | |||
| 802882f7cb | |||
| c2ccf6f919 | |||
| 32df2ed716 | |||
| c2188e2d0a | |||
| e7a81f8aaa | |||
| 3006c02bc2 | |||
| b43c122dd1 | |||
| 74a1ae065a | |||
| 45ce5ddd19 | |||
| 395f0a8b63 | |||
| d9fd087bbf | |||
| 5688fb19e6 | |||
| d1269c1b7d | |||
| 541b151cff | |||
| 8d08426725 | |||
| 85a3bf40fb | |||
| d9512b694b | |||
| 35a65361ff | |||
| 6659a80040 | |||
| 1813cc0af5 | |||
| 9cfd4c49b0 | |||
| eac18b9324 | |||
| 499a5a7917 | |||
| b0af476799 | |||
| 9dd3f25d6d | |||
| 7302a8f520 | |||
| 9f73e9afa3 | |||
| 5ccc756c56 | |||
| e219c00d87 | |||
| 7f752c17c6 | |||
| 811e6bb01c | |||
| b4aa5f626f | |||
| ca1a98e7a2 | |||
| 54f2a865e9 | |||
| 09470b68c1 | |||
| 9340324380 | |||
| 7a4813cedd | |||
| d1c0797630 | |||
| 2a6dac679c | |||
| b716ff5b97 | |||
| dccec7fcae | |||
| 4bf6bd42fd | |||
| c68ad09c04 | |||
| e155c19f8e | |||
| 6b15731e6c | |||
| 554f5d0492 | |||
| 3901824c0e | |||
| 5066f57371 | |||
| 1f7ce12cbc | |||
| 0eaf9d557f | |||
| 61497796e6 | |||
| 86a1d3b628 | |||
| 9ab14a8cc0 | |||
| f5dab59071 | |||
| 658c931561 | |||
| 0c46a730de | |||
| 1fa4312b29 | |||
| eb6fc17746 | |||
| ed785a2c79 | |||
| fba79aaaec | |||
| ec934edfbf | |||
| 5f0b316c24 | |||
| 5e8186af0a | |||
| 17c5c53910 | |||
| 6afc571ade | |||
| 22eaa04b49 | |||
| 65fc4fa625 | |||
| 8ecb49d143 | |||
| 9240ee5ddf | |||
| 3b806aef27 | |||
| 5470fd6de9 | |||
| 52133a3690 | |||
| 8f3677a0d4 | |||
| f21a9104e4 | |||
| 869e68a015 | |||
| 7d5a16ce71 | |||
| a69648e192 | |||
| e10def6de7 | |||
| 84c881c1a8 | |||
| 18d7c241f8 | |||
| 6281424988 | |||
| 81d762bf66 | |||
| 486724c433 | |||
| 55528e9178 | |||
| 689840f2eb | |||
| c59092619a | |||
| bfd9eaf092 | |||
| 6902435005 | |||
| 6eb24a49df | |||
| bec6e7565b | |||
| 19543afbfb | |||
| cc5f563905 | |||
| 2927cc87c8 | |||
| 747224cb54 | |||
| 82b8651e00 | |||
| cbce7a3648 | |||
| de3b5ec937 | |||
| 78dccc5c00 | |||
| 63e535210c | |||
| ae8561d740 | |||
| ddd85a9e2f | |||
| 83dbe197c0 | |||
| e669471aca | |||
| 1a965d2230 | |||
| 02bd652f2b | |||
| 0ebae5a3df | |||
| 830b05ecf9 | |||
| 02461dc843 |
@@ -1,8 +1,6 @@
|
||||
|
||||
* @elmindreda
|
||||
|
||||
src/wl_* @linkmauve
|
||||
|
||||
docs/*.css @glfw/webdev
|
||||
docs/*.scss @glfw/webdev
|
||||
docs/*.html @glfw/webdev
|
||||
@@ -3,6 +3,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ ci, master, latest, 3.3-stable ]
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
statuses: write
|
||||
contents: read
|
||||
@@ -11,11 +12,12 @@ jobs:
|
||||
build-linux-x11-clang:
|
||||
name: X11 (Linux, Clang)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 4
|
||||
env:
|
||||
CC: clang
|
||||
CFLAGS: -Werror
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -34,11 +36,12 @@ jobs:
|
||||
build-linux-wayland-clang:
|
||||
name: Wayland (Linux, Clang)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 4
|
||||
env:
|
||||
CC: clang
|
||||
CFLAGS: -Werror
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -57,11 +60,12 @@ jobs:
|
||||
build-linux-null-clang:
|
||||
name: Null (Linux, Clang)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 4
|
||||
env:
|
||||
CC: clang
|
||||
CFLAGS: -Werror
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
@@ -80,11 +84,12 @@ jobs:
|
||||
build-macos-cocoa-clang:
|
||||
name: Cocoa (macOS, Clang)
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 4
|
||||
env:
|
||||
CFLAGS: -Werror
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.8
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure static library
|
||||
run: cmake -S . -B build-static
|
||||
@@ -96,21 +101,22 @@ jobs:
|
||||
- name: Build shared library
|
||||
run: cmake --build build-shared --parallel
|
||||
|
||||
build-windows-win32-vs2019:
|
||||
name: Win32 (Windows, VS2019)
|
||||
build-windows-win32-vs2022:
|
||||
name: Win32 (Windows, VS2022)
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 4
|
||||
env:
|
||||
CFLAGS: /WX
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure static library
|
||||
run: cmake -S . -B build-static -G "Visual Studio 16 2019"
|
||||
run: cmake -S . -B build-static -G "Visual Studio 17 2022"
|
||||
- name: Build static library
|
||||
run: cmake --build build-static --parallel
|
||||
|
||||
- name: Configure shared library
|
||||
run: cmake -S . -B build-shared -G "Visual Studio 16 2019" -D BUILD_SHARED_LIBS=ON
|
||||
run: cmake -S . -B build-shared -G "Visual Studio 17 2022" -D BUILD_SHARED_LIBS=ON
|
||||
- name: Build shared library
|
||||
run: cmake --build build-shared --parallel
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# The canonical out-of-tree build subdirectory
|
||||
build
|
||||
build-*
|
||||
|
||||
# Visual Studio clutter
|
||||
_ReSharper*
|
||||
|
||||
+6
-4
@@ -1,8 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR)
|
||||
|
||||
project(GLFW VERSION 3.3.5 LANGUAGES C)
|
||||
|
||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||
project(GLFW VERSION 3.3.10 LANGUAGES C)
|
||||
|
||||
if (POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
@@ -47,6 +45,7 @@ if (BUILD_SHARED_LIBS AND UNIX)
|
||||
else()
|
||||
set(GLFW_LIB_NAME glfw3)
|
||||
endif()
|
||||
set(GLFW_LIB_NAME_SUFFIX "")
|
||||
|
||||
if (GLFW_VULKAN_STATIC)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
@@ -198,6 +197,10 @@ if (_GLFW_WIN32)
|
||||
if (GLFW_USE_HYBRID_HPG)
|
||||
set(_GLFW_USE_HYBRID_HPG 1)
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (GLFW_LIB_NAME_SUFFIX "dll")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
@@ -266,7 +269,6 @@ if (_GLFW_WAYLAND)
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
|
||||
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
|
||||
|
||||
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
|
||||
@@ -8,6 +8,7 @@ video tutorials.
|
||||
- Bobyshev Alexander
|
||||
- Laurent Aphecetche
|
||||
- Matt Arsenault
|
||||
- Takuro Ashie
|
||||
- ashishgamedev
|
||||
- David Avedissian
|
||||
- Keith Bauer
|
||||
@@ -18,17 +19,20 @@ video tutorials.
|
||||
- Nevyn Bengtsson
|
||||
- Niklas Bergström
|
||||
- Denis Bernard
|
||||
- BiBi
|
||||
- Doug Binks
|
||||
- blanco
|
||||
- Waris Boonyasiriwat
|
||||
- Kyle Brenneman
|
||||
- Rok Breulj
|
||||
- TheBrokenRail
|
||||
- Kai Burjack
|
||||
- Martin Capitanio
|
||||
- Nicolas Caramelli
|
||||
- David Carlier
|
||||
- Arturo Castro
|
||||
- Chi-kwan Chan
|
||||
- TheChocolateOre
|
||||
- Joseph Chua
|
||||
- Ian Clarkson
|
||||
- Michał Cichoń
|
||||
@@ -41,7 +45,9 @@ video tutorials.
|
||||
- Bailey Cosier
|
||||
- Noel Cower
|
||||
- CuriouserThing
|
||||
- Bill Currie
|
||||
- Jason Daly
|
||||
- danhambleton
|
||||
- Jarrod Davis
|
||||
- Olivier Delannoy
|
||||
- Paul R. Deppe
|
||||
@@ -53,32 +59,52 @@ video tutorials.
|
||||
- Ralph Eastwood
|
||||
- Fredrik Ehnbom
|
||||
- Robin Eklind
|
||||
- Jan Ekström
|
||||
- Siavash Eliasi
|
||||
- TheExileFox
|
||||
- Nikita Fediuchin
|
||||
- Felipe Ferreira
|
||||
- Michael Fogleman
|
||||
- forworldm
|
||||
- Jason Francis
|
||||
- Gerald Franz
|
||||
- Mário Freitas
|
||||
- GeO4d
|
||||
- Marcus Geelnard
|
||||
- Gegy
|
||||
- ghuser404
|
||||
- Charles Giessen
|
||||
- Ryan C. Gordon
|
||||
- Stephen Gowen
|
||||
- Kovid Goyal
|
||||
- Kevin Grandemange
|
||||
- Eloi Marín Gratacós
|
||||
- Grzesiek11
|
||||
- Stefan Gustavson
|
||||
- Andrew Gutekanst
|
||||
- Stephen Gutekanst
|
||||
- Jonathan Hale
|
||||
- Daniel Hauser
|
||||
- hdf89shfdfs
|
||||
- Moritz Heinemann
|
||||
- Sylvain Hellegouarch
|
||||
- Björn Hempel
|
||||
- Matthew Henry
|
||||
- heromyth
|
||||
- Lucas Hinderberger
|
||||
- Paul Holden
|
||||
- Hajime Hoshi
|
||||
- Warren Hu
|
||||
- Charles Huber
|
||||
- Brent Huisman
|
||||
- illustris
|
||||
- InKryption
|
||||
- IntellectualKitty
|
||||
- Aaron Jacobs
|
||||
- JannikGM
|
||||
- Erik S. V. Jansson
|
||||
- jjYBdx4IL
|
||||
- Peter Johnson
|
||||
- Toni Jovanoski
|
||||
- Arseny Kapoulkine
|
||||
- Cem Karan
|
||||
@@ -101,12 +127,16 @@ video tutorials.
|
||||
- Anders Lindqvist
|
||||
- Leon Linhart
|
||||
- Marco Lizza
|
||||
- lo-v-ol
|
||||
- Eyal Lotem
|
||||
- Aaron Loucks
|
||||
- Ned Loynd
|
||||
- Luflosi
|
||||
- lukect
|
||||
- Tristam MacDonald
|
||||
- Jean-Luc Mackail
|
||||
- Hans Mackowiak
|
||||
- Ramiro Magno
|
||||
- Дмитри Малышев
|
||||
- Zbigniew Mandziejewicz
|
||||
- Adam Marcus
|
||||
@@ -119,19 +149,25 @@ video tutorials.
|
||||
- Marcel Metz
|
||||
- Liam Middlebrook
|
||||
- Ave Milia
|
||||
- Icyllis Milica
|
||||
- Jonathan Miller
|
||||
- Kenneth Miller
|
||||
- Bruce Mitchener
|
||||
- Jack Moffitt
|
||||
- Ravi Mohan
|
||||
- Jeff Molofee
|
||||
- Alexander Monakov
|
||||
- Pierre Morel
|
||||
- Jon Morton
|
||||
- Pierre Moulon
|
||||
- Martins Mozeiko
|
||||
- James Murphy
|
||||
- Julian Møller
|
||||
- NateIsStalling
|
||||
- ndogxj
|
||||
- F. Nedelec
|
||||
- Kristian Nielsen
|
||||
- Joel Niemelä
|
||||
- Kamil Nowakowski
|
||||
- onox
|
||||
- Denis Ovod
|
||||
@@ -142,10 +178,12 @@ video tutorials.
|
||||
- Christopher Pelloux
|
||||
- Arturo J. Pérez
|
||||
- Vladimir Perminov
|
||||
- Olivier Perret
|
||||
- Anthony Pesch
|
||||
- Orson Peters
|
||||
- Emmanuel Gil Peyrot
|
||||
- Cyril Pichard
|
||||
- Pilzschaf
|
||||
- Keith Pitt
|
||||
- Stanislav Podgorskiy
|
||||
- Konstantin Podsvirov
|
||||
@@ -154,30 +192,40 @@ video tutorials.
|
||||
- Pablo Prietz
|
||||
- przemekmirek
|
||||
- pthom
|
||||
- Martin Pulec
|
||||
- Guillaume Racicot
|
||||
- Christian Rauch
|
||||
- Philip Rideout
|
||||
- Eddie Ringle
|
||||
- Max Risuhin
|
||||
- Joe Roback
|
||||
- Jorge Rodriguez
|
||||
- Luca Rood
|
||||
- Ed Ropple
|
||||
- Aleksey Rybalkin
|
||||
- Mikko Rytkönen
|
||||
- Riku Salminen
|
||||
- Anton Samokhvalov
|
||||
- Brandon Schaefer
|
||||
- Sebastian Schuberth
|
||||
- Christian Sdunek
|
||||
- Matt Sealey
|
||||
- Steve Sexton
|
||||
- Arkady Shapkin
|
||||
- Mingjie Shen
|
||||
- Ali Sherief
|
||||
- Yoshiki Shibukawa
|
||||
- Dmitri Shuralyov
|
||||
- Joao da Silva
|
||||
- Daniel Sieger
|
||||
- Michael Skec
|
||||
- Daniel Skorupski
|
||||
- Slemmie
|
||||
- Bradley Smith
|
||||
- Cliff Smolinsky
|
||||
- Patrick Snape
|
||||
- Erlend Sogge Heggen
|
||||
- Olivier Sohn
|
||||
- Julian Squires
|
||||
- Johannes Stein
|
||||
- Pontus Stenetorp
|
||||
@@ -187,8 +235,10 @@ video tutorials.
|
||||
- Paul Sultana
|
||||
- Nathan Sweet
|
||||
- TTK-Bandit
|
||||
- Nuno Teixeira
|
||||
- Sergey Tikhomirov
|
||||
- Arthur Tombs
|
||||
- TronicLabs
|
||||
- Ioannis Tsakpinis
|
||||
- Samuli Tuomola
|
||||
- Matthew Turner
|
||||
@@ -198,16 +248,20 @@ video tutorials.
|
||||
- Jari Vetoniemi
|
||||
- Ricardo Vieira
|
||||
- Nicholas Vitovitch
|
||||
- Vladimír Vondruš
|
||||
- Simon Voordouw
|
||||
- Corentin Wallez
|
||||
- Torsten Walluhn
|
||||
- Patrick Walton
|
||||
- Jim Wang
|
||||
- Xo Wang
|
||||
- Jay Weisskopf
|
||||
- Frank Wille
|
||||
- Richard A. Wilkes
|
||||
- Andy Williams
|
||||
- Tatsuya Yatagawa
|
||||
- Ryogo Yoshimura
|
||||
- Rácz Zalán
|
||||
- Lukas Zanner
|
||||
- Andrey Zholos
|
||||
- Aihui Zhu
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
[](https://github.com/glfw/glfw/actions)
|
||||
[](https://ci.appveyor.com/project/elmindreda/glfw)
|
||||
[](https://scan.coverity.com/projects/glfw-glfw)
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -123,26 +122,12 @@ information on what to include when reporting a bug.
|
||||
|
||||
## Changelog
|
||||
|
||||
- Updated gamepad mappings from upstream
|
||||
- Bugfix: Buffers were swapped at creation on single-buffered windows (#1873)
|
||||
- Bugfix: Gamepad mapping updates could spam `GLFW_INVALID_VALUE` due to
|
||||
incompatible controllers sharing hardware ID (#1763)
|
||||
- Bugfix: Native access functions for context handles did not check that the API matched
|
||||
- [Win32] Bugfix: `USE_MSVC_RUNTIME_LIBRARY_DLL` had no effect on CMake 3.15 or
|
||||
later (#1783,#1796)
|
||||
- [Win32] Bugfix: Compilation with LLVM for Windows failed (#1807,#1824,#1874)
|
||||
- [Cocoa] Bugfix: The MoltenVK layer contents scale was updated only after
|
||||
related events were emitted
|
||||
- [Cocoa] Bugfix: Moving the cursor programmatically would freeze it for
|
||||
a fraction of a second (#1962)
|
||||
- [Cocoa] Bugfix: `kIOMasterPortDefault` was deprecated in macOS 12.0 (#1980)
|
||||
- [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory
|
||||
- [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908)
|
||||
- [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899)
|
||||
- [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD
|
||||
- [NSGL] Bugfix: Defining `GL_SILENCE_DEPRECATION` externally caused
|
||||
a duplicate definition warning (#1840)
|
||||
- [EGL] Bugfix: The `GLFW_DOUBLEBUFFER` context attribute was ignored (#1843)
|
||||
- Bugfix: `glfwGetKeyName` emitted `GLFW_INVALID_VALUE` for scancodes with no
|
||||
key token (#1785,#2214)
|
||||
- [Wayland] Bugfix: Terminating the library before showing a window could segfault
|
||||
- [Wayland] Bugfix: Compilation failed on FreeBSD (#2445)
|
||||
- [Linux] Bugfix: `regfree´ was called on invalid data (#2464)
|
||||
- [WGL] Bugfix: Context creation failed in Parallels VM (#2191,#2406,#2467)
|
||||
|
||||
|
||||
## Contact
|
||||
@@ -151,13 +136,12 @@ On [glfw.org](https://www.glfw.org/) you can find the latest version of GLFW, as
|
||||
well as news, documentation and other information about the project.
|
||||
|
||||
If you have questions related to the use of GLFW, we have a
|
||||
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||
[Libera.Chat](https://libera.chat/).
|
||||
[forum](https://discourse.glfw.org/).
|
||||
|
||||
If you have a bug to report, a patch to submit or a feature you'd like to
|
||||
request, please file it in the
|
||||
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
|
||||
|
||||
Finally, if you're interested in helping out with the development of GLFW or
|
||||
porting it to your favorite platform, join us on the forum, GitHub or IRC.
|
||||
porting it to your favorite platform, join us on the forum or GitHub.
|
||||
|
||||
|
||||
Vendored
+6
-14
@@ -2,19 +2,9 @@
|
||||
/* 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");
|
||||
** 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.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -52,7 +42,7 @@ extern "C"
|
||||
#define VKAPI_CALL __stdcall
|
||||
#define VKAPI_PTR VKAPI_CALL
|
||||
#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)
|
||||
/* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
|
||||
/* calling convention, i.e. float parameters are passed in registers. This */
|
||||
@@ -68,7 +58,9 @@ extern "C"
|
||||
#define VKAPI_PTR
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#if !defined(VK_NO_STDDEF_H)
|
||||
#include <stddef.h>
|
||||
#endif /* !defined(VK_NO_STDDEF_H) */
|
||||
|
||||
#if !defined(VK_NO_STDINT_H)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
|
||||
Vendored
+2382
-354
File diff suppressed because it is too large
Load Diff
Vendored
+348
-208
@@ -14,10 +14,18 @@
|
||||
|
||||
#endif /* GLAD_IMPL_UTIL_C_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int GLAD_VK_VERSION_1_0 = 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_KHR_portability_enumeration = 0;
|
||||
int GLAD_VK_KHR_surface = 0;
|
||||
int GLAD_VK_KHR_swapchain = 0;
|
||||
|
||||
@@ -35,18 +43,26 @@ PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
|
||||
PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL;
|
||||
PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
|
||||
PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
|
||||
PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 = NULL;
|
||||
PFN_vkCmdBeginRendering glad_vkCmdBeginRendering = NULL;
|
||||
PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
|
||||
PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
|
||||
PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
|
||||
PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
|
||||
PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 = NULL;
|
||||
PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
|
||||
PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2 = NULL;
|
||||
PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
|
||||
PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
|
||||
PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
|
||||
PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
|
||||
PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 = NULL;
|
||||
PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
|
||||
PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 = NULL;
|
||||
PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
|
||||
PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2 = NULL;
|
||||
PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
|
||||
PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 = NULL;
|
||||
PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
|
||||
PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
|
||||
PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL;
|
||||
@@ -54,31 +70,56 @@ PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
|
||||
PFN_vkCmdDraw glad_vkCmdDraw = NULL;
|
||||
PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
|
||||
PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
|
||||
PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount = NULL;
|
||||
PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
|
||||
PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount = NULL;
|
||||
PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
|
||||
PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
|
||||
PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 = NULL;
|
||||
PFN_vkCmdEndRendering glad_vkCmdEndRendering = NULL;
|
||||
PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
|
||||
PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
|
||||
PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
|
||||
PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2 = NULL;
|
||||
PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
|
||||
PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 = NULL;
|
||||
PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
|
||||
PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
|
||||
PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2 = NULL;
|
||||
PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
|
||||
PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
|
||||
PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2 = NULL;
|
||||
PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
|
||||
PFN_vkCmdSetCullMode glad_vkCmdSetCullMode = NULL;
|
||||
PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
|
||||
PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable = 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_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
|
||||
PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2 = NULL;
|
||||
PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace = 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_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount = NULL;
|
||||
PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
|
||||
PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp = NULL;
|
||||
PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
|
||||
PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable = NULL;
|
||||
PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
|
||||
PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
|
||||
PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount = NULL;
|
||||
PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
|
||||
PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
|
||||
PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2 = NULL;
|
||||
PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
|
||||
PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 = NULL;
|
||||
PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
|
||||
PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
|
||||
PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
|
||||
@@ -97,8 +138,10 @@ PFN_vkCreateImageView glad_vkCreateImageView = NULL;
|
||||
PFN_vkCreateInstance glad_vkCreateInstance = NULL;
|
||||
PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
|
||||
PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
|
||||
PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot = NULL;
|
||||
PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
|
||||
PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
|
||||
PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2 = NULL;
|
||||
PFN_vkCreateSampler glad_vkCreateSampler = NULL;
|
||||
PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL;
|
||||
PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
|
||||
@@ -122,6 +165,7 @@ PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
|
||||
PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
|
||||
PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
|
||||
PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
|
||||
PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot = NULL;
|
||||
PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
|
||||
PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
|
||||
PFN_vkDestroySampler glad_vkDestroySampler = NULL;
|
||||
@@ -143,13 +187,19 @@ PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
|
||||
PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
|
||||
PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
|
||||
PFN_vkFreeMemory glad_vkFreeMemory = NULL;
|
||||
PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress = NULL;
|
||||
PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
|
||||
PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL;
|
||||
PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress = NULL;
|
||||
PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL;
|
||||
PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements = NULL;
|
||||
PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL;
|
||||
PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
|
||||
PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
|
||||
PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements = NULL;
|
||||
PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements = NULL;
|
||||
PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
|
||||
PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress = NULL;
|
||||
PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
|
||||
PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
|
||||
PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL;
|
||||
@@ -183,9 +233,12 @@ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCap
|
||||
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
|
||||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
|
||||
PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
|
||||
PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties = NULL;
|
||||
PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
|
||||
PFN_vkGetPrivateData glad_vkGetPrivateData = NULL;
|
||||
PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
|
||||
PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
|
||||
PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue = NULL;
|
||||
PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
|
||||
PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
|
||||
PFN_vkMapMemory glad_vkMapMemory = NULL;
|
||||
@@ -193,216 +246,277 @@ PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
|
||||
PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
|
||||
PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
|
||||
PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
|
||||
PFN_vkQueueSubmit2 glad_vkQueueSubmit2 = NULL;
|
||||
PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
|
||||
PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
|
||||
PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
|
||||
PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
|
||||
PFN_vkResetEvent glad_vkResetEvent = NULL;
|
||||
PFN_vkResetFences glad_vkResetFences = NULL;
|
||||
PFN_vkResetQueryPool glad_vkResetQueryPool = NULL;
|
||||
PFN_vkSetEvent glad_vkSetEvent = NULL;
|
||||
PFN_vkSetPrivateData glad_vkSetPrivateData = NULL;
|
||||
PFN_vkSignalSemaphore glad_vkSignalSemaphore = NULL;
|
||||
PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL;
|
||||
PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
|
||||
PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL;
|
||||
PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
|
||||
PFN_vkWaitForFences glad_vkWaitForFences = NULL;
|
||||
PFN_vkWaitSemaphores glad_vkWaitSemaphores = NULL;
|
||||
|
||||
|
||||
static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_VK_VERSION_1_0) return;
|
||||
vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load("vkAllocateCommandBuffers", userptr);
|
||||
vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load("vkAllocateDescriptorSets", userptr);
|
||||
vkAllocateMemory = (PFN_vkAllocateMemory) load("vkAllocateMemory", userptr);
|
||||
vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load("vkBeginCommandBuffer", userptr);
|
||||
vkBindBufferMemory = (PFN_vkBindBufferMemory) load("vkBindBufferMemory", userptr);
|
||||
vkBindImageMemory = (PFN_vkBindImageMemory) load("vkBindImageMemory", userptr);
|
||||
vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load("vkCmdBeginQuery", userptr);
|
||||
vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load("vkCmdBeginRenderPass", userptr);
|
||||
vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load("vkCmdBindDescriptorSets", userptr);
|
||||
vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load("vkCmdBindIndexBuffer", userptr);
|
||||
vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load("vkCmdBindPipeline", userptr);
|
||||
vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load("vkCmdBindVertexBuffers", userptr);
|
||||
vkCmdBlitImage = (PFN_vkCmdBlitImage) load("vkCmdBlitImage", userptr);
|
||||
vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load("vkCmdClearAttachments", userptr);
|
||||
vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load("vkCmdClearColorImage", userptr);
|
||||
vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load("vkCmdClearDepthStencilImage", userptr);
|
||||
vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load("vkCmdCopyBuffer", userptr);
|
||||
vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load("vkCmdCopyBufferToImage", userptr);
|
||||
vkCmdCopyImage = (PFN_vkCmdCopyImage) load("vkCmdCopyImage", userptr);
|
||||
vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load("vkCmdCopyImageToBuffer", userptr);
|
||||
vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load("vkCmdCopyQueryPoolResults", userptr);
|
||||
vkCmdDispatch = (PFN_vkCmdDispatch) load("vkCmdDispatch", userptr);
|
||||
vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load("vkCmdDispatchIndirect", userptr);
|
||||
vkCmdDraw = (PFN_vkCmdDraw) load("vkCmdDraw", userptr);
|
||||
vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load("vkCmdDrawIndexed", userptr);
|
||||
vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load("vkCmdDrawIndexedIndirect", userptr);
|
||||
vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load("vkCmdDrawIndirect", userptr);
|
||||
vkCmdEndQuery = (PFN_vkCmdEndQuery) load("vkCmdEndQuery", userptr);
|
||||
vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load("vkCmdEndRenderPass", userptr);
|
||||
vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load("vkCmdExecuteCommands", userptr);
|
||||
vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load("vkCmdFillBuffer", userptr);
|
||||
vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load("vkCmdNextSubpass", userptr);
|
||||
vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load("vkCmdPipelineBarrier", userptr);
|
||||
vkCmdPushConstants = (PFN_vkCmdPushConstants) load("vkCmdPushConstants", userptr);
|
||||
vkCmdResetEvent = (PFN_vkCmdResetEvent) load("vkCmdResetEvent", userptr);
|
||||
vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load("vkCmdResetQueryPool", userptr);
|
||||
vkCmdResolveImage = (PFN_vkCmdResolveImage) load("vkCmdResolveImage", userptr);
|
||||
vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load("vkCmdSetBlendConstants", userptr);
|
||||
vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load("vkCmdSetDepthBias", userptr);
|
||||
vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load("vkCmdSetDepthBounds", userptr);
|
||||
vkCmdSetEvent = (PFN_vkCmdSetEvent) load("vkCmdSetEvent", userptr);
|
||||
vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load("vkCmdSetLineWidth", userptr);
|
||||
vkCmdSetScissor = (PFN_vkCmdSetScissor) load("vkCmdSetScissor", userptr);
|
||||
vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load("vkCmdSetStencilCompareMask", userptr);
|
||||
vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load("vkCmdSetStencilReference", userptr);
|
||||
vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load("vkCmdSetStencilWriteMask", userptr);
|
||||
vkCmdSetViewport = (PFN_vkCmdSetViewport) load("vkCmdSetViewport", userptr);
|
||||
vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load("vkCmdUpdateBuffer", userptr);
|
||||
vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load("vkCmdWaitEvents", userptr);
|
||||
vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load("vkCmdWriteTimestamp", userptr);
|
||||
vkCreateBuffer = (PFN_vkCreateBuffer) load("vkCreateBuffer", userptr);
|
||||
vkCreateBufferView = (PFN_vkCreateBufferView) load("vkCreateBufferView", userptr);
|
||||
vkCreateCommandPool = (PFN_vkCreateCommandPool) load("vkCreateCommandPool", userptr);
|
||||
vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load("vkCreateComputePipelines", userptr);
|
||||
vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load("vkCreateDescriptorPool", userptr);
|
||||
vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load("vkCreateDescriptorSetLayout", userptr);
|
||||
vkCreateDevice = (PFN_vkCreateDevice) load("vkCreateDevice", userptr);
|
||||
vkCreateEvent = (PFN_vkCreateEvent) load("vkCreateEvent", userptr);
|
||||
vkCreateFence = (PFN_vkCreateFence) load("vkCreateFence", userptr);
|
||||
vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load("vkCreateFramebuffer", userptr);
|
||||
vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load("vkCreateGraphicsPipelines", userptr);
|
||||
vkCreateImage = (PFN_vkCreateImage) load("vkCreateImage", userptr);
|
||||
vkCreateImageView = (PFN_vkCreateImageView) load("vkCreateImageView", userptr);
|
||||
vkCreateInstance = (PFN_vkCreateInstance) load("vkCreateInstance", userptr);
|
||||
vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load("vkCreatePipelineCache", userptr);
|
||||
vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load("vkCreatePipelineLayout", userptr);
|
||||
vkCreateQueryPool = (PFN_vkCreateQueryPool) load("vkCreateQueryPool", userptr);
|
||||
vkCreateRenderPass = (PFN_vkCreateRenderPass) load("vkCreateRenderPass", userptr);
|
||||
vkCreateSampler = (PFN_vkCreateSampler) load("vkCreateSampler", userptr);
|
||||
vkCreateSemaphore = (PFN_vkCreateSemaphore) load("vkCreateSemaphore", userptr);
|
||||
vkCreateShaderModule = (PFN_vkCreateShaderModule) load("vkCreateShaderModule", userptr);
|
||||
vkDestroyBuffer = (PFN_vkDestroyBuffer) load("vkDestroyBuffer", userptr);
|
||||
vkDestroyBufferView = (PFN_vkDestroyBufferView) load("vkDestroyBufferView", userptr);
|
||||
vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load("vkDestroyCommandPool", userptr);
|
||||
vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load("vkDestroyDescriptorPool", userptr);
|
||||
vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load("vkDestroyDescriptorSetLayout", userptr);
|
||||
vkDestroyDevice = (PFN_vkDestroyDevice) load("vkDestroyDevice", userptr);
|
||||
vkDestroyEvent = (PFN_vkDestroyEvent) load("vkDestroyEvent", userptr);
|
||||
vkDestroyFence = (PFN_vkDestroyFence) load("vkDestroyFence", userptr);
|
||||
vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load("vkDestroyFramebuffer", userptr);
|
||||
vkDestroyImage = (PFN_vkDestroyImage) load("vkDestroyImage", userptr);
|
||||
vkDestroyImageView = (PFN_vkDestroyImageView) load("vkDestroyImageView", userptr);
|
||||
vkDestroyInstance = (PFN_vkDestroyInstance) load("vkDestroyInstance", userptr);
|
||||
vkDestroyPipeline = (PFN_vkDestroyPipeline) load("vkDestroyPipeline", userptr);
|
||||
vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load("vkDestroyPipelineCache", userptr);
|
||||
vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load("vkDestroyPipelineLayout", userptr);
|
||||
vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load("vkDestroyQueryPool", userptr);
|
||||
vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load("vkDestroyRenderPass", userptr);
|
||||
vkDestroySampler = (PFN_vkDestroySampler) load("vkDestroySampler", userptr);
|
||||
vkDestroySemaphore = (PFN_vkDestroySemaphore) load("vkDestroySemaphore", userptr);
|
||||
vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load("vkDestroyShaderModule", userptr);
|
||||
vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load("vkDeviceWaitIdle", userptr);
|
||||
vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load("vkEndCommandBuffer", userptr);
|
||||
vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load("vkEnumerateDeviceExtensionProperties", userptr);
|
||||
vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load("vkEnumerateDeviceLayerProperties", userptr);
|
||||
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load("vkEnumerateInstanceExtensionProperties", userptr);
|
||||
vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load("vkEnumerateInstanceLayerProperties", userptr);
|
||||
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load("vkEnumeratePhysicalDevices", userptr);
|
||||
vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load("vkFlushMappedMemoryRanges", userptr);
|
||||
vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load("vkFreeCommandBuffers", userptr);
|
||||
vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load("vkFreeDescriptorSets", userptr);
|
||||
vkFreeMemory = (PFN_vkFreeMemory) load("vkFreeMemory", userptr);
|
||||
vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load("vkGetBufferMemoryRequirements", userptr);
|
||||
vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load("vkGetDeviceMemoryCommitment", userptr);
|
||||
vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load("vkGetDeviceProcAddr", userptr);
|
||||
vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load("vkGetDeviceQueue", userptr);
|
||||
vkGetEventStatus = (PFN_vkGetEventStatus) load("vkGetEventStatus", userptr);
|
||||
vkGetFenceStatus = (PFN_vkGetFenceStatus) load("vkGetFenceStatus", userptr);
|
||||
vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load("vkGetImageMemoryRequirements", userptr);
|
||||
vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load("vkGetImageSparseMemoryRequirements", userptr);
|
||||
vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load("vkGetImageSubresourceLayout", userptr);
|
||||
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load("vkGetInstanceProcAddr", userptr);
|
||||
vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load("vkGetPhysicalDeviceFeatures", userptr);
|
||||
vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load("vkGetPhysicalDeviceFormatProperties", userptr);
|
||||
vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load("vkGetPhysicalDeviceImageFormatProperties", userptr);
|
||||
vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load("vkGetPhysicalDeviceMemoryProperties", userptr);
|
||||
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load("vkGetPhysicalDeviceProperties", userptr);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load("vkGetPhysicalDeviceQueueFamilyProperties", userptr);
|
||||
vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr);
|
||||
vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load("vkGetPipelineCacheData", userptr);
|
||||
vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load("vkGetQueryPoolResults", userptr);
|
||||
vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load("vkGetRenderAreaGranularity", userptr);
|
||||
vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load("vkInvalidateMappedMemoryRanges", userptr);
|
||||
vkMapMemory = (PFN_vkMapMemory) load("vkMapMemory", userptr);
|
||||
vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load("vkMergePipelineCaches", userptr);
|
||||
vkQueueBindSparse = (PFN_vkQueueBindSparse) load("vkQueueBindSparse", userptr);
|
||||
vkQueueSubmit = (PFN_vkQueueSubmit) load("vkQueueSubmit", userptr);
|
||||
vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load("vkQueueWaitIdle", userptr);
|
||||
vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load("vkResetCommandBuffer", userptr);
|
||||
vkResetCommandPool = (PFN_vkResetCommandPool) load("vkResetCommandPool", userptr);
|
||||
vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load("vkResetDescriptorPool", userptr);
|
||||
vkResetEvent = (PFN_vkResetEvent) load("vkResetEvent", userptr);
|
||||
vkResetFences = (PFN_vkResetFences) load("vkResetFences", userptr);
|
||||
vkSetEvent = (PFN_vkSetEvent) load("vkSetEvent", userptr);
|
||||
vkUnmapMemory = (PFN_vkUnmapMemory) load("vkUnmapMemory", userptr);
|
||||
vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load("vkUpdateDescriptorSets", userptr);
|
||||
vkWaitForFences = (PFN_vkWaitForFences) load("vkWaitForFences", userptr);
|
||||
glad_vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load(userptr, "vkAllocateCommandBuffers");
|
||||
glad_vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load(userptr, "vkAllocateDescriptorSets");
|
||||
glad_vkAllocateMemory = (PFN_vkAllocateMemory) load(userptr, "vkAllocateMemory");
|
||||
glad_vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load(userptr, "vkBeginCommandBuffer");
|
||||
glad_vkBindBufferMemory = (PFN_vkBindBufferMemory) load(userptr, "vkBindBufferMemory");
|
||||
glad_vkBindImageMemory = (PFN_vkBindImageMemory) load(userptr, "vkBindImageMemory");
|
||||
glad_vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load(userptr, "vkCmdBeginQuery");
|
||||
glad_vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load(userptr, "vkCmdBeginRenderPass");
|
||||
glad_vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load(userptr, "vkCmdBindDescriptorSets");
|
||||
glad_vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load(userptr, "vkCmdBindIndexBuffer");
|
||||
glad_vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load(userptr, "vkCmdBindPipeline");
|
||||
glad_vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load(userptr, "vkCmdBindVertexBuffers");
|
||||
glad_vkCmdBlitImage = (PFN_vkCmdBlitImage) load(userptr, "vkCmdBlitImage");
|
||||
glad_vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load(userptr, "vkCmdClearAttachments");
|
||||
glad_vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load(userptr, "vkCmdClearColorImage");
|
||||
glad_vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load(userptr, "vkCmdClearDepthStencilImage");
|
||||
glad_vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load(userptr, "vkCmdCopyBuffer");
|
||||
glad_vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load(userptr, "vkCmdCopyBufferToImage");
|
||||
glad_vkCmdCopyImage = (PFN_vkCmdCopyImage) load(userptr, "vkCmdCopyImage");
|
||||
glad_vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load(userptr, "vkCmdCopyImageToBuffer");
|
||||
glad_vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load(userptr, "vkCmdCopyQueryPoolResults");
|
||||
glad_vkCmdDispatch = (PFN_vkCmdDispatch) load(userptr, "vkCmdDispatch");
|
||||
glad_vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load(userptr, "vkCmdDispatchIndirect");
|
||||
glad_vkCmdDraw = (PFN_vkCmdDraw) load(userptr, "vkCmdDraw");
|
||||
glad_vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load(userptr, "vkCmdDrawIndexed");
|
||||
glad_vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load(userptr, "vkCmdDrawIndexedIndirect");
|
||||
glad_vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load(userptr, "vkCmdDrawIndirect");
|
||||
glad_vkCmdEndQuery = (PFN_vkCmdEndQuery) load(userptr, "vkCmdEndQuery");
|
||||
glad_vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load(userptr, "vkCmdEndRenderPass");
|
||||
glad_vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load(userptr, "vkCmdExecuteCommands");
|
||||
glad_vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load(userptr, "vkCmdFillBuffer");
|
||||
glad_vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load(userptr, "vkCmdNextSubpass");
|
||||
glad_vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load(userptr, "vkCmdPipelineBarrier");
|
||||
glad_vkCmdPushConstants = (PFN_vkCmdPushConstants) load(userptr, "vkCmdPushConstants");
|
||||
glad_vkCmdResetEvent = (PFN_vkCmdResetEvent) load(userptr, "vkCmdResetEvent");
|
||||
glad_vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load(userptr, "vkCmdResetQueryPool");
|
||||
glad_vkCmdResolveImage = (PFN_vkCmdResolveImage) load(userptr, "vkCmdResolveImage");
|
||||
glad_vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load(userptr, "vkCmdSetBlendConstants");
|
||||
glad_vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load(userptr, "vkCmdSetDepthBias");
|
||||
glad_vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load(userptr, "vkCmdSetDepthBounds");
|
||||
glad_vkCmdSetEvent = (PFN_vkCmdSetEvent) load(userptr, "vkCmdSetEvent");
|
||||
glad_vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load(userptr, "vkCmdSetLineWidth");
|
||||
glad_vkCmdSetScissor = (PFN_vkCmdSetScissor) load(userptr, "vkCmdSetScissor");
|
||||
glad_vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load(userptr, "vkCmdSetStencilCompareMask");
|
||||
glad_vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load(userptr, "vkCmdSetStencilReference");
|
||||
glad_vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load(userptr, "vkCmdSetStencilWriteMask");
|
||||
glad_vkCmdSetViewport = (PFN_vkCmdSetViewport) load(userptr, "vkCmdSetViewport");
|
||||
glad_vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load(userptr, "vkCmdUpdateBuffer");
|
||||
glad_vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load(userptr, "vkCmdWaitEvents");
|
||||
glad_vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load(userptr, "vkCmdWriteTimestamp");
|
||||
glad_vkCreateBuffer = (PFN_vkCreateBuffer) load(userptr, "vkCreateBuffer");
|
||||
glad_vkCreateBufferView = (PFN_vkCreateBufferView) load(userptr, "vkCreateBufferView");
|
||||
glad_vkCreateCommandPool = (PFN_vkCreateCommandPool) load(userptr, "vkCreateCommandPool");
|
||||
glad_vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load(userptr, "vkCreateComputePipelines");
|
||||
glad_vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load(userptr, "vkCreateDescriptorPool");
|
||||
glad_vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load(userptr, "vkCreateDescriptorSetLayout");
|
||||
glad_vkCreateDevice = (PFN_vkCreateDevice) load(userptr, "vkCreateDevice");
|
||||
glad_vkCreateEvent = (PFN_vkCreateEvent) load(userptr, "vkCreateEvent");
|
||||
glad_vkCreateFence = (PFN_vkCreateFence) load(userptr, "vkCreateFence");
|
||||
glad_vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load(userptr, "vkCreateFramebuffer");
|
||||
glad_vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load(userptr, "vkCreateGraphicsPipelines");
|
||||
glad_vkCreateImage = (PFN_vkCreateImage) load(userptr, "vkCreateImage");
|
||||
glad_vkCreateImageView = (PFN_vkCreateImageView) load(userptr, "vkCreateImageView");
|
||||
glad_vkCreateInstance = (PFN_vkCreateInstance) load(userptr, "vkCreateInstance");
|
||||
glad_vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load(userptr, "vkCreatePipelineCache");
|
||||
glad_vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load(userptr, "vkCreatePipelineLayout");
|
||||
glad_vkCreateQueryPool = (PFN_vkCreateQueryPool) load(userptr, "vkCreateQueryPool");
|
||||
glad_vkCreateRenderPass = (PFN_vkCreateRenderPass) load(userptr, "vkCreateRenderPass");
|
||||
glad_vkCreateSampler = (PFN_vkCreateSampler) load(userptr, "vkCreateSampler");
|
||||
glad_vkCreateSemaphore = (PFN_vkCreateSemaphore) load(userptr, "vkCreateSemaphore");
|
||||
glad_vkCreateShaderModule = (PFN_vkCreateShaderModule) load(userptr, "vkCreateShaderModule");
|
||||
glad_vkDestroyBuffer = (PFN_vkDestroyBuffer) load(userptr, "vkDestroyBuffer");
|
||||
glad_vkDestroyBufferView = (PFN_vkDestroyBufferView) load(userptr, "vkDestroyBufferView");
|
||||
glad_vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load(userptr, "vkDestroyCommandPool");
|
||||
glad_vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load(userptr, "vkDestroyDescriptorPool");
|
||||
glad_vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load(userptr, "vkDestroyDescriptorSetLayout");
|
||||
glad_vkDestroyDevice = (PFN_vkDestroyDevice) load(userptr, "vkDestroyDevice");
|
||||
glad_vkDestroyEvent = (PFN_vkDestroyEvent) load(userptr, "vkDestroyEvent");
|
||||
glad_vkDestroyFence = (PFN_vkDestroyFence) load(userptr, "vkDestroyFence");
|
||||
glad_vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load(userptr, "vkDestroyFramebuffer");
|
||||
glad_vkDestroyImage = (PFN_vkDestroyImage) load(userptr, "vkDestroyImage");
|
||||
glad_vkDestroyImageView = (PFN_vkDestroyImageView) load(userptr, "vkDestroyImageView");
|
||||
glad_vkDestroyInstance = (PFN_vkDestroyInstance) load(userptr, "vkDestroyInstance");
|
||||
glad_vkDestroyPipeline = (PFN_vkDestroyPipeline) load(userptr, "vkDestroyPipeline");
|
||||
glad_vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load(userptr, "vkDestroyPipelineCache");
|
||||
glad_vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load(userptr, "vkDestroyPipelineLayout");
|
||||
glad_vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load(userptr, "vkDestroyQueryPool");
|
||||
glad_vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load(userptr, "vkDestroyRenderPass");
|
||||
glad_vkDestroySampler = (PFN_vkDestroySampler) load(userptr, "vkDestroySampler");
|
||||
glad_vkDestroySemaphore = (PFN_vkDestroySemaphore) load(userptr, "vkDestroySemaphore");
|
||||
glad_vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load(userptr, "vkDestroyShaderModule");
|
||||
glad_vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load(userptr, "vkDeviceWaitIdle");
|
||||
glad_vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load(userptr, "vkEndCommandBuffer");
|
||||
glad_vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load(userptr, "vkEnumerateDeviceExtensionProperties");
|
||||
glad_vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load(userptr, "vkEnumerateDeviceLayerProperties");
|
||||
glad_vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load(userptr, "vkEnumerateInstanceExtensionProperties");
|
||||
glad_vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load(userptr, "vkEnumerateInstanceLayerProperties");
|
||||
glad_vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load(userptr, "vkEnumeratePhysicalDevices");
|
||||
glad_vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load(userptr, "vkFlushMappedMemoryRanges");
|
||||
glad_vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load(userptr, "vkFreeCommandBuffers");
|
||||
glad_vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load(userptr, "vkFreeDescriptorSets");
|
||||
glad_vkFreeMemory = (PFN_vkFreeMemory) load(userptr, "vkFreeMemory");
|
||||
glad_vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load(userptr, "vkGetBufferMemoryRequirements");
|
||||
glad_vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load(userptr, "vkGetDeviceMemoryCommitment");
|
||||
glad_vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load(userptr, "vkGetDeviceProcAddr");
|
||||
glad_vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load(userptr, "vkGetDeviceQueue");
|
||||
glad_vkGetEventStatus = (PFN_vkGetEventStatus) load(userptr, "vkGetEventStatus");
|
||||
glad_vkGetFenceStatus = (PFN_vkGetFenceStatus) load(userptr, "vkGetFenceStatus");
|
||||
glad_vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load(userptr, "vkGetImageMemoryRequirements");
|
||||
glad_vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load(userptr, "vkGetImageSparseMemoryRequirements");
|
||||
glad_vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load(userptr, "vkGetImageSubresourceLayout");
|
||||
glad_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load(userptr, "vkGetInstanceProcAddr");
|
||||
glad_vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load(userptr, "vkGetPhysicalDeviceFeatures");
|
||||
glad_vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load(userptr, "vkGetPhysicalDeviceFormatProperties");
|
||||
glad_vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load(userptr, "vkGetPhysicalDeviceImageFormatProperties");
|
||||
glad_vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load(userptr, "vkGetPhysicalDeviceMemoryProperties");
|
||||
glad_vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load(userptr, "vkGetPhysicalDeviceProperties");
|
||||
glad_vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties");
|
||||
glad_vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties");
|
||||
glad_vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load(userptr, "vkGetPipelineCacheData");
|
||||
glad_vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load(userptr, "vkGetQueryPoolResults");
|
||||
glad_vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load(userptr, "vkGetRenderAreaGranularity");
|
||||
glad_vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load(userptr, "vkInvalidateMappedMemoryRanges");
|
||||
glad_vkMapMemory = (PFN_vkMapMemory) load(userptr, "vkMapMemory");
|
||||
glad_vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load(userptr, "vkMergePipelineCaches");
|
||||
glad_vkQueueBindSparse = (PFN_vkQueueBindSparse) load(userptr, "vkQueueBindSparse");
|
||||
glad_vkQueueSubmit = (PFN_vkQueueSubmit) load(userptr, "vkQueueSubmit");
|
||||
glad_vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load(userptr, "vkQueueWaitIdle");
|
||||
glad_vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load(userptr, "vkResetCommandBuffer");
|
||||
glad_vkResetCommandPool = (PFN_vkResetCommandPool) load(userptr, "vkResetCommandPool");
|
||||
glad_vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load(userptr, "vkResetDescriptorPool");
|
||||
glad_vkResetEvent = (PFN_vkResetEvent) load(userptr, "vkResetEvent");
|
||||
glad_vkResetFences = (PFN_vkResetFences) load(userptr, "vkResetFences");
|
||||
glad_vkSetEvent = (PFN_vkSetEvent) load(userptr, "vkSetEvent");
|
||||
glad_vkUnmapMemory = (PFN_vkUnmapMemory) load(userptr, "vkUnmapMemory");
|
||||
glad_vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load(userptr, "vkUpdateDescriptorSets");
|
||||
glad_vkWaitForFences = (PFN_vkWaitForFences) load(userptr, "vkWaitForFences");
|
||||
}
|
||||
static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_VK_VERSION_1_1) return;
|
||||
vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load("vkBindBufferMemory2", userptr);
|
||||
vkBindImageMemory2 = (PFN_vkBindImageMemory2) load("vkBindImageMemory2", userptr);
|
||||
vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load("vkCmdDispatchBase", userptr);
|
||||
vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load("vkCmdSetDeviceMask", userptr);
|
||||
vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load("vkCreateDescriptorUpdateTemplate", userptr);
|
||||
vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load("vkCreateSamplerYcbcrConversion", userptr);
|
||||
vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load("vkDestroyDescriptorUpdateTemplate", userptr);
|
||||
vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load("vkDestroySamplerYcbcrConversion", userptr);
|
||||
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
|
||||
vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load("vkEnumeratePhysicalDeviceGroups", userptr);
|
||||
vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load("vkGetBufferMemoryRequirements2", userptr);
|
||||
vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load("vkGetDescriptorSetLayoutSupport", userptr);
|
||||
vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load("vkGetDeviceGroupPeerMemoryFeatures", userptr);
|
||||
vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load("vkGetDeviceQueue2", userptr);
|
||||
vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load("vkGetImageMemoryRequirements2", userptr);
|
||||
vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load("vkGetImageSparseMemoryRequirements2", userptr);
|
||||
vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load("vkGetPhysicalDeviceExternalBufferProperties", userptr);
|
||||
vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load("vkGetPhysicalDeviceExternalFenceProperties", userptr);
|
||||
vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load("vkGetPhysicalDeviceExternalSemaphoreProperties", userptr);
|
||||
vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load("vkGetPhysicalDeviceFeatures2", userptr);
|
||||
vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load("vkGetPhysicalDeviceFormatProperties2", userptr);
|
||||
vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load("vkGetPhysicalDeviceImageFormatProperties2", userptr);
|
||||
vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load("vkGetPhysicalDeviceMemoryProperties2", userptr);
|
||||
vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load("vkGetPhysicalDeviceProperties2", userptr);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load("vkGetPhysicalDeviceQueueFamilyProperties2", userptr);
|
||||
vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load("vkGetPhysicalDeviceSparseImageFormatProperties2", userptr);
|
||||
vkTrimCommandPool = (PFN_vkTrimCommandPool) load("vkTrimCommandPool", userptr);
|
||||
vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load("vkUpdateDescriptorSetWithTemplate", userptr);
|
||||
glad_vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load(userptr, "vkBindBufferMemory2");
|
||||
glad_vkBindImageMemory2 = (PFN_vkBindImageMemory2) load(userptr, "vkBindImageMemory2");
|
||||
glad_vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load(userptr, "vkCmdDispatchBase");
|
||||
glad_vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load(userptr, "vkCmdSetDeviceMask");
|
||||
glad_vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load(userptr, "vkCreateDescriptorUpdateTemplate");
|
||||
glad_vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load(userptr, "vkCreateSamplerYcbcrConversion");
|
||||
glad_vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load(userptr, "vkDestroyDescriptorUpdateTemplate");
|
||||
glad_vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load(userptr, "vkDestroySamplerYcbcrConversion");
|
||||
glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion");
|
||||
glad_vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load(userptr, "vkEnumeratePhysicalDeviceGroups");
|
||||
glad_vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load(userptr, "vkGetBufferMemoryRequirements2");
|
||||
glad_vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load(userptr, "vkGetDescriptorSetLayoutSupport");
|
||||
glad_vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load(userptr, "vkGetDeviceGroupPeerMemoryFeatures");
|
||||
glad_vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load(userptr, "vkGetDeviceQueue2");
|
||||
glad_vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load(userptr, "vkGetImageMemoryRequirements2");
|
||||
glad_vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load(userptr, "vkGetImageSparseMemoryRequirements2");
|
||||
glad_vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load(userptr, "vkGetPhysicalDeviceExternalBufferProperties");
|
||||
glad_vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load(userptr, "vkGetPhysicalDeviceExternalFenceProperties");
|
||||
glad_vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load(userptr, "vkGetPhysicalDeviceExternalSemaphoreProperties");
|
||||
glad_vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load(userptr, "vkGetPhysicalDeviceFeatures2");
|
||||
glad_vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load(userptr, "vkGetPhysicalDeviceFormatProperties2");
|
||||
glad_vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceImageFormatProperties2");
|
||||
glad_vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load(userptr, "vkGetPhysicalDeviceMemoryProperties2");
|
||||
glad_vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load(userptr, "vkGetPhysicalDeviceProperties2");
|
||||
glad_vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties2");
|
||||
glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties2");
|
||||
glad_vkTrimCommandPool = (PFN_vkTrimCommandPool) load(userptr, "vkTrimCommandPool");
|
||||
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) {
|
||||
if(!GLAD_VK_EXT_debug_report) return;
|
||||
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load("vkCreateDebugReportCallbackEXT", userptr);
|
||||
vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load("vkDebugReportMessageEXT", userptr);
|
||||
vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load("vkDestroyDebugReportCallbackEXT", userptr);
|
||||
glad_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load(userptr, "vkCreateDebugReportCallbackEXT");
|
||||
glad_vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load(userptr, "vkDebugReportMessageEXT");
|
||||
glad_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load(userptr, "vkDestroyDebugReportCallbackEXT");
|
||||
}
|
||||
static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_VK_KHR_surface) return;
|
||||
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load("vkDestroySurfaceKHR", userptr);
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr);
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr);
|
||||
glad_vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load(userptr, "vkDestroySurfaceKHR");
|
||||
glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load(userptr, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
|
||||
glad_vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load(userptr, "vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||
glad_vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load(userptr, "vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||
glad_vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load(userptr, "vkGetPhysicalDeviceSurfaceSupportKHR");
|
||||
}
|
||||
static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_VK_KHR_swapchain) return;
|
||||
vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load("vkAcquireNextImage2KHR", userptr);
|
||||
vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load("vkAcquireNextImageKHR", userptr);
|
||||
vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load("vkCreateSwapchainKHR", userptr);
|
||||
vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load("vkDestroySwapchainKHR", userptr);
|
||||
vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr);
|
||||
vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load("vkGetDeviceGroupSurfacePresentModesKHR", userptr);
|
||||
vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load("vkGetPhysicalDevicePresentRectanglesKHR", userptr);
|
||||
vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load("vkGetSwapchainImagesKHR", userptr);
|
||||
vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load("vkQueuePresentKHR", userptr);
|
||||
glad_vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load(userptr, "vkAcquireNextImage2KHR");
|
||||
glad_vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load(userptr, "vkAcquireNextImageKHR");
|
||||
glad_vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load(userptr, "vkCreateSwapchainKHR");
|
||||
glad_vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load(userptr, "vkDestroySwapchainKHR");
|
||||
glad_vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load(userptr, "vkGetDeviceGroupPresentCapabilitiesKHR");
|
||||
glad_vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load(userptr, "vkGetDeviceGroupSurfacePresentModesKHR");
|
||||
glad_vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load(userptr, "vkGetPhysicalDevicePresentRectanglesKHR");
|
||||
glad_vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load(userptr, "vkGetSwapchainImagesKHR");
|
||||
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 instance_extension_count = 0;
|
||||
uint32_t device_extension_count = 0;
|
||||
uint32_t max_extension_count;
|
||||
uint32_t total_extension_count;
|
||||
char **extensions;
|
||||
VkExtensionProperties *ext_properties;
|
||||
uint32_t max_extension_count = 0;
|
||||
uint32_t total_extension_count = 0;
|
||||
char **extensions = NULL;
|
||||
VkExtensionProperties *ext_properties = NULL;
|
||||
VkResult result;
|
||||
|
||||
if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) {
|
||||
if (glad_vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && glad_vkEnumerateDeviceExtensionProperties == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
|
||||
result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
|
||||
if (result != VK_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
? instance_extension_count : device_extension_count;
|
||||
|
||||
ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties));
|
||||
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) {
|
||||
free((void*) ext_properties);
|
||||
return 0;
|
||||
goto glad_vk_get_extensions_error;
|
||||
}
|
||||
|
||||
extensions = (char**) calloc(total_extension_count, sizeof(char*));
|
||||
if (extensions == NULL) {
|
||||
free((void*) ext_properties);
|
||||
return 0;
|
||||
goto glad_vk_get_extensions_error;
|
||||
}
|
||||
|
||||
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;
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
for (i = 0; i < instance_extension_count; ++i) {
|
||||
free((void*) extensions[i]);
|
||||
}
|
||||
free(extensions);
|
||||
return 0;
|
||||
goto glad_vk_get_extensions_error;
|
||||
}
|
||||
|
||||
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;
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -487,6 +605,16 @@ static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *o
|
||||
*out_extensions = extensions;
|
||||
|
||||
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) {
|
||||
@@ -503,7 +631,7 @@ static int glad_vk_has_extension(const char *name, uint32_t extension_count, cha
|
||||
uint32_t 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;
|
||||
}
|
||||
}
|
||||
@@ -511,7 +639,7 @@ static int glad_vk_has_extension(const char *name, uint32_t extension_count, cha
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
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_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
|
||||
|
||||
(void) glad_vk_has_extension;
|
||||
|
||||
glad_vk_free_extensions(extension_count, extensions);
|
||||
|
||||
return 1;
|
||||
@@ -534,11 +665,11 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
|
||||
int minor = 0;
|
||||
|
||||
#ifdef VK_VERSION_1_1
|
||||
if (vkEnumerateInstanceVersion != NULL) {
|
||||
if (glad_vkEnumerateInstanceVersion != NULL) {
|
||||
uint32_t version;
|
||||
VkResult result;
|
||||
|
||||
result = vkEnumerateInstanceVersion(&version);
|
||||
result = glad_vkEnumerateInstanceVersion(&version);
|
||||
if (result == VK_SUCCESS) {
|
||||
major = (int) VK_VERSION_MAJOR(version);
|
||||
minor = (int) VK_VERSION_MINOR(version);
|
||||
@@ -546,9 +677,9 @@ static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) {
|
||||
if (physical_device != NULL && glad_vkGetPhysicalDeviceProperties != NULL) {
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(physical_device, &properties);
|
||||
glad_vkGetPhysicalDeviceProperties(physical_device, &properties);
|
||||
|
||||
major = (int) VK_VERSION_MAJOR(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_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);
|
||||
}
|
||||
@@ -564,7 +697,7 @@ int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc
|
||||
int version;
|
||||
|
||||
#ifdef VK_VERSION_1_1
|
||||
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
|
||||
glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion");
|
||||
#endif
|
||||
version = glad_vk_find_core_vulkan( physical_device);
|
||||
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_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;
|
||||
glad_vk_load_VK_EXT_debug_report(load, userptr);
|
||||
@@ -590,4 +725,9 @@ int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Vendored
+803
-127
File diff suppressed because it is too large
Load Diff
@@ -23,13 +23,12 @@ Questions about how to use GLFW should be asked either in the [support
|
||||
section](https://discourse.glfw.org/c/support) of the forum, under the [Stack
|
||||
Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
|
||||
Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
|
||||
Stack Exchange or in the IRC channel `#glfw` on
|
||||
[Libera.Chat](https://libera.chat/).
|
||||
Stack Exchange.
|
||||
|
||||
Questions about the design or implementation of GLFW or about future plans
|
||||
should be asked in the [dev section](https://discourse.glfw.org/c/dev) of the
|
||||
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
|
||||
questions without first checking with a maintainer.
|
||||
forum. Please don't open a GitHub issue to discuss design questions without
|
||||
first checking with a maintainer.
|
||||
|
||||
|
||||
## Reporting a bug
|
||||
@@ -351,8 +350,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
|
||||
[experimental branch](https://github.com/glfw/glfw/branches/all).
|
||||
|
||||
__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
|
||||
__There is no preferred patch size__. A one-character change is just as welcome
|
||||
as one adding a thousand lines, if that is the appropriate size for the
|
||||
feature.
|
||||
|
||||
In addition to the code, a complete feature includes:
|
||||
|
||||
+1849
-940
File diff suppressed because it is too large
Load Diff
+1
-2
@@ -4,8 +4,7 @@ See the [latest documentation](https://www.glfw.org/docs/latest/) for tutorials,
|
||||
guides and the API reference.
|
||||
|
||||
If you have questions about using GLFW, we have a
|
||||
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||
[Libera.Chat](https://libera.chat/).
|
||||
[forum](https://discourse.glfw.org/).
|
||||
|
||||
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||
Please check the [contribution
|
||||
|
||||
+96
-19
@@ -26,7 +26,7 @@ GLFW.
|
||||
@endcode
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
headers in any order.
|
||||
|
||||
@@ -160,20 +160,94 @@ A good general introduction to linking is
|
||||
David Drysdale.
|
||||
|
||||
|
||||
@subsection build_link_win32 With MinGW or Visual C++ on Windows
|
||||
@subsection build_link_win32 With Visual C++ and GLFW binaries
|
||||
|
||||
The static version of the GLFW library is named `glfw3`. When using this
|
||||
version, it is also necessary to link with some libraries that GLFW uses.
|
||||
If you are using a downloaded
|
||||
[binary archive](https://www.glfw.org/download.html), first make sure you have
|
||||
the archive matching the architecture you are building for (32-bit or 64-bit),
|
||||
or you will get link errors. Also make sure you are using the binaries for your
|
||||
version of Visual C++ or you may get other link errors.
|
||||
|
||||
When using MinGW to link an application with the static version of GLFW, you
|
||||
must also explicitly link with `gdi32`. Other toolchains including MinGW-w64
|
||||
include it in the set of default libraries along with other dependencies like
|
||||
`user32` and `kernel32`.
|
||||
There are two version of the static GLFW library in the binary archive, because
|
||||
it needs to use the same base run-time library variant as the rest of your
|
||||
executable.
|
||||
|
||||
The link library for the GLFW DLL is named `glfw3dll`. When compiling an
|
||||
application that uses the DLL version of GLFW, you need to define the @ref
|
||||
GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done
|
||||
either with a compiler switch or by defining it in your source code.
|
||||
One is named `glfw3.lib` and is for projects with the _Runtime Library_ project
|
||||
option set to _Multi-threaded DLL_ or _Multi-threaded Debug DLL_. The other is
|
||||
named `glfw3_mt.lib` and is for projects with _Runtime Library_ set to
|
||||
_Multi-threaded_ or _Multi-threaded Debug_. To use the static GLFW library you
|
||||
will need to add `path/to/glfw3.lib` or `path/to/glfw3_mt.lib` to the
|
||||
_Additional Dependencies_ project option.
|
||||
|
||||
If you compiled a GLFW static library yourself then there will only be one,
|
||||
named `glfw3.lib`, and you have to make sure the run-time library variant
|
||||
matches.
|
||||
|
||||
The DLL version of the GLFW library is named `glfw3.dll`, but you will be
|
||||
linking against the `glfw3dll.lib` link library. To use the DLL you will need
|
||||
to add `path/to/glfw3dll.lib` to the _Additional Dependencies_ project option.
|
||||
All of its dependencies are already listed there by default, but when building
|
||||
with the DLL version of GLFW, you also need to define the @ref GLFW_DLL. This
|
||||
can be done either in the _Preprocessor Definitions_ project option or by
|
||||
defining it in your source code before including the GLFW header.
|
||||
|
||||
@code
|
||||
#define GLFW_DLL
|
||||
#include <GLFW/glfw3.h>
|
||||
@endcode
|
||||
|
||||
All link-time dependencies for GLFW are already listed in the _Additional
|
||||
Dependencies_ option by default.
|
||||
|
||||
|
||||
@subsection build_link_mingw With MinGW-w64 and GLFW binaries
|
||||
|
||||
This is intended for building a program from the command-line or by writing
|
||||
a makefile, on Windows with [MinGW-w64](https://www.mingw-w64.org/) and GLFW
|
||||
binaries. These can be from a downloaded and extracted
|
||||
[binary archive](https://www.glfw.org/download.html) or by compiling GLFW
|
||||
yourself. The paths below assume a binary archive is used.
|
||||
|
||||
If you are using a downloaded binary archive, first make sure you have the
|
||||
archive matching the architecture you are building for (32-bit or 64-bit) or you
|
||||
will get link errors.
|
||||
|
||||
Note that the order of source files and libraries matter for GCC. Dependencies
|
||||
must be listed after the files that depend on them. Any source files that
|
||||
depend on GLFW must be listed before the GLFW library. GLFW in turn depends on
|
||||
`gdi32` and must be listed before it.
|
||||
|
||||
If you are using the static version of the GLFW library, which is named
|
||||
`libglfw3.a`, do:
|
||||
|
||||
@code{.sh}
|
||||
gcc -o myprog myprog.c -I path/to/glfw/include path/to/glfw/lib-mingw-w64/libglfw3.a -lgdi32
|
||||
@endcode
|
||||
|
||||
If you are using the DLL version of the GLFW library, which is named
|
||||
`glfw3.dll`, you will need to use the `libglfw3dll.a` link library.
|
||||
|
||||
@code{.sh}
|
||||
gcc -o myprog myprog.c -I path/to/glfw/include path/to/glfw/lib-mingw-w64/libglfw3dll.a -lgdi32
|
||||
@endcode
|
||||
|
||||
The resulting executable will need to find `glfw3.dll` to run, typically by
|
||||
keeping both files in the same directory.
|
||||
|
||||
When you are building with the DLL version of GLFW, you will also need to define
|
||||
the @ref GLFW_DLL macro. This can be done in your source files, as long as it
|
||||
done before including the GLFW header:
|
||||
|
||||
@code
|
||||
#define GLFW_DLL
|
||||
#include <GLFW/glfw3.h>
|
||||
@endcode
|
||||
|
||||
It can also be done on the command-line:
|
||||
|
||||
@code{.sh}
|
||||
gcc -o myprog myprog.c -D GLFW_DLL -I path/to/glfw/include path/to/glfw/lib-mingw-w64/libglfw3dll.a -lgdi32
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection build_link_cmake_source With CMake and GLFW source
|
||||
@@ -271,7 +345,10 @@ target_link_libraries(myapp OpenGL::GL)
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
||||
@subsection build_link_pkgconfig With pkg-config and GLFW binaries on Unix
|
||||
|
||||
This is intended for building a program from the command-line or by writing
|
||||
a makefile, on macOS or any Unix-like system like Linux, FreeBSD and Cygwin.
|
||||
|
||||
GLFW supports [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/),
|
||||
and the `glfw3.pc` pkg-config file is generated when the GLFW library is built
|
||||
@@ -322,13 +399,13 @@ OpenGL and IOKit frameworks to the project as dependencies. They can all be
|
||||
found in `/System/Library/Frameworks`.
|
||||
|
||||
|
||||
@subsection build_link_osx With command-line on macOS
|
||||
@subsection build_link_osx With command-line or makefile on macOS
|
||||
|
||||
It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when
|
||||
building from the command line on macOS. That way you will get any new
|
||||
dependencies added automatically. If you still wish to build manually, you need
|
||||
to add the required frameworks and libraries to your command-line yourself using
|
||||
the `-l` and `-framework` switches.
|
||||
using installed GLFW binaries from the command line on macOS. That way you will
|
||||
get any new dependencies added automatically. If you still wish to build
|
||||
manually, you need to add the required frameworks and libraries to your
|
||||
command-line yourself using the `-l` and `-framework` switches.
|
||||
|
||||
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
|
||||
|
||||
|
||||
+19
-8
@@ -85,6 +85,13 @@ transparent window framebuffers. If the running X server does not support this
|
||||
extension or there is no running compositing manager, the
|
||||
`GLFW_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
|
||||
|
||||
GLFW uses both the Xcursor extension and the freedesktop cursor conventions to
|
||||
provide an expanded set of standard cursor shapes. If the running X server does
|
||||
not support this extension or the current cursor theme does not support the
|
||||
conventions, the `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR` and
|
||||
`GLFW_NOT_ALLOWED_CURSOR` shapes will not be available and other shapes may use
|
||||
legacy images.
|
||||
|
||||
|
||||
@section compat_wayland Wayland protocols and IPC standards
|
||||
|
||||
@@ -104,11 +111,7 @@ has been configured in the compositor.
|
||||
GLFW uses the [xdg-shell
|
||||
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
|
||||
wayland-protocols 1.12, and mandatory at build time. If the running compositor
|
||||
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.
|
||||
wayland-protocols 1.12, and mandatory at build time.
|
||||
|
||||
GLFW uses the [relative pointer
|
||||
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml)
|
||||
@@ -126,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
|
||||
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
|
||||
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
|
||||
@@ -150,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
|
||||
`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.
|
||||
|
||||
GLFW uses the `GLX_ARB_multisample` extension to create contexts with
|
||||
@@ -219,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.
|
||||
|
||||
GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB`
|
||||
extensions to provide support for sRGB framebuffers. Where both of these
|
||||
extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
|
||||
extensions to provide support for sRGB framebuffers. When both of these
|
||||
extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
|
||||
|
||||
|
||||
@section compat_osx OpenGL on macOS
|
||||
|
||||
+13
-10
@@ -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
|
||||
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.
|
||||
|
||||
@code{.sh}
|
||||
@@ -68,8 +68,10 @@ install the `xorgproto` package.
|
||||
pkg install xorgproto
|
||||
@endcode
|
||||
|
||||
On Cygwin the `xorgproto` package in the Devel section of the GUI installer will
|
||||
install the headers and other development related files for all of X11.
|
||||
On Cygwin the `libXcursor-devel`, `libXi-devel`, `libXinerama-devel`,
|
||||
`libXrandr-devel` and `libXrender-devel` packages in the Libs section of the GUI
|
||||
installer will install all the headers and other development related files GLFW
|
||||
requires for X11.
|
||||
|
||||
Once you have the required depdendencies, move on to @ref compile_generate.
|
||||
|
||||
@@ -80,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
|
||||
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.
|
||||
These will pull in all other dependencies.
|
||||
|
||||
@code{.sh}
|
||||
sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules
|
||||
@@ -94,11 +97,11 @@ On Fedora and derivatives like Red Hat you will need the `wayland-devel`,
|
||||
sudo dnf install wayland-devel libxkbcommon-devel wayland-protocols-devel extra-cmake-modules
|
||||
@endcode
|
||||
|
||||
On FreeBSD you will need the `wayland`, `libxkbcommon`, `wayland-protocols` and
|
||||
`kf5-extra-cmake-modules` packages.
|
||||
On FreeBSD you will need the `wayland`, `libxkbcommon`, `wayland-protocols`,
|
||||
`evdev-proto` and `kf5-extra-cmake-modules` packages.
|
||||
|
||||
@code{.sh}
|
||||
pkg install wayland libxkbcommon wayland-protocols kf5-extra-cmake-modules
|
||||
pkg install wayland libxkbcommon wayland-protocols evdev-proto kf5-extra-cmake-modules
|
||||
@endcode
|
||||
|
||||
Once you have the required depdendencies, move on to @ref compile_generate.
|
||||
@@ -135,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
|
||||
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
|
||||
GLFW section of the variable list, then apply the new value as described above.
|
||||
|
||||
@@ -169,7 +172,7 @@ flag.
|
||||
cmake -S path/to/glfw -B path/to/build -G Xcode
|
||||
@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.
|
||||
|
||||
@code{.sh}
|
||||
@@ -325,7 +328,7 @@ For more details see the
|
||||
@section compile_manual Compiling GLFW manually
|
||||
|
||||
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
|
||||
being compiled for and also has optional, platform-specific ones for various
|
||||
features.
|
||||
|
||||
+7
-6
@@ -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
|
||||
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
|
||||
@@ -92,9 +92,10 @@ creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
|
||||
@subsection context_less Windows without contexts
|
||||
|
||||
You can disable context creation by setting the
|
||||
[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`. Windows
|
||||
without contexts must not be passed to @ref glfwMakeContextCurrent or @ref
|
||||
glfwSwapBuffers.
|
||||
[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`.
|
||||
|
||||
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
|
||||
@@ -193,7 +194,7 @@ it suppresses the development environment's OpenGL or OpenGL ES header.
|
||||
#include <GLFW/glfw3.h>
|
||||
@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
|
||||
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
|
||||
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
|
||||
[context hints](@ref window_hints_ctx). If your needs are more complex, you can
|
||||
|
||||
+40
-19
@@ -24,7 +24,7 @@ All input callbacks receive a window handle. By using the
|
||||
or objects from your callbacks.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key
|
||||
will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example
|
||||
_E-mail_ and _Play_ keys.
|
||||
The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. Events with
|
||||
`GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press. Most
|
||||
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.
|
||||
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.
|
||||
You can query the scancode for any [named key](@ref keys) on the current
|
||||
platform with @ref glfwGetKeyScancode.
|
||||
You can query the scancode for any [key token](@ref keys) supported on the
|
||||
current platform with @ref glfwGetKeyScancode.
|
||||
|
||||
@code
|
||||
const int scancode = glfwGetKeyScancode(GLFW_KEY_X);
|
||||
set_key_mapping(scancode, swap_weapons);
|
||||
@endcode
|
||||
|
||||
The last reported state for every [named key](@ref keys) is also saved in
|
||||
per-window state arrays that can be polled with @ref glfwGetKey.
|
||||
The last reported state for every physical key with a [key token](@ref keys) is
|
||||
also saved in per-window state arrays that can be polled with @ref glfwGetKey.
|
||||
|
||||
@code
|
||||
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`.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
The `GLFW_KEY_LAST` constant holds the highest value of any
|
||||
[named key](@ref keys).
|
||||
[key token](@ref keys).
|
||||
|
||||
|
||||
@subsection input_char Text input
|
||||
|
||||
GLFW supports text input in the form of a stream of
|
||||
[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
|
||||
layouts and modifier keys and supports composing characters using
|
||||
operating system text input system. Unlike key input, text input is affected by
|
||||
keyboard layouts and modifier keys and supports composing characters using
|
||||
[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.
|
||||
|
||||
@@ -370,15 +387,18 @@ sequential rows, starting from the top-left corner.
|
||||
@subsubsection cursor_standard Standard cursor creation
|
||||
|
||||
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
|
||||
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
|
||||
GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
|
||||
@endcode
|
||||
|
||||
These cursor objects behave in the exact same way as those created with @ref
|
||||
glfwCreateCursor except that the system cursor theme provides the actual image.
|
||||
|
||||
A few of these shapes are not available everywhere. If a shape is unavailable,
|
||||
`NULL` is returned. See @ref glfwCreateStandardCursor for details.
|
||||
|
||||
|
||||
@subsubsection cursor_destruction Cursor destruction
|
||||
|
||||
@@ -475,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`.
|
||||
|
||||
Mouse button states for [named buttons](@ref buttons) are also saved in
|
||||
per-window state arrays that can be polled with @ref glfwGetMouseButton.
|
||||
The last reported state for every [supported mouse button](@ref buttons) is also
|
||||
saved in per-window state arrays that can be polled with @ref
|
||||
glfwGetMouseButton.
|
||||
|
||||
@code
|
||||
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||
@@ -509,7 +530,7 @@ had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
|
||||
otherwise it will remain `GLFW_PRESS`.
|
||||
|
||||
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
|
||||
@@ -818,7 +839,7 @@ The second value is always the human-readable name of the gamepad.
|
||||
All subsequent values are in the form `<field>:<value>` and describe the layout
|
||||
of the mapping. These fields may not all be present and may occur in any order.
|
||||
|
||||
The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
|
||||
The button fields are `a`, `b`, `x`, `y`, `back`, `start`, `guide`, `dpup`,
|
||||
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
|
||||
`rightstick`.
|
||||
|
||||
|
||||
+32
-7
@@ -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.
|
||||
|
||||
|
||||
@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
|
||||
|
||||
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_COCOA_CHDIR_RESOURCES | `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
|
||||
@@ -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
|
||||
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
|
||||
library was not initialized or had already been terminated, it return
|
||||
library was not initialized or had already been terminated, it returns
|
||||
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
|
||||
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
|
||||
not be considered a bug.
|
||||
|
||||
|
||||
@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.
|
||||
|
||||
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
|
||||
- Any additional options or APIs
|
||||
|
||||
For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL
|
||||
back ends, the version string may look something like this:
|
||||
For example, when compiling GLFW 3.3.9 with MinGW for Windows, may result in
|
||||
a version string like this:
|
||||
|
||||
@code
|
||||
3.0.0 Win32 WGL MinGW
|
||||
3.3.9 Win32 WGL EGL OSMesa MinGW
|
||||
@endcode
|
||||
|
||||
*/
|
||||
|
||||
+2
-2
@@ -138,7 +138,7 @@ glfwGetMonitorPhysicalSize(monitor, &width_mm, &height_mm);
|
||||
@endcode
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ To experiment with gamma correction via the @ref glfwSetGamma function, run the
|
||||
`gamma` test program.
|
||||
|
||||
@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
|
||||
produce the default (usually sRGB-like) behavior.
|
||||
|
||||
|
||||
+3
-3
@@ -243,7 +243,7 @@ while (!glfwWindowShouldClose(window))
|
||||
@endcode
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
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
|
||||
of your program has.
|
||||
of your program have.
|
||||
|
||||
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
|
||||
|
||||
@@ -37,6 +37,16 @@ SDK](https://vulkan.lunarg.com/).
|
||||
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
|
||||
|
||||
GLFW now provides content scales for windows and monitors, i.e. the ratio
|
||||
@@ -306,6 +316,25 @@ GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off
|
||||
(the Transparency setting under Personalization > Window Color).
|
||||
|
||||
|
||||
@subsubsection emptyevents_33 Empty events on X11 no longer roundtrip to server
|
||||
|
||||
Starting with GLFW 3.3.7, events posted with @ref glfwPostEmptyEvent now use a separate
|
||||
unnamed pipe instead of sending an X11 client event to the helper window.
|
||||
|
||||
|
||||
@subsubsection wayland_alpha_33 Framebuffer 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
|
||||
|
||||
@subsubsection charmods_callback_33 Character with modifiers callback
|
||||
@@ -372,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.
|
||||
|
||||
|
||||
@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
|
||||
|
||||
The experimental Mir support has been completely removed as the Mir project has
|
||||
@@ -417,6 +453,9 @@ Use Wayland or X11 instead.
|
||||
- @ref GLFWwindowmaximizefun
|
||||
- @ref GLFWwindowcontentscalefun
|
||||
- @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
|
||||
|
||||
+1
-5
@@ -144,10 +144,6 @@ if (!window)
|
||||
}
|
||||
@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.
|
||||
|
||||
@code
|
||||
@@ -233,7 +229,7 @@ events as described below.
|
||||
@subsection quick_render Rendering with OpenGL
|
||||
|
||||
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`.
|
||||
|
||||
@code
|
||||
|
||||
+11
-4
@@ -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
|
||||
Vulkan loader will then be a compile-time error.
|
||||
|
||||
@macos Because the Vulkan loader and ICD are not installed globally on macOS,
|
||||
you need to set up the application bundle according to the LunarG SDK
|
||||
documentation. This is explained in more detail in the
|
||||
@macos To make your application be redistributable you will need to set up the
|
||||
application bundle according to the LunarG SDK documentation. This is explained
|
||||
in more detail in the
|
||||
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
|
||||
glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
|
||||
@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
|
||||
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
|
||||
`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
|
||||
|
||||
|
||||
+2
-1
@@ -471,7 +471,8 @@ should also declare this in its `Info.plist` by setting the
|
||||
@anchor GLFW_X11_CLASS_NAME_hint
|
||||
@anchor GLFW_X11_INSTANCE_NAME_hint
|
||||
__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.
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This is an example program for the GLFW library
|
||||
//
|
||||
// The program uses a "split window" view, rendering four views of the
|
||||
// same scene in one window (e.g. uesful for 3D modelling software). This
|
||||
// same scene in one window (e.g. useful for 3D modelling software). This
|
||||
// demo uses scissors to separate the four different rendering areas from
|
||||
// each other.
|
||||
//
|
||||
|
||||
+201
-70
@@ -262,13 +262,12 @@ extern "C" {
|
||||
/* We are building GLFW as a Win32 DLL */
|
||||
#define GLFWAPI __declspec(dllexport)
|
||||
#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)
|
||||
#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")))
|
||||
#else
|
||||
/* We are building or calling GLFW as a static library */
|
||||
#define GLFWAPI
|
||||
#endif
|
||||
|
||||
@@ -299,7 +298,7 @@ extern "C" {
|
||||
* release is made that does not contain any API changes.
|
||||
* @ingroup init
|
||||
*/
|
||||
#define GLFW_VERSION_REVISION 5
|
||||
#define GLFW_VERSION_REVISION 10
|
||||
/*! @} */
|
||||
|
||||
/*! @brief One.
|
||||
@@ -362,10 +361,15 @@ extern "C" {
|
||||
#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_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
|
||||
|
||||
/*! @ingroup input
|
||||
*/
|
||||
#define GLFW_KEY_UNKNOWN -1
|
||||
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup keys Keyboard keys
|
||||
* @brief Keyboard key IDs.
|
||||
/*! @defgroup keys Keyboard key tokens
|
||||
* @brief Keyboard key tokens.
|
||||
*
|
||||
* 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 */
|
||||
#define GLFW_KEY_SPACE 32
|
||||
#define GLFW_KEY_APOSTROPHE 39 /* ' */
|
||||
@@ -786,6 +787,17 @@ extern "C" {
|
||||
* @analysis Application programmer error. Fix the offending call.
|
||||
*/
|
||||
#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
|
||||
/*! @brief The specified cursor shape is not available.
|
||||
*
|
||||
* The specified standard cursor shape is not available, either because the
|
||||
* current system cursor theme does not provide it or because it is not
|
||||
* available on the platform.
|
||||
*
|
||||
* @analysis Platform or system settings limitation. Pick another
|
||||
* [standard cursor shape](@ref shapes) or create a
|
||||
* [custom cursor](@ref cursor_custom).
|
||||
*/
|
||||
#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
|
||||
/*! @} */
|
||||
|
||||
/*! @addtogroup window
|
||||
@@ -960,7 +972,7 @@ extern "C" {
|
||||
* and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
|
||||
/*! @brief Context client API revision number hint and attribute.
|
||||
/*! @brief Context client API revision number attribute.
|
||||
*
|
||||
* Context client API revision number
|
||||
* [attribute](@ref GLFW_CONTEXT_REVISION_attrib).
|
||||
@@ -1064,17 +1076,21 @@ extern "C" {
|
||||
#define GLFW_EGL_CONTEXT_API 0x00036002
|
||||
#define GLFW_OSMESA_CONTEXT_API 0x00036003
|
||||
|
||||
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
|
||||
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
|
||||
|
||||
/*! @defgroup shapes Standard cursor shapes
|
||||
* @brief Standard system cursor shapes.
|
||||
*
|
||||
* See [standard cursor creation](@ref cursor_standard) for how these are used.
|
||||
* These are the [standard cursor shapes](@ref cursor_standard) that can be
|
||||
* requested from the window system.
|
||||
*
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
|
||||
/*! @brief The regular arrow cursor shape.
|
||||
*
|
||||
* The regular arrow cursor.
|
||||
* The regular arrow cursor shape.
|
||||
*/
|
||||
#define GLFW_ARROW_CURSOR 0x00036001
|
||||
/*! @brief The text input I-beam cursor shape.
|
||||
@@ -1082,26 +1098,91 @@ extern "C" {
|
||||
* The text input I-beam cursor shape.
|
||||
*/
|
||||
#define GLFW_IBEAM_CURSOR 0x00036002
|
||||
/*! @brief The crosshair shape.
|
||||
/*! @brief The crosshair cursor shape.
|
||||
*
|
||||
* The crosshair shape.
|
||||
* The crosshair cursor shape.
|
||||
*/
|
||||
#define GLFW_CROSSHAIR_CURSOR 0x00036003
|
||||
/*! @brief The hand shape.
|
||||
/*! @brief The pointing hand cursor shape.
|
||||
*
|
||||
* The hand shape.
|
||||
* The pointing hand cursor shape.
|
||||
*/
|
||||
#define GLFW_HAND_CURSOR 0x00036004
|
||||
/*! @brief The horizontal resize arrow shape.
|
||||
#define GLFW_POINTING_HAND_CURSOR 0x00036004
|
||||
/*! @brief The horizontal resize/move arrow shape.
|
||||
*
|
||||
* The horizontal resize arrow shape.
|
||||
* The horizontal resize/move arrow shape. This is usually a horizontal
|
||||
* double-headed arrow.
|
||||
*/
|
||||
#define GLFW_HRESIZE_CURSOR 0x00036005
|
||||
/*! @brief The vertical resize arrow shape.
|
||||
#define GLFW_RESIZE_EW_CURSOR 0x00036005
|
||||
/*! @brief The vertical resize/move arrow shape.
|
||||
*
|
||||
* The vertical resize arrow shape.
|
||||
* The vertical resize/move shape. This is usually a vertical double-headed
|
||||
* arrow.
|
||||
*/
|
||||
#define GLFW_VRESIZE_CURSOR 0x00036006
|
||||
#define GLFW_RESIZE_NS_CURSOR 0x00036006
|
||||
/*! @brief The top-left to bottom-right diagonal resize/move arrow shape.
|
||||
*
|
||||
* The top-left to bottom-right diagonal resize/move shape. This is usually
|
||||
* a diagonal double-headed arrow.
|
||||
*
|
||||
* @note @macos This shape is provided by a private system API and may fail
|
||||
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*/
|
||||
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
|
||||
/*! @brief The top-right to bottom-left diagonal resize/move arrow shape.
|
||||
*
|
||||
* The top-right to bottom-left diagonal resize/move shape. This is usually
|
||||
* a diagonal double-headed arrow.
|
||||
*
|
||||
* @note @macos This shape is provided by a private system API and may fail
|
||||
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*/
|
||||
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
|
||||
/*! @brief The omni-directional resize/move cursor shape.
|
||||
*
|
||||
* The omni-directional resize cursor/move shape. This is usually either
|
||||
* a combined horizontal and vertical double-headed arrow or a grabbing hand.
|
||||
*/
|
||||
#define GLFW_RESIZE_ALL_CURSOR 0x00036009
|
||||
/*! @brief The operation-not-allowed shape.
|
||||
*
|
||||
* The operation-not-allowed shape. This is usually a circle with a diagonal
|
||||
* line through it.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*/
|
||||
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
|
||||
/*! @brief Legacy name for compatibility.
|
||||
*
|
||||
* This is an alias for compatibility with earlier versions.
|
||||
*/
|
||||
#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR
|
||||
/*! @brief Legacy name for compatibility.
|
||||
*
|
||||
* This is an alias for compatibility with earlier versions.
|
||||
*/
|
||||
#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR
|
||||
/*! @brief Legacy name for compatibility.
|
||||
*
|
||||
* This is an alias for compatibility with earlier versions.
|
||||
*/
|
||||
#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
|
||||
/*! @} */
|
||||
|
||||
#define GLFW_CONNECTED 0x00040001
|
||||
@@ -1124,6 +1205,11 @@ extern "C" {
|
||||
* macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint).
|
||||
*/
|
||||
#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
|
||||
@@ -2602,8 +2688,8 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
|
||||
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 Window creation will fail if the Microsoft GDI software
|
||||
* OpenGL implementation is the only one available.
|
||||
@@ -2808,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
|
||||
* count is zero.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified image data is copied before this function
|
||||
* returns.
|
||||
@@ -3219,18 +3305,15 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
|
||||
* previously restored. If the window is already iconified, this function does
|
||||
* nothing.
|
||||
*
|
||||
* If the specified window is a full screen window, the original monitor
|
||||
* resolution is restored until the window is restored.
|
||||
* If the specified window is a full screen window, GLFW restores the original
|
||||
* 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.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* 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.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
@@ -3250,8 +3333,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
|
||||
* (minimized) or maximized. If the window is already restored, this function
|
||||
* does nothing.
|
||||
*
|
||||
* If the specified window is a full screen window, the resolution chosen for
|
||||
* the window is restored on the selected monitor.
|
||||
* If the specified window is an iconified full screen window, its desired
|
||||
* video mode is set again for its monitor when the window is restored.
|
||||
*
|
||||
* @param[in] window The window to restore.
|
||||
*
|
||||
@@ -3312,6 +3395,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Because Wayland wants every frame of the desktop to be
|
||||
* complete, this function does not immediately make the window visible.
|
||||
* Instead it will become visible the next time the window framebuffer is
|
||||
* updated after this call.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_hide
|
||||
@@ -3514,6 +3602,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
|
||||
* errors. However, this function should not fail as long as it is passed
|
||||
* valid arguments and the library has been [initialized](@ref intro_init).
|
||||
*
|
||||
* @remark @wayland 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.
|
||||
*
|
||||
* @sa @ref window_attribs
|
||||
@@ -3547,11 +3638,15 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
|
||||
* @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark Calling @ref glfwGetWindowAttrib will always return the latest
|
||||
* value, even if that value is ignored by the current mode of the window.
|
||||
*
|
||||
* @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window
|
||||
* attribute is not supported. Setting this will emit @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_attribs
|
||||
@@ -3805,8 +3900,8 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @wayland The wl_shell protocol has no concept of iconification,
|
||||
* this callback will never be called when using this deprecated protocol.
|
||||
* @remark @wayland The XDG-shell protocol has no event for iconification, so
|
||||
* this callback will never be called.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@@ -4226,8 +4321,8 @@ GLFWAPI int glfwRawMouseMotionSupported(void);
|
||||
* @param[in] scancode The scancode of the key to query.
|
||||
* @return The UTF-8 encoded, layout-specific name of the key, or `NULL`.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark The contents of the returned string may change when a keyboard
|
||||
* layout change event is received.
|
||||
@@ -4249,15 +4344,18 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode);
|
||||
*
|
||||
* 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
|
||||
* method will return `-1`.
|
||||
* If the specified [key token](@ref keys) corresponds to a physical key not
|
||||
* 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).
|
||||
* @return The platform-specific scancode for the key, or `-1` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
* @param[in] key Any [key token](@ref keys).
|
||||
* @return The platform-specific scancode for the key, or `-1` if the key is
|
||||
* not supported on the current platform or an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_ENUM.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread.
|
||||
*
|
||||
@@ -4274,8 +4372,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
|
||||
*
|
||||
* This function returns the last state reported for the specified key to the
|
||||
* specified window. The returned state is one of `GLFW_PRESS` or
|
||||
* `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
|
||||
* the key callback.
|
||||
* `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback.
|
||||
*
|
||||
* 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
|
||||
@@ -4436,8 +4533,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
|
||||
* @return The handle of the created cursor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified image data is copied before this function
|
||||
* returns.
|
||||
@@ -4456,19 +4553,44 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
||||
|
||||
/*! @brief Creates a cursor with a standard shape.
|
||||
*
|
||||
* Returns a cursor with a [standard shape](@ref shapes), that can be set for
|
||||
* a window with @ref glfwSetCursor.
|
||||
* Returns a cursor with a standard shape, that can be set for a window with
|
||||
* @ref glfwSetCursor. The images for these cursors come from the system
|
||||
* cursor theme and their exact appearance will vary between platforms.
|
||||
*
|
||||
* Most of these shapes are guaranteed to exist on every supported platform but
|
||||
* a few may not be present. See the table below for details.
|
||||
*
|
||||
* Cursor shape | Windows | macOS | X11 | Wayland
|
||||
* ------------------------------ | ------- | ----- | ------ | -------
|
||||
* @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
|
||||
* @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
|
||||
* @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes
|
||||
* @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe<sup>2</sup> | Maybe<sup>2</sup>
|
||||
*
|
||||
* 1) This uses a private system API and may fail in the future.
|
||||
*
|
||||
* 2) This uses a newer standard that not all cursor themes support.
|
||||
*
|
||||
* If the requested shape is not available, this function emits a @ref
|
||||
* GLFW_CURSOR_UNAVAILABLE error and returns `NULL`.
|
||||
*
|
||||
* @param[in] shape One of the [standard shapes](@ref shapes).
|
||||
* @return A new cursor ready to use or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
* GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref cursor_object
|
||||
* @sa @ref cursor_standard
|
||||
* @sa @ref glfwCreateCursor
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
@@ -4542,9 +4664,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
||||
* [character callback](@ref glfwSetCharCallback) instead.
|
||||
*
|
||||
* 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 by the fact that the synthetic ones are generated after the focus
|
||||
* loss event has been processed, i.e. after the
|
||||
* events for all pressed keys with associated key tokens. You can tell these
|
||||
* events from user-generated events by the fact that the synthetic ones are
|
||||
* generated after the focus loss event has been processed, i.e. after the
|
||||
* [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
|
||||
*
|
||||
* The scancode of a key is specific to that platform or sometimes even to that
|
||||
@@ -5227,6 +5349,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string);
|
||||
* joystick is not present, does not have a mapping or an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected, the gamepad mappings are updated or the library is terminated.
|
||||
@@ -5316,8 +5440,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
|
||||
* @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
|
||||
* if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the next call to @ref
|
||||
@@ -5441,12 +5565,15 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
|
||||
* thread.
|
||||
*
|
||||
* 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
|
||||
* a single thread at a time and each thread can have only a single current
|
||||
* context at a time.
|
||||
* current on the calling thread. It can also detach the current context from
|
||||
* the calling thread without making a new one current by passing in `NULL`.
|
||||
*
|
||||
* When moving a context between threads, you must make it non-current on the
|
||||
* old thread before making it current on the new one.
|
||||
* A context must only be made current on a single thread at a time and each
|
||||
* thread can have only a single current context at a time. Making a 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.
|
||||
* On machines that support `GL_KHR_context_flush_control`, you can control
|
||||
@@ -5461,6 +5588,10 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
|
||||
* @param[in] window The window whose context to make current, or `NULL` to
|
||||
* 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
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
@@ -5711,9 +5842,6 @@ GLFWAPI int glfwVulkanSupported(void);
|
||||
* returned array, as it is an error to specify an extension more than once in
|
||||
* the `VkInstanceCreateInfo` struct.
|
||||
*
|
||||
* @remark @macos GLFW currently supports both the `VK_MVK_macos_surface` and
|
||||
* the newer `VK_EXT_metal_surface` extensions.
|
||||
*
|
||||
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is guaranteed to be valid only until the
|
||||
* library is terminated.
|
||||
@@ -5852,8 +5980,10 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
|
||||
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
|
||||
* eliminate almost all occurrences of these errors.
|
||||
*
|
||||
* @remark @macos This function currently only supports the
|
||||
* `VK_MVK_macos_surface` extension from MoltenVK.
|
||||
* @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the
|
||||
* `VK_MVK_macos_surface` extension as a fallback. The name of the selected
|
||||
* extension, if any, is included in the array returned by @ref
|
||||
* glfwGetRequiredInstanceExtensions.
|
||||
*
|
||||
* @remark @macos This function creates and sets a `CAMetalLayer` instance for
|
||||
* the window content view, which is required for MoltenVK to function.
|
||||
@@ -5894,6 +6024,7 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window
|
||||
*/
|
||||
#ifndef GLAPIENTRY
|
||||
#define GLAPIENTRY APIENTRY
|
||||
#define GLFW_GLAPIENTRY_DEFINED
|
||||
#endif
|
||||
|
||||
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
|
||||
|
||||
+77
-37
@@ -74,6 +74,16 @@ extern "C" {
|
||||
* and which platform-specific headers to include. It is then up your (by
|
||||
* definition platform-specific) code to handle which of these should be
|
||||
* 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,44 +91,71 @@ extern "C" {
|
||||
* System headers and types
|
||||
*************************************************************************/
|
||||
|
||||
#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
|
||||
// example to allow applications to correctly declare a GL_KHR_debug callback)
|
||||
// but windows.h assumes no one will define APIENTRY before it does
|
||||
#if defined(GLFW_APIENTRY_DEFINED)
|
||||
#undef APIENTRY
|
||||
#undef GLFW_APIENTRY_DEFINED
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
typedef void* id;
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
#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
|
||||
* example to allow applications to correctly declare a GL_KHR_debug callback)
|
||||
* but windows.h assumes no one will define APIENTRY before it does
|
||||
*/
|
||||
#if defined(GLFW_APIENTRY_DEFINED)
|
||||
#undef APIENTRY
|
||||
#undef GLFW_APIENTRY_DEFINED
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <objc/objc.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#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>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#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>
|
||||
#endif
|
||||
|
||||
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -475,6 +512,9 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
*
|
||||
* @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
|
||||
* synchronized.
|
||||
*
|
||||
|
||||
@@ -168,6 +168,7 @@ if (BUILD_SHARED_LIBS)
|
||||
# Add a suffix to the import library to avoid naming conflicts
|
||||
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
|
||||
endif()
|
||||
set (GLFW_LIB_NAME_SUFFIX "dll")
|
||||
|
||||
target_compile_definitions(glfw INTERFACE GLFW_DLL)
|
||||
elseif (APPLE)
|
||||
|
||||
+16
-6
@@ -251,7 +251,7 @@ static void createKeyTables(void)
|
||||
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
|
||||
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
|
||||
_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[0x71] = GLFW_KEY_F15;
|
||||
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
|
||||
@@ -475,18 +475,26 @@ void* _glfwLoadLocalVulkanLoaderNS(void)
|
||||
if (!bundle)
|
||||
return NULL;
|
||||
|
||||
CFURLRef url =
|
||||
CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib"));
|
||||
if (!url)
|
||||
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
|
||||
if (!frameworksUrl)
|
||||
return NULL;
|
||||
|
||||
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
|
||||
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
|
||||
if (!loaderUrl)
|
||||
{
|
||||
CFRelease(frameworksUrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char path[PATH_MAX];
|
||||
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);
|
||||
|
||||
CFRelease(url);
|
||||
CFRelease(loaderUrl);
|
||||
CFRelease(frameworksUrl);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -607,6 +615,8 @@ void _glfwPlatformTerminate(void)
|
||||
free(_glfw.ns.clipboardString);
|
||||
|
||||
_glfwTerminateNSGL();
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateOSMesa();
|
||||
_glfwTerminateJoysticksNS();
|
||||
|
||||
} // autoreleasepool
|
||||
|
||||
+16
-10
@@ -98,8 +98,7 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!js->present)
|
||||
return;
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||
@@ -114,7 +113,6 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
CFRelease(js->ns.hats);
|
||||
|
||||
_glfwFreeJoystick(js);
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
}
|
||||
|
||||
// Callback for user-initiated joystick addition
|
||||
@@ -139,6 +137,14 @@ static void matchCallback(void* context,
|
||||
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);
|
||||
buttons = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
hats = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
@@ -182,9 +188,6 @@ static void matchCallback(void* context,
|
||||
name[8], name[9], name[10]);
|
||||
}
|
||||
|
||||
CFArrayRef elements =
|
||||
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(elements); i++)
|
||||
{
|
||||
IOHIDElementRef native = (IOHIDElementRef)
|
||||
@@ -294,9 +297,9 @@ static void removeCallback(void* context,
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -392,7 +395,10 @@ void _glfwTerminateJoysticksNS(void)
|
||||
int 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);
|
||||
_glfw.ns.hidManager = NULL;
|
||||
@@ -470,7 +476,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
}
|
||||
}
|
||||
|
||||
return js->present;
|
||||
return js->connected;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
|
||||
+2
-6
@@ -58,7 +58,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
|
||||
io_service_t service;
|
||||
CFDictionaryRef info;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMainPortDefault,
|
||||
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
|
||||
IOServiceMatching("IODisplayConnect"),
|
||||
&it) != 0)
|
||||
{
|
||||
@@ -98,11 +98,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
|
||||
IOObjectRelease(it);
|
||||
|
||||
if (!service)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to find service port for display");
|
||||
return _glfw_strdup("Display");
|
||||
}
|
||||
|
||||
CFDictionaryRef names =
|
||||
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
|
||||
@@ -231,7 +227,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||
io_iterator_t it;
|
||||
io_service_t service;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMainPortDefault,
|
||||
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
|
||||
IOServiceMatching("IOFramebuffer"),
|
||||
&it) != 0)
|
||||
{
|
||||
|
||||
+12
-8
@@ -42,15 +42,10 @@ typedef void* id;
|
||||
#endif
|
||||
|
||||
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||
// SDK versions where one is unavailable or the other deprecated
|
||||
// We use the newer names in code and these macros to handle compatibility
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 120000
|
||||
#define kIOMainPortDefault kIOMasterPortDefault
|
||||
#endif
|
||||
// SDK versions where one is unavailable or deprecated.
|
||||
// We use the newer names in code and replace them with the older names if
|
||||
// the base SDK does not provide the newer names.
|
||||
|
||||
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||
// SDK versions where one is unavailable or the other deprecated
|
||||
// We use the newer names in code and these macros to handle compatibility
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||
#define NSEventMaskAny NSAnyEventMask
|
||||
@@ -69,6 +64,15 @@ typedef void* id;
|
||||
#define NSWindowStyleMaskTitled NSTitledWindowMask
|
||||
#endif
|
||||
|
||||
// NOTE: Many Cocoa dynamically linked constants have been renamed and we need
|
||||
// to build across SDK versions where one is unavailable or deprecated.
|
||||
// We use the newer names in code and replace them with the older names if
|
||||
// the deployment target is older than the newer names.
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
|
||||
#define NSPasteboardTypeURL NSURLPboardType
|
||||
#endif
|
||||
|
||||
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
|
||||
|
||||
|
||||
+166
-48
@@ -31,25 +31,9 @@
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
// Returns the style mask corresponding to the window settings
|
||||
//
|
||||
static NSUInteger getStyleMask(_GLFWwindow* window)
|
||||
{
|
||||
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
|
||||
|
||||
if (window->monitor || !window->decorated)
|
||||
styleMask |= NSWindowStyleMaskBorderless;
|
||||
else
|
||||
{
|
||||
styleMask |= NSWindowStyleMaskTitled |
|
||||
NSWindowStyleMaskClosable;
|
||||
|
||||
if (window->resizable)
|
||||
styleMask |= NSWindowStyleMaskResizable;
|
||||
}
|
||||
|
||||
return styleMask;
|
||||
}
|
||||
// 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
|
||||
#define NSWindowCollectionBehaviorFullScreenNone (1 << 9)
|
||||
|
||||
// Returns whether the cursor is in the content area of the specified window
|
||||
//
|
||||
@@ -325,10 +309,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
- (void)windowDidChangeOcclusionState:(NSNotification* )notification
|
||||
{
|
||||
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
|
||||
window->ns.occluded = GLFW_FALSE;
|
||||
else
|
||||
window->ns.occluded = GLFW_TRUE;
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
|
||||
if ([window->ns.object respondsToSelector:@selector(occlusionState)])
|
||||
{
|
||||
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
|
||||
window->ns.occluded = GLFW_FALSE;
|
||||
else
|
||||
window->ns.occluded = GLFW_TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -361,9 +350,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
markedText = [[NSMutableAttributedString alloc] init];
|
||||
|
||||
[self updateTrackingAreas];
|
||||
// NOTE: kUTTypeURL corresponds to NSPasteboardTypeURL but is available
|
||||
// on 10.7 without having been deprecated yet
|
||||
[self registerForDraggedTypes:@[(__bridge NSString*) kUTTypeURL]];
|
||||
[self registerForDraggedTypes:@[NSPasteboardTypeURL]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -811,9 +798,21 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
else
|
||||
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]
|
||||
initWithContentRect:contentRect
|
||||
styleMask:getStyleMask(window)
|
||||
styleMask:styleMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
|
||||
@@ -839,6 +838,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
NSWindowCollectionBehaviorManaged;
|
||||
[window->ns.object setCollectionBehavior:behavior];
|
||||
}
|
||||
else
|
||||
{
|
||||
const NSWindowCollectionBehavior behavior =
|
||||
NSWindowCollectionBehaviorFullScreenNone;
|
||||
[window->ns.object setCollectionBehavior:behavior];
|
||||
}
|
||||
|
||||
if (wndconfig->floating)
|
||||
[window->ns.object setLevel:NSFloatingWindowLevel];
|
||||
@@ -936,6 +941,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
@@ -943,6 +951,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
_glfwPlatformShowWindow(window);
|
||||
_glfwPlatformFocusWindow(window);
|
||||
acquireMonitor(window);
|
||||
|
||||
if (wndconfig->centerCursor)
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
_glfwPlatformShowWindow(window);
|
||||
if (wndconfig->focused)
|
||||
_glfwPlatformFocusWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@@ -1221,9 +1241,10 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
{
|
||||
const NSRect contentRect =
|
||||
NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height);
|
||||
const NSUInteger styleMask = [window->ns.object styleMask];
|
||||
const NSRect frameRect =
|
||||
[window->ns.object frameRectForContentRect:contentRect
|
||||
styleMask:getStyleMask(window)];
|
||||
styleMask:styleMask];
|
||||
|
||||
[window->ns.object setFrame:frameRect display:YES];
|
||||
}
|
||||
@@ -1240,7 +1261,27 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
// TODO: Solve this in a less terrible way
|
||||
_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];
|
||||
// HACK: Changing the style mask can cause the first responder to be cleared
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
@@ -1286,6 +1327,20 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
else
|
||||
[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];
|
||||
// HACK: Clearing NSWindowStyleMaskTitled resets and disables the window
|
||||
// title property but the miniwindow title property is unaffected
|
||||
@@ -1319,7 +1374,12 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
{
|
||||
@autoreleasepool {
|
||||
return [window->ns.object isZoomed];
|
||||
|
||||
if (window->resizable)
|
||||
return [window->ns.object isZoomed];
|
||||
else
|
||||
return GLFW_FALSE;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
@@ -1351,15 +1411,46 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
@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
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
@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];
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
@@ -1544,14 +1635,15 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
if (scancode < 0 || scancode > 0xff ||
|
||||
_glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||
if (scancode < 0 || scancode > 0xff)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int key = _glfw.ns.keycodes[scancode];
|
||||
if (key == GLFW_KEY_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
UInt32 deadKeyState = 0;
|
||||
UniChar characters[4];
|
||||
@@ -1642,23 +1734,49 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
cursor->ns.object = [NSCursor arrowCursor];
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
cursor->ns.object = [NSCursor IBeamCursor];
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
cursor->ns.object = [NSCursor crosshairCursor];
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
cursor->ns.object = [NSCursor pointingHandCursor];
|
||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||
cursor->ns.object = [NSCursor resizeLeftRightCursor];
|
||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||
cursor->ns.object = [NSCursor resizeUpDownCursor];
|
||||
SEL cursorSelector = NULL;
|
||||
|
||||
// HACK: Try to use a private message
|
||||
if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
cursorSelector = @selector(_windowResizeEastWestCursor);
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
cursorSelector = @selector(_windowResizeNorthSouthCursor);
|
||||
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||
cursorSelector = @selector(_windowResizeNorthWestSouthEastCursor);
|
||||
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||
cursorSelector = @selector(_windowResizeNorthEastSouthWestCursor);
|
||||
|
||||
if (cursorSelector && [NSCursor respondsToSelector:cursorSelector])
|
||||
{
|
||||
id object = [NSCursor performSelector:cursorSelector];
|
||||
if ([object isKindOfClass:[NSCursor class]])
|
||||
cursor->ns.object = object;
|
||||
}
|
||||
|
||||
if (!cursor->ns.object)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to retrieve standard cursor");
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
cursor->ns.object = [NSCursor arrowCursor];
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
cursor->ns.object = [NSCursor IBeamCursor];
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
cursor->ns.object = [NSCursor crosshairCursor];
|
||||
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||
cursor->ns.object = [NSCursor pointingHandCursor];
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
cursor->ns.object = [NSCursor resizeLeftRightCursor];
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
cursor->ns.object = [NSCursor resizeUpDownCursor];
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
cursor->ns.object = [NSCursor closedHandCursor];
|
||||
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||
cursor->ns.object = [NSCursor operationNotAllowedCursor];
|
||||
}
|
||||
|
||||
if (!cursor->ns.object)
|
||||
{
|
||||
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
|
||||
"Cocoa: Standard cursor shape unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
|
||||
+22
-11
@@ -48,16 +48,6 @@
|
||||
//
|
||||
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 &&
|
||||
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
|
||||
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
|
||||
@@ -78,6 +68,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
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->major < 1 || ctxconfig->minor < 0) ||
|
||||
@@ -356,6 +363,8 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
|
||||
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
glfwMakeContextCurrent((GLFWwindow*) window);
|
||||
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
|
||||
return GLFW_FALSE;
|
||||
|
||||
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
|
||||
window->context.getProcAddress("glGetIntegerv");
|
||||
@@ -609,10 +618,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
||||
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
_GLFWwindow* previous;
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
|
||||
if (window && window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
|
||||
|
||||
+95
-35
@@ -88,13 +88,30 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
||||
// Return the EGLConfig most closely matching the specified hints
|
||||
//
|
||||
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* desired,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
EGLConfig* result)
|
||||
{
|
||||
EGLConfig* nativeConfigs;
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
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);
|
||||
if (!nativeCount)
|
||||
@@ -131,7 +148,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
if (!vi.visualid)
|
||||
continue;
|
||||
|
||||
if (desired->transparent)
|
||||
if (fbconfig->transparent)
|
||||
{
|
||||
int count;
|
||||
XVisualInfo* vis =
|
||||
@@ -145,23 +162,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
}
|
||||
#endif // _GLFW_X11
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
|
||||
{
|
||||
if (ctxconfig->major == 1)
|
||||
{
|
||||
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;
|
||||
wrongApiAvailable = GLFW_TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
|
||||
@@ -172,16 +176,57 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_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->doublebuffer = desired->doublebuffer;
|
||||
u->doublebuffer = fbconfig->doublebuffer;
|
||||
|
||||
u->handle = (uintptr_t) n;
|
||||
usableCount++;
|
||||
}
|
||||
|
||||
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
||||
if (closest)
|
||||
*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(usableConfigs);
|
||||
@@ -230,6 +275,12 @@ static void swapBuffersEGL(_GLFWwindow* window)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
|
||||
if (!window->wl.visible)
|
||||
return;
|
||||
#endif
|
||||
|
||||
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
|
||||
}
|
||||
|
||||
@@ -253,6 +304,7 @@ static int extensionSupportedEGL(const char* extension)
|
||||
static GLFWglproc getProcAddressEGL(const char* procname)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
assert(window != NULL);
|
||||
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
@@ -314,6 +366,8 @@ GLFWbool _glfwInitEGL(void)
|
||||
"libEGL.dylib",
|
||||
#elif defined(__CYGWIN__)
|
||||
"libEGL-1.so",
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
"libEGL.so",
|
||||
#else
|
||||
"libEGL.so.1",
|
||||
#endif
|
||||
@@ -426,6 +480,8 @@ GLFWbool _glfwInitEGL(void)
|
||||
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
|
||||
_glfw.egl.KHR_context_flush_control =
|
||||
extensionSupportedEGL("EGL_KHR_context_flush_control");
|
||||
_glfw.egl.EXT_present_opaque =
|
||||
extensionSupportedEGL("EGL_EXT_present_opaque");
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
@@ -475,11 +531,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
share = ctxconfig->share->context.egl.handle;
|
||||
|
||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
@@ -536,18 +588,18 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
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)
|
||||
{
|
||||
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
||||
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)
|
||||
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
||||
|
||||
@@ -599,6 +651,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (!fbconfig->doublebuffer)
|
||||
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
||||
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
if (_glfw.egl.EXT_present_opaque)
|
||||
setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
||||
#endif // _GLFW_WAYLAND
|
||||
|
||||
setAttrib(EGL_NONE, EGL_NONE);
|
||||
|
||||
window->context.egl.surface =
|
||||
@@ -630,6 +687,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
"libGLES_CM.dll",
|
||||
#elif defined(_GLFW_COCOA)
|
||||
"libGLESv1_CM.dylib",
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
"libGLESv1_CM.so",
|
||||
#else
|
||||
"libGLESv1_CM.so.1",
|
||||
"libGLES_CM.so.1",
|
||||
@@ -647,6 +706,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
"libGLESv2.dylib",
|
||||
#elif defined(__CYGWIN__)
|
||||
"libGLESv2-2.so",
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
"libGLESv2.so",
|
||||
#else
|
||||
"libGLESv2.so.2",
|
||||
#endif
|
||||
@@ -658,7 +719,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_GLFW_OPENGL_LIBRARY,
|
||||
#elif defined(_GLFW_WIN32)
|
||||
#elif defined(_GLFW_COCOA)
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
"libGL.so",
|
||||
#else
|
||||
"libOpenGL.so.0",
|
||||
"libGL.so.1",
|
||||
#endif
|
||||
NULL
|
||||
@@ -721,11 +785,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
const long vimask = VisualScreenMask | VisualIDMask;
|
||||
|
||||
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
eglGetConfigAttrib(_glfw.egl.display, native,
|
||||
EGL_NATIVE_VISUAL_ID, &visualID);
|
||||
|
||||
@@ -108,6 +108,7 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
|
||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
|
||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
|
||||
#define EGL_PRESENT_OPAQUE_EXT 0x31df
|
||||
|
||||
typedef int EGLint;
|
||||
typedef unsigned int EGLBoolean;
|
||||
@@ -179,6 +180,7 @@ typedef struct _GLFWlibraryEGL
|
||||
GLFWbool KHR_gl_colorspace;
|
||||
GLFWbool KHR_get_all_proc_addresses;
|
||||
GLFWbool KHR_context_flush_control;
|
||||
GLFWbool EXT_present_opaque;
|
||||
|
||||
void* handle;
|
||||
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@ Description: A multi-platform library for OpenGL, window and input
|
||||
Version: @GLFW_VERSION@
|
||||
URL: https://www.glfw.org/
|
||||
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@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
// Define this to 1 to force use of high-performance GPU on hybrid systems
|
||||
#cmakedefine _GLFW_USE_HYBRID_HPG
|
||||
|
||||
// Define this to 1 if xkbcommon supports the compose key
|
||||
#cmakedefine HAVE_XKBCOMMON_COMPOSE_H
|
||||
// Define this to 1 if the libc supports memfd_create()
|
||||
#cmakedefine HAVE_MEMFD_CREATE
|
||||
|
||||
|
||||
+13
-6
@@ -190,6 +190,7 @@ static void swapBuffersGLX(_GLFWwindow* window)
|
||||
static void swapIntervalGLX(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
assert(window != NULL);
|
||||
|
||||
if (_glfw.glx.EXT_swap_control)
|
||||
{
|
||||
@@ -226,7 +227,10 @@ static GLFWglproc getProcAddressGLX(const char* procname)
|
||||
else if (_glfw.glx.GetProcAddressARB)
|
||||
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
|
||||
else
|
||||
{
|
||||
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
|
||||
return _glfw_dlsym(_glfw.glx.handle, procname);
|
||||
}
|
||||
}
|
||||
|
||||
static void destroyContextGLX(_GLFWwindow* window)
|
||||
@@ -260,7 +264,10 @@ GLFWbool _glfwInitGLX(void)
|
||||
_GLFW_GLX_LIBRARY,
|
||||
#elif defined(__CYGWIN__)
|
||||
"libGL-1.so",
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
"libGL.so",
|
||||
#else
|
||||
"libGLX.so.0",
|
||||
"libGL.so.1",
|
||||
"libGL.so",
|
||||
#endif
|
||||
@@ -307,10 +314,6 @@ GLFWbool _glfwInitGLX(void)
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
|
||||
_glfw.glx.DestroyWindow =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
|
||||
_glfw.glx.GetProcAddress =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
|
||||
_glfw.glx.GetProcAddressARB =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
|
||||
_glfw.glx.GetVisualFromFBConfig =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||
|
||||
@@ -326,8 +329,6 @@ GLFWbool _glfwInitGLX(void)
|
||||
!_glfw.glx.CreateNewContext ||
|
||||
!_glfw.glx.CreateWindow ||
|
||||
!_glfw.glx.DestroyWindow ||
|
||||
!_glfw.glx.GetProcAddress ||
|
||||
!_glfw.glx.GetProcAddressARB ||
|
||||
!_glfw.glx.GetVisualFromFBConfig)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
@@ -335,6 +336,12 @@ GLFWbool _glfwInitGLX(void)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// NOTE: Unlike GLX 1.3 entry points these are not required to be present
|
||||
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
|
||||
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
|
||||
|
||||
if (!glXQueryExtension(_glfw.x11.display,
|
||||
&_glfw.glx.errorBase,
|
||||
&_glfw.glx.eventBase))
|
||||
|
||||
@@ -127,7 +127,6 @@ typedef struct _GLFWlibraryGLX
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
|
||||
// dlopen handle for libGL.so.1
|
||||
void* handle;
|
||||
|
||||
// GLX 1.3 functions
|
||||
|
||||
+107
-6
@@ -36,16 +36,15 @@
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// The global variables below comprise all mutable global data in GLFW
|
||||
//
|
||||
// Any other global variable is a bug
|
||||
// NOTE: The global variables below comprise all mutable global data in GLFW
|
||||
// Any other mutable global variable is a bug
|
||||
|
||||
// Global state shared between compilation units of GLFW
|
||||
// This contains all mutable state shared between compilation units of GLFW
|
||||
//
|
||||
_GLFWlibrary _glfw = { GLFW_FALSE };
|
||||
|
||||
// These are outside of _glfw so they can be used before initialization and
|
||||
// after termination
|
||||
// after termination without special handling when _glfw is cleared to zero
|
||||
//
|
||||
static _GLFWerror _glfwMainThreadError;
|
||||
static GLFWerrorfun _glfwErrorCallback;
|
||||
@@ -55,7 +54,10 @@ static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
GLFW_TRUE, // macOS menu bar
|
||||
GLFW_TRUE // macOS bundle chdir
|
||||
}
|
||||
},
|
||||
{
|
||||
GLFW_WAYLAND_PREFER_LIBDECOR // Wayland libdecor mode
|
||||
},
|
||||
};
|
||||
|
||||
// Terminate the library
|
||||
@@ -112,6 +114,90 @@ static void terminate(void)
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Encode a Unicode code point to a UTF-8 stream
|
||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||
//
|
||||
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
if (codepoint < 0x80)
|
||||
s[count++] = (char) codepoint;
|
||||
else if (codepoint < 0x800)
|
||||
{
|
||||
s[count++] = (codepoint >> 6) | 0xc0;
|
||||
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||
}
|
||||
else if (codepoint < 0x10000)
|
||||
{
|
||||
s[count++] = (codepoint >> 12) | 0xe0;
|
||||
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||
}
|
||||
else if (codepoint < 0x110000)
|
||||
{
|
||||
s[count++] = (codepoint >> 18) | 0xf0;
|
||||
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
|
||||
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const size_t length = strlen(source);
|
||||
@@ -120,6 +206,16 @@ char* _glfw_strdup(const char* source)
|
||||
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)
|
||||
{
|
||||
if (a != a)
|
||||
@@ -188,6 +284,8 @@ void _glfwInputError(int code, const char* format, ...)
|
||||
strcpy(description, "The requested format is unavailable");
|
||||
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
||||
strcpy(description, "The specified window has no context");
|
||||
else if (code == GLFW_CURSOR_UNAVAILABLE)
|
||||
strcpy(description, "The specified cursor shape is unavailable");
|
||||
else
|
||||
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||
}
|
||||
@@ -274,6 +372,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
||||
case GLFW_COCOA_MENUBAR:
|
||||
_glfwInitHints.ns.menubar = value;
|
||||
return;
|
||||
case GLFW_WAYLAND_LIBDECOR:
|
||||
_glfwInitHints.wl.libdecorMode = value;
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
|
||||
+51
-20
@@ -278,7 +278,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m
|
||||
// Notifies shared code of a Unicode codepoint input event
|
||||
// The 'plain' parameter determines whether to emit a regular character event
|
||||
//
|
||||
void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain)
|
||||
void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain)
|
||||
{
|
||||
if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
|
||||
return;
|
||||
@@ -360,6 +360,11 @@ void _glfwInputJoystick(_GLFWjoystick* js, int event)
|
||||
{
|
||||
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)
|
||||
_glfw.callbacks.joystick(jid, event);
|
||||
}
|
||||
@@ -401,6 +406,7 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
||||
//
|
||||
void _glfwInitGamepadMappings(void)
|
||||
{
|
||||
int jid;
|
||||
size_t i;
|
||||
const size_t count = sizeof(_glfwDefaultMappings) / sizeof(char*);
|
||||
_glfw.mappings = calloc(count, sizeof(_GLFWmapping));
|
||||
@@ -410,6 +416,13 @@ void _glfwInitGamepadMappings(void)
|
||||
if (parseMapping(&_glfw.mappings[_glfw.mappingCount], _glfwDefaultMappings[i]))
|
||||
_glfw.mappingCount++;
|
||||
}
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->connected)
|
||||
js->mapping = findValidMapping(js);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an available joystick object with arrays and name allocated
|
||||
@@ -425,7 +438,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (!_glfw.joysticks[jid].present)
|
||||
if (!_glfw.joysticks[jid].allocated)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -433,7 +446,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
return NULL;
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
js->present = GLFW_TRUE;
|
||||
js->allocated = GLFW_TRUE;
|
||||
js->axes = calloc(axisCount, sizeof(float));
|
||||
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
|
||||
js->hats = calloc(hatCount, 1);
|
||||
@@ -603,6 +616,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
|
||||
|
||||
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 &&
|
||||
(key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
|
||||
(key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))
|
||||
@@ -618,12 +637,12 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
|
||||
|
||||
GLFWAPI int glfwGetKeyScancode(int key)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(-1);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
|
||||
if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
|
||||
return GLFW_RELEASE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _glfwPlatformGetKeyScancode(key);
|
||||
@@ -735,9 +754,16 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
||||
_GLFWcursor* cursor;
|
||||
|
||||
assert(image != NULL);
|
||||
assert(image->pixels != 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->next = _glfw.cursorListHead;
|
||||
_glfw.cursorListHead = cursor;
|
||||
@@ -760,9 +786,13 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
||||
if (shape != GLFW_ARROW_CURSOR &&
|
||||
shape != GLFW_IBEAM_CURSOR &&
|
||||
shape != GLFW_CROSSHAIR_CURSOR &&
|
||||
shape != GLFW_HAND_CURSOR &&
|
||||
shape != GLFW_HRESIZE_CURSOR &&
|
||||
shape != GLFW_VRESIZE_CURSOR)
|
||||
shape != GLFW_POINTING_HAND_CURSOR &&
|
||||
shape != GLFW_RESIZE_EW_CURSOR &&
|
||||
shape != GLFW_RESIZE_NS_CURSOR &&
|
||||
shape != GLFW_RESIZE_NWSE_CURSOR &&
|
||||
shape != GLFW_RESIZE_NESW_CURSOR &&
|
||||
shape != GLFW_RESIZE_ALL_CURSOR &&
|
||||
shape != GLFW_NOT_ALLOWED_CURSOR)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
|
||||
return NULL;
|
||||
@@ -929,7 +959,7 @@ GLFWAPI int glfwJoystickPresent(int jid)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return GLFW_FALSE;
|
||||
|
||||
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||
@@ -954,7 +984,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
|
||||
@@ -983,7 +1013,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
|
||||
@@ -1016,7 +1046,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
|
||||
@@ -1042,7 +1072,7 @@ GLFWAPI const char* glfwGetJoystickName(int jid)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
@@ -1067,7 +1097,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
@@ -1086,7 +1116,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->allocated)
|
||||
return;
|
||||
|
||||
js->userPointer = pointer;
|
||||
@@ -1102,7 +1132,7 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid)
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->allocated)
|
||||
return NULL;
|
||||
|
||||
return js->userPointer;
|
||||
@@ -1168,7 +1198,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
if (js->connected)
|
||||
js->mapping = findValidMapping(js);
|
||||
}
|
||||
|
||||
@@ -1191,7 +1221,7 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
@@ -1216,7 +1246,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
@@ -1248,7 +1278,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
if (!js->connected)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
|
||||
@@ -1357,3 +1387,4 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void)
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
return _glfwPlatformGetTimerFrequency();
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -244,6 +244,9 @@ struct _GLFWinitconfig
|
||||
GLFWbool menubar;
|
||||
GLFWbool chdir;
|
||||
} ns;
|
||||
struct {
|
||||
int libdecorMode;
|
||||
} wl;
|
||||
};
|
||||
|
||||
// Window configuration
|
||||
@@ -478,7 +481,8 @@ struct _GLFWmapping
|
||||
//
|
||||
struct _GLFWjoystick
|
||||
{
|
||||
GLFWbool present;
|
||||
GLFWbool allocated;
|
||||
GLFWbool connected;
|
||||
float* axes;
|
||||
int axisCount;
|
||||
unsigned char* buttons;
|
||||
@@ -718,7 +722,7 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
||||
void _glfwInputKey(_GLFWwindow* window,
|
||||
int key, int scancode, int action, int mods);
|
||||
void _glfwInputChar(_GLFWwindow* window,
|
||||
unsigned int codepoint, int mods, GLFWbool plain);
|
||||
uint32_t codepoint, int mods, GLFWbool plain);
|
||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
@@ -774,7 +778,12 @@ GLFWbool _glfwInitVulkan(int mode);
|
||||
void _glfwTerminateVulkan(void);
|
||||
const char* _glfwGetVulkanResultString(VkResult result);
|
||||
|
||||
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
||||
char** _glfwParseUriList(char* text, int* count);
|
||||
|
||||
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_fmaxf(float a, float b);
|
||||
|
||||
|
||||
+10
-8
@@ -128,7 +128,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (!_glfw.joysticks[jid].present)
|
||||
if (!_glfw.joysticks[jid].connected)
|
||||
continue;
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
return GLFW_FALSE;
|
||||
@@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
}
|
||||
|
||||
// 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);
|
||||
return GLFW_FALSE;
|
||||
@@ -245,9 +245,9 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
//
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
close(js->linjs.fd);
|
||||
_glfwFreeJoystick(js);
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
}
|
||||
|
||||
// Lexically compare joysticks by name; used by qsort
|
||||
@@ -283,7 +283,8 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
||||
|
||||
// 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");
|
||||
return GLFW_FALSE;
|
||||
@@ -329,12 +330,10 @@ void _glfwTerminateJoysticksLinux(void)
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
if (js->connected)
|
||||
closeJoystick(js);
|
||||
}
|
||||
|
||||
regfree(&_glfw.linjs.regex);
|
||||
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
{
|
||||
if (_glfw.linjs.watch > 0)
|
||||
@@ -342,6 +341,9 @@ void _glfwTerminateJoysticksLinux(void)
|
||||
|
||||
close(_glfw.linjs.inotify);
|
||||
}
|
||||
|
||||
if (_glfw.linjs.regexCompiled)
|
||||
regfree(&_glfw.linjs.regex);
|
||||
}
|
||||
|
||||
void _glfwDetectJoystickConnectionLinux(void)
|
||||
@@ -424,7 +426,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
handleAbsEvent(js, e.code, e.value);
|
||||
}
|
||||
|
||||
return js->present;
|
||||
return js->connected;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct _GLFWlibraryLinux
|
||||
int inotify;
|
||||
int watch;
|
||||
regex_t regex;
|
||||
GLFWbool regexCompiled;
|
||||
GLFWbool dropped;
|
||||
} _GLFWlibraryLinux;
|
||||
|
||||
|
||||
+2
-2
@@ -521,6 +521,8 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
|
||||
assert(ramp->green != NULL);
|
||||
assert(ramp->blue != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (ramp->size <= 0)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
@@ -529,8 +531,6 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
|
||||
return;
|
||||
}
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (!monitor->originalRamp.size)
|
||||
{
|
||||
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
|
||||
|
||||
+4
-2
@@ -25,8 +25,10 @@
|
||||
//========================================================================
|
||||
|
||||
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||
// SDK versions where one is unavailable or the other deprecated
|
||||
// We use the newer names in code and these macros to handle compatibility
|
||||
// SDK versions where one is unavailable or deprecated.
|
||||
// We use the newer names in code and replace them with the older names if
|
||||
// the base SDK does not provide the newer names.
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
|
||||
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
||||
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||
|
||||
+5
-6
@@ -81,11 +81,10 @@ static void swapIntervalNSGL(int interval)
|
||||
@autoreleasepool {
|
||||
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
if (window)
|
||||
{
|
||||
[window->context.nsgl.object setValues:&interval
|
||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||
}
|
||||
assert(window != NULL);
|
||||
|
||||
[window->context.nsgl.object setValues:&interval
|
||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
@@ -162,7 +161,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: OpenGL ES is not available on macOS");
|
||||
"NSGL: OpenGL ES is not available via NSGL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
@@ -124,6 +123,8 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
"libOSMesa.8.dylib",
|
||||
#elif defined(__CYGWIN__)
|
||||
"libOSMesa-8.so",
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
"libOSMesa.so",
|
||||
#else
|
||||
"libOSMesa.so.8",
|
||||
"libOSMesa.so.6",
|
||||
|
||||
@@ -59,6 +59,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
||||
if (!_glfw.vk.handle)
|
||||
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.so");
|
||||
#else
|
||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
||||
#endif
|
||||
|
||||
+14
-8
@@ -73,18 +73,30 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
int attribs[40];
|
||||
int values[sizeof(attribs) / sizeof(attribs[0])];
|
||||
|
||||
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
// NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than
|
||||
// DescribePixelFormat, violating the guarantees of the extension spec
|
||||
// HACK: Iterate through the minimum of both counts
|
||||
|
||||
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||
int extensionCount;
|
||||
|
||||
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||
1, 0, 1, &attrib, &nativeCount))
|
||||
1, 0, 1, &attrib, &extensionCount))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve pixel format attribute");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nativeCount = _glfw_min(nativeCount, extensionCount);
|
||||
|
||||
addAttrib(WGL_SUPPORT_OPENGL_ARB);
|
||||
addAttrib(WGL_DRAW_TO_WINDOW_ARB);
|
||||
addAttrib(WGL_PIXEL_TYPE_ARB);
|
||||
@@ -122,13 +134,6 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
addAttrib(WGL_COLORSPACE_EXT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
|
||||
@@ -345,6 +350,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
|
||||
static void swapIntervalWGL(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
assert(window != NULL);
|
||||
|
||||
window->context.wgl.interval = interval;
|
||||
|
||||
|
||||
+19
-4
@@ -72,6 +72,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
//
|
||||
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");
|
||||
if (!_glfw.win32.user32.instance)
|
||||
{
|
||||
@@ -92,6 +102,8 @@ static GLFWbool loadLibraries(void)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
|
||||
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
||||
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
|
||||
|
||||
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
@@ -252,7 +264,6 @@ static void createKeyTables(void)
|
||||
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
|
||||
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
|
||||
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
|
||||
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
|
||||
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
|
||||
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
|
||||
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
|
||||
@@ -334,7 +345,7 @@ static GLFWbool createHelperWindow(void)
|
||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||
0, 0, 1, 1,
|
||||
NULL, NULL,
|
||||
GetModuleHandleW(NULL),
|
||||
_glfw.win32.instance,
|
||||
NULL);
|
||||
|
||||
if (!_glfw.win32.helperWindowHandle)
|
||||
@@ -484,7 +495,7 @@ void _glfwUpdateKeyNamesWin32(void)
|
||||
vk = vks[key - GLFW_KEY_KP_0];
|
||||
}
|
||||
else
|
||||
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
|
||||
vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK);
|
||||
|
||||
length = ToUnicode(vk, scancode, state,
|
||||
chars, sizeof(chars) / sizeof(WCHAR),
|
||||
@@ -492,6 +503,8 @@ void _glfwUpdateKeyNamesWin32(void)
|
||||
|
||||
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,
|
||||
chars, sizeof(chars) / sizeof(WCHAR),
|
||||
0);
|
||||
@@ -507,7 +520,8 @@ void _glfwUpdateKeyNamesWin32(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
|
||||
// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
|
||||
// application having a correct embedded manifest
|
||||
//
|
||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
||||
{
|
||||
@@ -598,6 +612,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
_glfwTerminateWGL();
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateOSMesa();
|
||||
|
||||
_glfwTerminateJoysticksWin32();
|
||||
|
||||
|
||||
+14
-7
@@ -256,6 +256,8 @@ static GLFWbool supportsXInput(const GUID* guid)
|
||||
//
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
|
||||
if (js->win32.device)
|
||||
{
|
||||
IDirectInputDevice8_Unacquire(js->win32.device);
|
||||
@@ -263,9 +265,7 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
}
|
||||
|
||||
free(js->win32.objects);
|
||||
|
||||
_glfwFreeJoystick(js);
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
if (js->connected)
|
||||
{
|
||||
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||
return DIENUM_CONTINUE;
|
||||
@@ -497,7 +497,7 @@ void _glfwInitJoysticksWin32(void)
|
||||
{
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
{
|
||||
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
||||
if (FAILED(DirectInput8Create(_glfw.win32.instance,
|
||||
DIRECTINPUT_VERSION,
|
||||
&IID_IDirectInput8W,
|
||||
(void**) &_glfw.win32.dinput8.api,
|
||||
@@ -541,7 +541,7 @@ void _glfwDetectJoystickConnectionWin32(void)
|
||||
|
||||
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.index == index)
|
||||
{
|
||||
@@ -593,7 +593,7 @@ void _glfwDetectJoystickDisconnectionWin32(void)
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
if (js->connected)
|
||||
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||
}
|
||||
}
|
||||
@@ -609,7 +609,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
int i, ai = 0, bi = 0, pi = 0;
|
||||
HRESULT result;
|
||||
DIJOYSTATE state;
|
||||
DIJOYSTATE state = {0};
|
||||
|
||||
IDirectInputDevice8_Poll(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)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+13
-2
@@ -318,8 +318,19 @@ void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* ysc
|
||||
{
|
||||
UINT xdpi, ydpi;
|
||||
|
||||
if (xscale)
|
||||
*xscale = 0.f;
|
||||
if (yscale)
|
||||
*yscale = 0.f;
|
||||
|
||||
if (IsWindows8Point1OrGreater())
|
||||
GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||
{
|
||||
if (GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query monitor DPI");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const HDC dc = GetDC(NULL);
|
||||
@@ -371,7 +382,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* width, int* height)
|
||||
{
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
GetMonitorInfo(monitor->win32.handle, &mi);
|
||||
GetMonitorInfoW(monitor->win32.handle, &mi);
|
||||
|
||||
if (xpos)
|
||||
*xpos = mi.rcWork.left;
|
||||
|
||||
@@ -162,7 +162,9 @@ typedef enum
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
|
||||
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
||||
|
||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
||||
// Replacement for versionhelpers.h macros, as we cannot rely on the
|
||||
// application having a correct embedded manifest
|
||||
//
|
||||
#define IsWindowsXPOrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
|
||||
LOBYTE(_WIN32_WINNT_WINXP), 0)
|
||||
@@ -235,12 +237,14 @@ typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
||||
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
|
||||
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
||||
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
||||
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
|
||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
||||
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
||||
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
||||
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
||||
#define GetSystemMetricsForDpi _glfw.win32.user32.GetSystemMetricsForDpi_
|
||||
|
||||
// dwmapi.dll function pointer typedefs
|
||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||
@@ -330,6 +334,7 @@ typedef struct _GLFWwindowWin32
|
||||
//
|
||||
typedef struct _GLFWlibraryWin32
|
||||
{
|
||||
HINSTANCE instance;
|
||||
HWND helperWindowHandle;
|
||||
HDEVNOTIFY deviceNotificationHandle;
|
||||
DWORD foregroundLockTimeout;
|
||||
@@ -342,6 +347,8 @@ typedef struct _GLFWlibraryWin32
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
// The window whose disabled cursor mode is active
|
||||
_GLFWwindow* disabledCursorWindow;
|
||||
// The window the cursor is captured in
|
||||
_GLFWwindow* capturedCursorWindow;
|
||||
RAWINPUT* rawInput;
|
||||
int rawInputSize;
|
||||
UINT mouseTrailSize;
|
||||
@@ -366,6 +373,7 @@ typedef struct _GLFWlibraryWin32
|
||||
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
||||
PFN_GetDpiForWindow GetDpiForWindow_;
|
||||
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
||||
PFN_GetSystemMetricsForDpi GetSystemMetricsForDpi_;
|
||||
} user32;
|
||||
|
||||
struct {
|
||||
|
||||
+256
-113
@@ -186,53 +186,38 @@ static HICON createIcon(const GLFWimage* image,
|
||||
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
|
||||
//
|
||||
static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
|
||||
{
|
||||
int xoff, yoff;
|
||||
UINT dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
RECT frame = {0};
|
||||
const float ratio = (float) window->numer / (float) window->denom;
|
||||
const DWORD style = getWindowStyle(window);
|
||||
const DWORD exStyle = getWindowExStyle(window);
|
||||
|
||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||
dpi = GetDpiForWindow(window->win32.handle);
|
||||
|
||||
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
||||
0, 0, &xoff, &yoff, dpi);
|
||||
{
|
||||
AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,
|
||||
GetDpiForWindow(window->win32.handle));
|
||||
}
|
||||
else
|
||||
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
|
||||
|
||||
if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
|
||||
edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
|
||||
{
|
||||
area->bottom = area->top + yoff +
|
||||
(int) ((area->right - area->left - xoff) / ratio);
|
||||
area->bottom = area->top + (frame.bottom - frame.top) +
|
||||
(int) (((area->right - area->left) - (frame.right - frame.left)) / ratio);
|
||||
}
|
||||
else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)
|
||||
{
|
||||
area->top = area->bottom - yoff -
|
||||
(int) ((area->right - area->left - xoff) / ratio);
|
||||
area->top = area->bottom - (frame.bottom - frame.top) -
|
||||
(int) (((area->right - area->left) - (frame.right - frame.left)) / ratio);
|
||||
}
|
||||
else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM)
|
||||
{
|
||||
area->right = area->left + xoff +
|
||||
(int) ((area->bottom - area->top - yoff) * ratio);
|
||||
area->right = area->left + (frame.right - frame.left) +
|
||||
(int) (((area->bottom - area->top) - (frame.bottom - frame.top)) * ratio);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,20 +236,24 @@ static void updateCursorImage(_GLFWwindow* window)
|
||||
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;
|
||||
GetClientRect(window->win32.handle, &clipRect);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
|
||||
ClipCursor(&clipRect);
|
||||
}
|
||||
else
|
||||
ClipCursor(NULL);
|
||||
RECT clipRect;
|
||||
GetClientRect(window->win32.handle, &clipRect);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
|
||||
ClipCursor(&clipRect);
|
||||
_glfw.win32.capturedCursorWindow = window;
|
||||
}
|
||||
|
||||
// Disabled clip cursor
|
||||
//
|
||||
static void releaseCursor(void)
|
||||
{
|
||||
ClipCursor(NULL);
|
||||
_glfw.win32.capturedCursorWindow = NULL;
|
||||
}
|
||||
|
||||
// Enables WM_INPUT messages for the mouse for the specified window
|
||||
@@ -303,7 +292,7 @@ static void disableCursor(_GLFWwindow* window)
|
||||
&_glfw.win32.restoreCursorPosY);
|
||||
updateCursorImage(window);
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
updateClipRect(window);
|
||||
captureCursor(window);
|
||||
|
||||
if (window->rawMouseMotion)
|
||||
enableRawMouseMotion(window);
|
||||
@@ -317,7 +306,7 @@ static void enableCursor(_GLFWwindow* window)
|
||||
disableRawMouseMotion(window);
|
||||
|
||||
_glfw.win32.disabledCursorWindow = NULL;
|
||||
updateClipRect(NULL);
|
||||
releaseCursor();
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.win32.restoreCursorPosX,
|
||||
_glfw.win32.restoreCursorPosY);
|
||||
@@ -435,7 +424,7 @@ static int getKeyMods(void)
|
||||
static void fitToMonitor(_GLFWwindow* window)
|
||||
{
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
GetMonitorInfo(window->monitor->win32.handle, &mi);
|
||||
GetMonitorInfoW(window->monitor->win32.handle, &mi);
|
||||
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
||||
mi.rcMonitor.left,
|
||||
mi.rcMonitor.top,
|
||||
@@ -456,8 +445,8 @@ static void acquireMonitor(_GLFWwindow* window)
|
||||
// the OpenGL ICD switches to page flipping
|
||||
if (IsWindowsXPOrGreater())
|
||||
{
|
||||
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
||||
SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
|
||||
SystemParametersInfoW(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
||||
SystemParametersInfoW(SPI_SETMOUSETRAILS, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,13 +471,63 @@ static void releaseMonitor(_GLFWwindow* window)
|
||||
|
||||
// HACK: Restore mouse trail length saved in acquireMonitor
|
||||
if (IsWindowsXPOrGreater())
|
||||
SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
||||
SystemParametersInfoW(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
||||
}
|
||||
|
||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||
_glfwRestoreVideoModeWin32(window->monitor);
|
||||
}
|
||||
|
||||
// Manually maximize the window, for when SW_MAXIMIZE cannot be used
|
||||
//
|
||||
static void maximizeWindowManually(_GLFWwindow* window)
|
||||
{
|
||||
RECT rect;
|
||||
DWORD style;
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
|
||||
GetMonitorInfoW(MonitorFromWindow(window->win32.handle,
|
||||
MONITOR_DEFAULTTONEAREST), &mi);
|
||||
|
||||
rect = mi.rcWork;
|
||||
|
||||
if (window->maxwidth != GLFW_DONT_CARE && window->maxheight != GLFW_DONT_CARE)
|
||||
{
|
||||
rect.right = _glfw_min(rect.right, rect.left + window->maxwidth);
|
||||
rect.bottom = _glfw_min(rect.bottom, rect.top + window->maxheight);
|
||||
}
|
||||
|
||||
style = GetWindowLongW(window->win32.handle, GWL_STYLE);
|
||||
style |= WS_MAXIMIZE;
|
||||
SetWindowLongW(window->win32.handle, GWL_STYLE, style);
|
||||
|
||||
if (window->decorated)
|
||||
{
|
||||
const DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||
|
||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||
{
|
||||
const UINT dpi = GetDpiForWindow(window->win32.handle);
|
||||
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, dpi);
|
||||
OffsetRect(&rect, 0, GetSystemMetricsForDpi(SM_CYCAPTION, dpi));
|
||||
}
|
||||
else
|
||||
{
|
||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||
OffsetRect(&rect, 0, GetSystemMetrics(SM_CYCAPTION));
|
||||
}
|
||||
|
||||
rect.bottom = _glfw_min(rect.bottom, mi.rcWork.bottom);
|
||||
}
|
||||
|
||||
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
}
|
||||
|
||||
// Window callback function (handles window messages)
|
||||
//
|
||||
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
@@ -646,7 +685,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
window->win32.highSurrogate = (WCHAR) wParam;
|
||||
else
|
||||
{
|
||||
unsigned int codepoint = 0;
|
||||
uint32_t codepoint = 0;
|
||||
|
||||
if (wParam >= 0xdc00 && wParam <= 0xdfff)
|
||||
{
|
||||
@@ -677,7 +716,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE);
|
||||
_glfwInputChar(window, (uint32_t) wParam, getKeyMods(), GLFW_TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -698,6 +737,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
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];
|
||||
|
||||
// The Ctrl keys require special handling
|
||||
@@ -971,8 +1022,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
(window->win32.maximized &&
|
||||
wParam != SIZE_RESTORED);
|
||||
|
||||
if (_glfw.win32.disabledCursorWindow == window)
|
||||
updateClipRect(window);
|
||||
if (_glfw.win32.capturedCursorWindow == window)
|
||||
captureCursor(window);
|
||||
|
||||
if (window->win32.iconified != iconified)
|
||||
_glfwInputWindowIconify(window, iconified);
|
||||
@@ -1007,8 +1058,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
if (_glfw.win32.disabledCursorWindow == window)
|
||||
updateClipRect(window);
|
||||
if (_glfw.win32.capturedCursorWindow == window)
|
||||
captureCursor(window);
|
||||
|
||||
// NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
|
||||
// those macros do not handle negative window positions correctly
|
||||
@@ -1032,31 +1083,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
int xoff, yoff;
|
||||
UINT dpi = USER_DEFAULT_SCREEN_DPI;
|
||||
RECT frame = {0};
|
||||
MINMAXINFO* mmi = (MINMAXINFO*) lParam;
|
||||
const DWORD style = getWindowStyle(window);
|
||||
const DWORD exStyle = getWindowExStyle(window);
|
||||
|
||||
if (window->monitor)
|
||||
break;
|
||||
|
||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||
dpi = GetDpiForWindow(window->win32.handle);
|
||||
|
||||
getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
|
||||
0, 0, &xoff, &yoff, dpi);
|
||||
{
|
||||
AdjustWindowRectExForDpi(&frame, style, FALSE, exStyle,
|
||||
GetDpiForWindow(window->win32.handle));
|
||||
}
|
||||
else
|
||||
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
|
||||
|
||||
if (window->minwidth != GLFW_DONT_CARE &&
|
||||
window->minheight != GLFW_DONT_CARE)
|
||||
{
|
||||
mmi->ptMinTrackSize.x = window->minwidth + xoff;
|
||||
mmi->ptMinTrackSize.y = window->minheight + yoff;
|
||||
mmi->ptMinTrackSize.x = window->minwidth + frame.right - frame.left;
|
||||
mmi->ptMinTrackSize.y = window->minheight + frame.bottom - frame.top;
|
||||
}
|
||||
|
||||
if (window->maxwidth != GLFW_DONT_CARE &&
|
||||
window->maxheight != GLFW_DONT_CARE)
|
||||
{
|
||||
mmi->ptMaxTrackSize.x = window->maxwidth + xoff;
|
||||
mmi->ptMaxTrackSize.y = window->maxheight + yoff;
|
||||
mmi->ptMaxTrackSize.x = window->maxwidth + frame.right - frame.left;
|
||||
mmi->ptMaxTrackSize.y = window->maxheight + frame.bottom - frame.top;
|
||||
}
|
||||
|
||||
if (!window->decorated)
|
||||
@@ -1067,7 +1121,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
ZeroMemory(&mi, sizeof(mi));
|
||||
mi.cbSize = sizeof(mi);
|
||||
GetMonitorInfo(mh, &mi);
|
||||
GetMonitorInfoW(mh, &mi);
|
||||
|
||||
mmi->ptMaxPosition.x = mi.rcWork.left - mi.rcMonitor.left;
|
||||
mmi->ptMaxPosition.y = mi.rcWork.top - mi.rcMonitor.top;
|
||||
@@ -1215,36 +1269,38 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int xpos, ypos, fullWidth, fullHeight;
|
||||
int frameX, frameY, frameWidth, frameHeight;
|
||||
WCHAR* wideTitle;
|
||||
DWORD style = getWindowStyle(window);
|
||||
DWORD exStyle = getWindowExStyle(window);
|
||||
|
||||
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
|
||||
// correct position and size cannot be known until the monitor
|
||||
// video mode has been picked in _glfwSetVideoModeWin32
|
||||
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
|
||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||
fullWidth = mode.width;
|
||||
fullHeight = mode.height;
|
||||
frameX = mi.rcMonitor.left;
|
||||
frameY = mi.rcMonitor.top;
|
||||
frameWidth = mi.rcMonitor.right - mi.rcMonitor.left;
|
||||
frameHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;
|
||||
}
|
||||
else
|
||||
{
|
||||
xpos = CW_USEDEFAULT;
|
||||
ypos = CW_USEDEFAULT;
|
||||
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
||||
|
||||
window->win32.maximized = wndconfig->maximized;
|
||||
if (wndconfig->maximized)
|
||||
style |= WS_MAXIMIZE;
|
||||
|
||||
getFullWindowSize(style, exStyle,
|
||||
wndconfig->width, wndconfig->height,
|
||||
&fullWidth, &fullHeight,
|
||||
USER_DEFAULT_SCREEN_DPI);
|
||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||
|
||||
frameX = CW_USEDEFAULT;
|
||||
frameY = CW_USEDEFAULT;
|
||||
frameWidth = rect.right - rect.left;
|
||||
frameHeight = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
||||
@@ -1255,11 +1311,11 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
_GLFW_WNDCLASSNAME,
|
||||
wideTitle,
|
||||
style,
|
||||
xpos, ypos,
|
||||
fullWidth, fullHeight,
|
||||
frameX, frameY,
|
||||
frameWidth, frameHeight,
|
||||
NULL, // No parent window
|
||||
NULL, // No window menu
|
||||
GetModuleHandleW(NULL),
|
||||
_glfw.win32.instance,
|
||||
(LPVOID) wndconfig);
|
||||
|
||||
free(wideTitle);
|
||||
@@ -1285,24 +1341,29 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
|
||||
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
||||
|
||||
// Adjust window rect to account for DPI scaling of the window frame and
|
||||
// (if enabled) DPI scaling of the content area
|
||||
// This cannot be done until we know what monitor the window was placed on
|
||||
if (!window->monitor)
|
||||
{
|
||||
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
||||
WINDOWPLACEMENT wp = { sizeof(wp) };
|
||||
const HMONITOR mh = MonitorFromWindow(window->win32.handle,
|
||||
MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// Adjust window rect to account for DPI scaling of the window frame and
|
||||
// (if enabled) DPI scaling of the content area
|
||||
// This cannot be done until we know what monitor the window was placed on
|
||||
// Only update the restored window rect as the window may be maximized
|
||||
|
||||
if (wndconfig->scaleToMonitor)
|
||||
{
|
||||
float xscale, yscale;
|
||||
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||
rect.right = (int) (rect.right * xscale);
|
||||
rect.bottom = (int) (rect.bottom * yscale);
|
||||
}
|
||||
_glfwGetMonitorContentScaleWin32(mh, &xscale, &yscale);
|
||||
|
||||
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
||||
if (xscale > 0.f && yscale > 0.f)
|
||||
{
|
||||
rect.right = (int) (rect.right * xscale);
|
||||
rect.bottom = (int) (rect.bottom * yscale);
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||
{
|
||||
@@ -1312,11 +1373,30 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
else
|
||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||
|
||||
// Only update the restored window rect as the window may be maximized
|
||||
GetWindowPlacement(window->win32.handle, &wp);
|
||||
OffsetRect(&rect,
|
||||
wp.rcNormalPosition.left - rect.left,
|
||||
wp.rcNormalPosition.top - rect.top);
|
||||
|
||||
wp.rcNormalPosition = rect;
|
||||
wp.showCmd = SW_HIDE;
|
||||
SetWindowPlacement(window->win32.handle, &wp);
|
||||
|
||||
// Adjust rect of maximized undecorated window, because by default Windows will
|
||||
// make such a window cover the whole monitor instead of its workarea
|
||||
|
||||
if (wndconfig->maximized && !wndconfig->decorated)
|
||||
{
|
||||
MONITORINFO mi = { sizeof(mi) };
|
||||
GetMonitorInfoW(mh, &mi);
|
||||
|
||||
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||
mi.rcWork.left,
|
||||
mi.rcWork.top,
|
||||
mi.rcWork.right - mi.rcWork.left,
|
||||
mi.rcWork.bottom - mi.rcWork.top,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
DragAcceptFiles(window->win32.handle, TRUE);
|
||||
@@ -1346,8 +1426,8 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
|
||||
ZeroMemory(&wc, sizeof(wc));
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
wc.lpfnWndProc = (WNDPROC) windowProc;
|
||||
wc.hInstance = GetModuleHandleW(NULL);
|
||||
wc.lpfnWndProc = windowProc;
|
||||
wc.hInstance = _glfw.win32.instance;
|
||||
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
|
||||
wc.lpszClassName = _GLFW_WNDCLASSNAME;
|
||||
|
||||
@@ -1377,7 +1457,7 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
|
||||
//
|
||||
void _glfwUnregisterWindowClassWin32(void)
|
||||
{
|
||||
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
|
||||
UnregisterClassW(_GLFW_WNDCLASSNAME, _glfw.win32.instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -1416,6 +1496,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
@@ -1424,6 +1507,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
_glfwPlatformFocusWindow(window);
|
||||
acquireMonitor(window);
|
||||
fitToMonitor(window);
|
||||
|
||||
if (wndconfig->centerCursor)
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
_glfwPlatformShowWindow(window);
|
||||
if (wndconfig->focused)
|
||||
_glfwPlatformFocusWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@@ -1438,7 +1533,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
window->context.destroy(window);
|
||||
|
||||
if (_glfw.win32.disabledCursorWindow == window)
|
||||
_glfw.win32.disabledCursorWindow = NULL;
|
||||
enableCursor(window);
|
||||
|
||||
if (_glfw.win32.capturedCursorWindow == window)
|
||||
releaseCursor();
|
||||
|
||||
if (window->win32.handle)
|
||||
{
|
||||
@@ -1487,8 +1585,8 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);
|
||||
}
|
||||
|
||||
SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
|
||||
SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
|
||||
SendMessageW(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
|
||||
SendMessageW(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
|
||||
|
||||
if (window->win32.bigIcon)
|
||||
DestroyIcon(window->win32.bigIcon);
|
||||
@@ -1668,7 +1766,10 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
|
||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
{
|
||||
ShowWindow(window->win32.handle, SW_MAXIMIZE);
|
||||
if (IsWindowVisible(window->win32.handle))
|
||||
ShowWindow(window->win32.handle, SW_MAXIMIZE);
|
||||
else
|
||||
maximizeWindowManually(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
@@ -1755,7 +1856,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
|
||||
acquireMonitor(window);
|
||||
|
||||
GetMonitorInfo(window->monitor->win32.handle, &mi);
|
||||
GetMonitorInfoW(window->monitor->win32.handle, &mi);
|
||||
SetWindowPos(window->win32.handle, HWND_TOPMOST,
|
||||
mi.rcMonitor.left,
|
||||
mi.rcMonitor.top,
|
||||
@@ -2012,14 +2113,14 @@ void _glfwPlatformWaitEvents(void)
|
||||
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
{
|
||||
MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
|
||||
MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLINPUT);
|
||||
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
PostMessage(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
|
||||
PostMessageW(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
@@ -2051,27 +2152,58 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
||||
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
{
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
disableCursor(window);
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.win32.restoreCursorPosX,
|
||||
&_glfw.win32.restoreCursorPosY);
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
if (window->rawMouseMotion)
|
||||
enableRawMouseMotion(window);
|
||||
}
|
||||
else if (_glfw.win32.disabledCursorWindow == 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);
|
||||
}
|
||||
}
|
||||
else if (_glfw.win32.disabledCursorWindow == window)
|
||||
enableCursor(window);
|
||||
else if (cursorInContentArea(window))
|
||||
|
||||
if (cursorInContentArea(window))
|
||||
updateCursorImage(window);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||
{
|
||||
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) ||
|
||||
_glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||
int key;
|
||||
|
||||
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff))
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
||||
key = _glfw.win32.keycodes[scancode];
|
||||
if (key == GLFW_KEY_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
return _glfw.win32.keynames[key];
|
||||
}
|
||||
|
||||
int _glfwPlatformGetKeyScancode(int key)
|
||||
@@ -2100,14 +2232,25 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
id = OCR_IBEAM;
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
id = OCR_CROSS;
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||
id = OCR_HAND;
|
||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
id = OCR_SIZEWE;
|
||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
id = OCR_SIZENS;
|
||||
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||
id = OCR_SIZENWSE;
|
||||
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||
id = OCR_SIZENESW;
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
id = OCR_SIZEALL;
|
||||
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||
id = OCR_NO;
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
cursor->win32.handle = LoadImageW(NULL,
|
||||
MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,
|
||||
@@ -2263,7 +2406,7 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
|
||||
memset(&sci, 0, sizeof(sci));
|
||||
sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||
sci.hinstance = GetModuleHandle(NULL);
|
||||
sci.hinstance = _glfw.win32.instance;
|
||||
sci.hwnd = window->win32.handle;
|
||||
|
||||
err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
|
||||
|
||||
+22
-25
@@ -221,30 +221,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -504,12 +480,33 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
|
||||
GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
|
||||
int count, const GLFWimage* images)
|
||||
{
|
||||
int i;
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
||||
assert(window != NULL);
|
||||
assert(count >= 0);
|
||||
assert(count == 0 || images != NULL);
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
@@ -697,7 +694,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(1.f);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0.f);
|
||||
return _glfwPlatformGetWindowOpacity(window);
|
||||
}
|
||||
|
||||
|
||||
+249
-820
File diff suppressed because it is too large
Load Diff
+68
-26
@@ -35,7 +35,7 @@
|
||||
#include <math.h>
|
||||
|
||||
|
||||
static void outputHandleGeometry(void* data,
|
||||
static void outputHandleGeometry(void* userData,
|
||||
struct wl_output* output,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
@@ -46,24 +46,25 @@ static void outputHandleGeometry(void* data,
|
||||
const char* model,
|
||||
int32_t transform)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
struct _GLFWmonitor* monitor = userData;
|
||||
|
||||
monitor->wl.x = x;
|
||||
monitor->wl.y = y;
|
||||
monitor->widthMM = physicalWidth;
|
||||
monitor->heightMM = physicalHeight;
|
||||
|
||||
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
|
||||
if (strlen(monitor->name) == 0)
|
||||
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
|
||||
}
|
||||
|
||||
static void outputHandleMode(void* data,
|
||||
static void outputHandleMode(void* userData,
|
||||
struct wl_output* output,
|
||||
uint32_t flags,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t refresh)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
struct _GLFWmonitor* monitor = userData;
|
||||
GLFWvidmode mode;
|
||||
|
||||
mode.width = width;
|
||||
@@ -82,9 +83,9 @@ static void outputHandleMode(void* data,
|
||||
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)
|
||||
{
|
||||
@@ -94,23 +95,64 @@ static void outputHandleDone(void* data, struct wl_output* output)
|
||||
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);
|
||||
}
|
||||
|
||||
static void outputHandleScale(void* data,
|
||||
static void outputHandleScale(void* userData,
|
||||
struct wl_output* output,
|
||||
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,
|
||||
outputHandleMode,
|
||||
outputHandleDone,
|
||||
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)
|
||||
{
|
||||
_GLFWmonitor *monitor;
|
||||
struct wl_output *output;
|
||||
|
||||
if (version < 2)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
@@ -130,23 +169,26 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
||||
return;
|
||||
}
|
||||
|
||||
// The actual name of this output will be set in the geometry handler.
|
||||
monitor = _glfwAllocMonitor("", 0, 0);
|
||||
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
||||
version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
|
||||
#else
|
||||
version = 2;
|
||||
#endif
|
||||
|
||||
output = wl_registry_bind(_glfw.wl.registry,
|
||||
name,
|
||||
&wl_output_interface,
|
||||
2);
|
||||
struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
|
||||
name,
|
||||
&wl_output_interface,
|
||||
version);
|
||||
if (!output)
|
||||
{
|
||||
_glfwFreeMonitor(monitor);
|
||||
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.name = name;
|
||||
|
||||
wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag);
|
||||
wl_output_add_listener(output, &outputListener, monitor);
|
||||
}
|
||||
|
||||
@@ -173,9 +215,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
if (xscale)
|
||||
*xscale = (float) monitor->wl.scale;
|
||||
*xscale = (float) monitor->wl.contentScale;
|
||||
if (yscale)
|
||||
*yscale = (float) monitor->wl.scale;
|
||||
*yscale = (float) monitor->wl.contentScale;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
|
||||
+232
-57
@@ -26,11 +26,11 @@
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkWaylandSurfaceCreateInfoKHR
|
||||
@@ -67,7 +67,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
#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_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl
|
||||
@@ -112,24 +112,27 @@ typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context
|
||||
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
|
||||
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
|
||||
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
|
||||
typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**);
|
||||
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
|
||||
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 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 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_unref _glfw.wl.xkb.context_unref
|
||||
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
|
||||
#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
|
||||
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
|
||||
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
|
||||
#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
|
||||
#define xkb_state_new _glfw.wl.xkb.state_new
|
||||
#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_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_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
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 struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
|
||||
@@ -144,20 +147,130 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
|
||||
#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
|
||||
#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
|
||||
#endif
|
||||
|
||||
#define _GLFW_DECORATION_WIDTH 4
|
||||
#define _GLFW_DECORATION_TOP 24
|
||||
#define _GLFW_DECORATION_VERTICAL (_GLFW_DECORATION_TOP + _GLFW_DECORATION_WIDTH)
|
||||
#define _GLFW_DECORATION_HORIZONTAL (2 * _GLFW_DECORATION_WIDTH)
|
||||
struct libdecor;
|
||||
struct libdecor_frame;
|
||||
struct libdecor_state;
|
||||
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
|
||||
{
|
||||
mainWindow,
|
||||
topDecoration,
|
||||
leftDecoration,
|
||||
rightDecoration,
|
||||
bottomDecoration,
|
||||
GLFW_MAIN_WINDOW,
|
||||
GLFW_TOP_DECORATION,
|
||||
GLFW_LEFT_DECORATION,
|
||||
GLFW_RIGHT_DECORATION,
|
||||
GLFW_BOTTOM_DECORATION
|
||||
} _GLFWdecorationSideWayland;
|
||||
|
||||
typedef struct _GLFWdecorationWayland
|
||||
@@ -167,6 +280,19 @@ typedef struct _GLFWdecorationWayland
|
||||
struct wp_viewport* viewport;
|
||||
} _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
|
||||
//
|
||||
typedef struct _GLFWwindowWayland
|
||||
@@ -174,19 +300,37 @@ typedef struct _GLFWwindowWayland
|
||||
int width, height;
|
||||
GLFWbool visible;
|
||||
GLFWbool maximized;
|
||||
GLFWbool activated;
|
||||
GLFWbool fullscreen;
|
||||
GLFWbool hovered;
|
||||
GLFWbool transparent;
|
||||
struct wl_surface* surface;
|
||||
struct wl_egl_window* native;
|
||||
struct wl_shell_surface* shellSurface;
|
||||
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 xdg_surface* surface;
|
||||
struct xdg_toplevel* toplevel;
|
||||
struct zxdg_toplevel_decoration_v1* decoration;
|
||||
uint32_t decorationMode;
|
||||
} xdg;
|
||||
|
||||
struct {
|
||||
struct libdecor_frame* frame;
|
||||
int mode;
|
||||
} libdecor;
|
||||
|
||||
_GLFWcursor* currentCursor;
|
||||
double cursorPosX, cursorPosY;
|
||||
|
||||
@@ -194,25 +338,20 @@ typedef struct _GLFWwindowWayland
|
||||
|
||||
// We need to track the monitors the window spans on to calculate the
|
||||
// optimal scaling factor.
|
||||
int scale;
|
||||
_GLFWmonitor** monitors;
|
||||
int monitorsCount;
|
||||
int monitorsSize;
|
||||
int contentScale;
|
||||
_GLFWscaleWayland* scales;
|
||||
int scaleCount;
|
||||
int scaleSize;
|
||||
|
||||
struct {
|
||||
struct zwp_relative_pointer_v1* relativePointer;
|
||||
struct zwp_locked_pointer_v1* lockedPointer;
|
||||
} pointerLock;
|
||||
struct zwp_relative_pointer_v1* relativePointer;
|
||||
struct zwp_locked_pointer_v1* lockedPointer;
|
||||
|
||||
struct zwp_idle_inhibitor_v1* idleInhibitor;
|
||||
|
||||
GLFWbool wasFullscreen;
|
||||
|
||||
struct {
|
||||
GLFWbool serverSide;
|
||||
struct wl_buffer* buffer;
|
||||
_GLFWdecorationWayland top, left, right, bottom;
|
||||
int focus;
|
||||
_GLFWdecorationSideWayland focus;
|
||||
} decorations;
|
||||
} _GLFWwindowWayland;
|
||||
|
||||
@@ -224,15 +363,12 @@ typedef struct _GLFWlibraryWayland
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_subcompositor* subcompositor;
|
||||
struct wl_shell* shell;
|
||||
struct wl_shm* shm;
|
||||
struct wl_seat* seat;
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_keyboard* keyboard;
|
||||
struct wl_data_device_manager* dataDeviceManager;
|
||||
struct wl_data_device* dataDevice;
|
||||
struct wl_data_offer* dataOffer;
|
||||
struct wl_data_source* dataSource;
|
||||
struct xdg_wm_base* wmBase;
|
||||
struct zxdg_decoration_manager_v1* decorationManager;
|
||||
struct wp_viewporter* viewporter;
|
||||
@@ -240,8 +376,17 @@ typedef struct _GLFWlibraryWayland
|
||||
struct zwp_pointer_constraints_v1* pointerConstraints;
|
||||
struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
|
||||
|
||||
int compositorVersion;
|
||||
int seatVersion;
|
||||
_GLFWofferWayland* offers;
|
||||
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* cursorThemeHiDPI;
|
||||
@@ -251,34 +396,29 @@ typedef struct _GLFWlibraryWayland
|
||||
uint32_t serial;
|
||||
uint32_t pointerEnterSerial;
|
||||
|
||||
int32_t keyboardRepeatRate;
|
||||
int32_t keyboardRepeatDelay;
|
||||
int keyboardLastKey;
|
||||
int keyboardLastScancode;
|
||||
int keyRepeatTimerfd;
|
||||
int32_t keyRepeatRate;
|
||||
int32_t keyRepeatDelay;
|
||||
int keyRepeatScancode;
|
||||
|
||||
char* clipboardString;
|
||||
size_t clipboardSize;
|
||||
char* clipboardSendString;
|
||||
size_t clipboardSendSize;
|
||||
int timerfd;
|
||||
short int keycodes[256];
|
||||
short int scancodes[GLFW_KEY_LAST + 1];
|
||||
char keynames[GLFW_KEY_LAST + 1][5];
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
struct xkb_context* context;
|
||||
struct xkb_keymap* keymap;
|
||||
struct xkb_state* state;
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
struct xkb_compose_state* composeState;
|
||||
#endif
|
||||
|
||||
xkb_mod_mask_t controlMask;
|
||||
xkb_mod_mask_t altMask;
|
||||
xkb_mod_mask_t shiftMask;
|
||||
xkb_mod_mask_t superMask;
|
||||
xkb_mod_mask_t capsLockMask;
|
||||
xkb_mod_mask_t numLockMask;
|
||||
xkb_mod_index_t controlIndex;
|
||||
xkb_mod_index_t altIndex;
|
||||
xkb_mod_index_t shiftIndex;
|
||||
xkb_mod_index_t superIndex;
|
||||
xkb_mod_index_t capsLockIndex;
|
||||
xkb_mod_index_t numLockIndex;
|
||||
unsigned int modifiers;
|
||||
|
||||
PFN_xkb_context_new context_new;
|
||||
@@ -287,13 +427,14 @@ typedef struct _GLFWlibraryWayland
|
||||
PFN_xkb_keymap_unref keymap_unref;
|
||||
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
|
||||
PFN_xkb_keymap_key_repeats keymap_key_repeats;
|
||||
PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level;
|
||||
PFN_xkb_state_new state_new;
|
||||
PFN_xkb_state_unref state_unref;
|
||||
PFN_xkb_state_key_get_syms state_key_get_syms;
|
||||
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_mod_index_is_active state_mod_index_is_active;
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
|
||||
PFN_xkb_compose_table_unref compose_table_unref;
|
||||
PFN_xkb_compose_state_new compose_state_new;
|
||||
@@ -301,7 +442,6 @@ typedef struct _GLFWlibraryWayland
|
||||
PFN_xkb_compose_state_feed compose_state_feed;
|
||||
PFN_xkb_compose_state_get_status compose_state_get_status;
|
||||
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
|
||||
#endif
|
||||
} xkb;
|
||||
|
||||
_GLFWwindow* pointerFocus;
|
||||
@@ -323,6 +463,38 @@ typedef struct _GLFWlibraryWayland
|
||||
PFN_wl_egl_window_destroy window_destroy;
|
||||
PFN_wl_egl_window_resize window_resize;
|
||||
} 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;
|
||||
|
||||
// Wayland-specific per-monitor data
|
||||
@@ -335,7 +507,7 @@ typedef struct _GLFWmonitorWayland
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int scale;
|
||||
int contentScale;
|
||||
} _GLFWmonitorWayland;
|
||||
|
||||
// Wayland-specific per-cursor data
|
||||
@@ -350,6 +522,9 @@ typedef struct _GLFWcursorWayland
|
||||
int currentImage;
|
||||
} _GLFWcursorWayland;
|
||||
|
||||
|
||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
|
||||
|
||||
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
||||
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
||||
|
||||
|
||||
+1983
-805
File diff suppressed because it is too large
Load Diff
+71
-2
@@ -36,6 +36,10 @@
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// Translate the X11 KeySyms for a key to a GLFW key code
|
||||
@@ -568,7 +572,11 @@ static void detectEWMH(void)
|
||||
//
|
||||
static GLFWbool initExtensions(void)
|
||||
{
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so");
|
||||
#else
|
||||
_glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
|
||||
#endif
|
||||
if (_glfw.x11.vidmode.handle)
|
||||
{
|
||||
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
||||
@@ -588,6 +596,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so");
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.xi.handle = _glfw_dlopen("libXi.so");
|
||||
#else
|
||||
_glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
|
||||
#endif
|
||||
@@ -618,6 +628,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so");
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so");
|
||||
#else
|
||||
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
|
||||
#endif
|
||||
@@ -710,6 +722,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so");
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so");
|
||||
#else
|
||||
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
|
||||
#endif
|
||||
@@ -721,10 +735,18 @@ static GLFWbool initExtensions(void)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
_glfw.x11.xcursor.GetTheme = (PFN_XcursorGetTheme)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetTheme");
|
||||
_glfw.x11.xcursor.GetDefaultSize = (PFN_XcursorGetDefaultSize)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetDefaultSize");
|
||||
_glfw.x11.xcursor.LibraryLoadImage = (PFN_XcursorLibraryLoadImage)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorLibraryLoadImage");
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so");
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so");
|
||||
#else
|
||||
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
|
||||
#endif
|
||||
@@ -776,6 +798,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so");
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so");
|
||||
#else
|
||||
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
|
||||
#endif
|
||||
@@ -787,6 +811,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so");
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so");
|
||||
#else
|
||||
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
|
||||
#endif
|
||||
@@ -952,6 +978,37 @@ static Window createHelperWindow(void)
|
||||
CWEventMask, &wa);
|
||||
}
|
||||
|
||||
// Create the pipe for empty events without assumuing the OS has pipe2(2)
|
||||
//
|
||||
static GLFWbool createEmptyEventPipe(void)
|
||||
{
|
||||
if (pipe(_glfw.x11.emptyEventPipe) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create empty event pipe: %s",
|
||||
strerror(errno));
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
const int sf = fcntl(_glfw.x11.emptyEventPipe[i], F_GETFL, 0);
|
||||
const int df = fcntl(_glfw.x11.emptyEventPipe[i], F_GETFD, 0);
|
||||
|
||||
if (sf == -1 || df == -1 ||
|
||||
fcntl(_glfw.x11.emptyEventPipe[i], F_SETFL, sf | O_NONBLOCK) == -1 ||
|
||||
fcntl(_glfw.x11.emptyEventPipe[i], F_SETFD, df | FD_CLOEXEC) == -1)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to set flags for empty event pipe: %s",
|
||||
strerror(errno));
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// X error handler
|
||||
//
|
||||
static int errorHandler(Display *display, XErrorEvent* event)
|
||||
@@ -972,8 +1029,9 @@ static int errorHandler(Display *display, XErrorEvent* event)
|
||||
//
|
||||
void _glfwGrabErrorHandlerX11(void)
|
||||
{
|
||||
assert(_glfw.x11.errorHandler == NULL);
|
||||
_glfw.x11.errorCode = Success;
|
||||
XSetErrorHandler(errorHandler);
|
||||
_glfw.x11.errorHandler = XSetErrorHandler(errorHandler);
|
||||
}
|
||||
|
||||
// Clears the X error handler callback
|
||||
@@ -982,7 +1040,8 @@ void _glfwReleaseErrorHandlerX11(void)
|
||||
{
|
||||
// Synchronize to make sure all commands are processed
|
||||
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
|
||||
@@ -1073,6 +1132,9 @@ int _glfwPlatformInit(void)
|
||||
|
||||
getSystemContentScale(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY);
|
||||
|
||||
if (!createEmptyEventPipe())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!initExtensions())
|
||||
return GLFW_FALSE;
|
||||
|
||||
@@ -1182,6 +1244,7 @@ void _glfwPlatformTerminate(void)
|
||||
_glfw.x11.xi.handle = NULL;
|
||||
}
|
||||
|
||||
_glfwTerminateOSMesa();
|
||||
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
||||
// cleanup callbacks that get called by that function
|
||||
_glfwTerminateEGL();
|
||||
@@ -1190,6 +1253,12 @@ void _glfwPlatformTerminate(void)
|
||||
#if defined(__linux__)
|
||||
_glfwTerminateJoysticksLinux();
|
||||
#endif
|
||||
|
||||
if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1])
|
||||
{
|
||||
close(_glfw.x11.emptyEventPipe[0]);
|
||||
close(_glfw.x11.emptyEventPipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
|
||||
@@ -85,9 +85,15 @@ typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
|
||||
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
|
||||
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
|
||||
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
|
||||
typedef char* (* PFN_XcursorGetTheme)(Display*);
|
||||
typedef int (* PFN_XcursorGetDefaultSize)(Display*);
|
||||
typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int);
|
||||
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
|
||||
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
|
||||
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
|
||||
#define XcursorGetTheme _glfw.x11.xcursor.GetTheme
|
||||
#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize
|
||||
#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage
|
||||
|
||||
typedef Bool (* PFN_XineramaIsActive)(Display*);
|
||||
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
|
||||
@@ -222,6 +228,8 @@ typedef struct _GLFWlibraryX11
|
||||
XContext context;
|
||||
// XIM input method
|
||||
XIM im;
|
||||
// The previous X error handler, to be restored later
|
||||
XErrorHandler errorHandler;
|
||||
// Most recent error code received by X error handler
|
||||
int errorCode;
|
||||
// Primary selection string (while the primary selection is owned)
|
||||
@@ -238,6 +246,7 @@ typedef struct _GLFWlibraryX11
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
// The window whose disabled cursor mode is active
|
||||
_GLFWwindow* disabledCursorWindow;
|
||||
int emptyEventPipe[2];
|
||||
|
||||
// Window manager atoms
|
||||
Atom NET_SUPPORTED;
|
||||
@@ -353,6 +362,9 @@ typedef struct _GLFWlibraryX11
|
||||
PFN_XcursorImageCreate ImageCreate;
|
||||
PFN_XcursorImageDestroy ImageDestroy;
|
||||
PFN_XcursorImageLoadCursor ImageLoadCursor;
|
||||
PFN_XcursorGetTheme GetTheme;
|
||||
PFN_XcursorGetDefaultSize GetDefaultSize;
|
||||
PFN_XcursorLibraryLoadImage LibraryLoadImage;
|
||||
} xcursor;
|
||||
|
||||
struct {
|
||||
|
||||
+320
-224
@@ -27,12 +27,16 @@
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/Xmd.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -56,50 +60,126 @@
|
||||
|
||||
#define _GLFW_XDND_VERSION 5
|
||||
|
||||
|
||||
// Wait for data to arrive using select
|
||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||
// covers GLX functions
|
||||
// Wait for data to arrive on any of the specified file descriptors
|
||||
//
|
||||
static GLFWbool waitForEvent(double* timeout)
|
||||
static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout)
|
||||
{
|
||||
fd_set fds;
|
||||
const int fd = ConnectionNumber(_glfw.x11.display);
|
||||
int count = fd + 1;
|
||||
|
||||
#if defined(__linux__)
|
||||
if (_glfw.linjs.inotify > fd)
|
||||
count = _glfw.linjs.inotify + 1;
|
||||
#endif
|
||||
for (;;)
|
||||
{
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
#if defined(__linux__)
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
FD_SET(_glfw.linjs.inotify, &fds);
|
||||
#endif
|
||||
|
||||
if (timeout)
|
||||
{
|
||||
const long seconds = (long) *timeout;
|
||||
const long microseconds = (long) ((*timeout - seconds) * 1e6);
|
||||
struct timeval tv = { seconds, microseconds };
|
||||
const uint64_t base = _glfwPlatformGetTimerValue();
|
||||
|
||||
const int result = select(count, &fds, NULL, NULL, &tv);
|
||||
const int error = errno;
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
const time_t seconds = (time_t) *timeout;
|
||||
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||
const struct timespec ts = { seconds, nanoseconds };
|
||||
const int result = ppoll(fds, count, &ts, NULL);
|
||||
#elif defined(__NetBSD__)
|
||||
const time_t seconds = (time_t) *timeout;
|
||||
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||
const struct timespec ts = { seconds, nanoseconds };
|
||||
const int result = pollts(fds, count, &ts, NULL);
|
||||
#else
|
||||
const int milliseconds = (int) (*timeout * 1e3);
|
||||
const int result = poll(fds, count, milliseconds);
|
||||
#endif
|
||||
const int error = errno; // clock_gettime may overwrite our error
|
||||
|
||||
*timeout -= (_glfwPlatformGetTimerValue() - base) /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
if ((result == -1 && error == EINTR) || *timeout <= 0.0)
|
||||
else if (result == -1 && error != EINTR && error != EAGAIN)
|
||||
return GLFW_FALSE;
|
||||
else if (*timeout <= 0.0)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
|
||||
return GLFW_TRUE;
|
||||
else
|
||||
{
|
||||
const int result = poll(fds, count, -1);
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
else if (result == -1 && errno != EINTR && errno != EAGAIN)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for event data to arrive on the X11 display socket
|
||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||
// covers GLX functions
|
||||
//
|
||||
static GLFWbool waitForX11Event(double* timeout)
|
||||
{
|
||||
struct pollfd fd = { ConnectionNumber(_glfw.x11.display), POLLIN };
|
||||
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
if (!waitForData(&fd, 1, timeout))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Wait for event data to arrive on any event file descriptor
|
||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||
// covers GLX functions
|
||||
//
|
||||
static GLFWbool waitForAnyEvent(double* timeout)
|
||||
{
|
||||
nfds_t count = 2;
|
||||
struct pollfd fds[3] =
|
||||
{
|
||||
{ ConnectionNumber(_glfw.x11.display), POLLIN },
|
||||
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
||||
};
|
||||
|
||||
#if defined(__linux__)
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
|
||||
#endif
|
||||
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
if (!waitForData(fds, count, timeout))
|
||||
return GLFW_FALSE;
|
||||
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
if (fds[i].revents & POLLIN)
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Writes a byte to the empty event pipe
|
||||
//
|
||||
static void writeEmptyEvent(void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const char byte = 0;
|
||||
const ssize_t result = write(_glfw.x11.emptyEventPipe[1], &byte, 1);
|
||||
if (result == 1 || (result == -1 && errno != EINTR))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Drains available data from the empty event pipe
|
||||
//
|
||||
static void drainEmptyEvents(void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
char dummy[64];
|
||||
const ssize_t result = read(_glfw.x11.emptyEventPipe[0], dummy, sizeof(dummy));
|
||||
if (result == -1 && errno != EINTR)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +196,7 @@ static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
|
||||
VisibilityNotify,
|
||||
&dummy))
|
||||
{
|
||||
if (!waitForEvent(&timeout))
|
||||
if (!waitForX11Event(&timeout))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
@@ -241,6 +321,11 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
XSizeHints* hints = XAllocSizeHints();
|
||||
|
||||
long supplied;
|
||||
XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied);
|
||||
|
||||
hints->flags &= ~(PMinSize | PMaxSize | PAspect);
|
||||
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (window->resizable)
|
||||
@@ -277,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);
|
||||
XFree(hints);
|
||||
}
|
||||
@@ -378,96 +460,14 @@ 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;
|
||||
}
|
||||
|
||||
// Encode a Unicode code point to a UTF-8 stream
|
||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||
//
|
||||
static size_t encodeUTF8(char* s, unsigned int ch)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
if (ch < 0x80)
|
||||
s[count++] = (char) ch;
|
||||
else if (ch < 0x800)
|
||||
{
|
||||
s[count++] = (ch >> 6) | 0xc0;
|
||||
s[count++] = (ch & 0x3f) | 0x80;
|
||||
}
|
||||
else if (ch < 0x10000)
|
||||
{
|
||||
s[count++] = (ch >> 12) | 0xe0;
|
||||
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
||||
s[count++] = (ch & 0x3f) | 0x80;
|
||||
}
|
||||
else if (ch < 0x110000)
|
||||
{
|
||||
s[count++] = (ch >> 18) | 0xf0;
|
||||
s[count++] = ((ch >> 12) & 0x3f) | 0x80;
|
||||
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
||||
s[count++] = (ch & 0x3f) | 0x80;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Decode a Unicode code point from a UTF-8 stream
|
||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||
//
|
||||
#if defined(X_HAVE_UTF8_STRING)
|
||||
static unsigned int decodeUTF8(const char** s)
|
||||
static uint32_t decodeUTF8(const char** s)
|
||||
{
|
||||
unsigned int ch = 0, count = 0;
|
||||
static const unsigned int offsets[] =
|
||||
uint32_t codepoint = 0, count = 0;
|
||||
static const uint32_t offsets[] =
|
||||
{
|
||||
0x00000000u, 0x00003080u, 0x000e2080u,
|
||||
0x03c82080u, 0xfa082080u, 0x82082080u
|
||||
@@ -475,13 +475,13 @@ static unsigned int decodeUTF8(const char** s)
|
||||
|
||||
do
|
||||
{
|
||||
ch = (ch << 6) + (unsigned char) **s;
|
||||
codepoint = (codepoint << 6) + (unsigned char) **s;
|
||||
(*s)++;
|
||||
count++;
|
||||
} while ((**s & 0xc0) == 0x80);
|
||||
|
||||
assert(count <= 6);
|
||||
return ch - offsets[count - 1];
|
||||
return codepoint - offsets[count - 1];
|
||||
}
|
||||
#endif /*X_HAVE_UTF8_STRING*/
|
||||
|
||||
@@ -499,7 +499,7 @@ static char* convertLatin1toUTF8(const char* source)
|
||||
char* tp = target;
|
||||
|
||||
for (sp = source; *sp; sp++)
|
||||
tp += encodeUTF8(tp, *sp);
|
||||
tp += _glfwEncodeUTF8(tp, *sp);
|
||||
|
||||
return target;
|
||||
}
|
||||
@@ -525,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
|
||||
//
|
||||
static void enableRawMouseMotion(_GLFWwindow* window)
|
||||
@@ -567,12 +586,7 @@ static void disableCursor(_GLFWwindow* window)
|
||||
&_glfw.x11.restoreCursorPosY);
|
||||
updateCursorImage(window);
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
window->x11.handle,
|
||||
_glfw.x11.hiddenCursorHandle,
|
||||
CurrentTime);
|
||||
captureCursor(window);
|
||||
}
|
||||
|
||||
// Exit disabled cursor mode for the specified window
|
||||
@@ -583,7 +597,7 @@ static void enableCursor(_GLFWwindow* window)
|
||||
disableRawMouseMotion(window);
|
||||
|
||||
_glfw.x11.disabledCursorWindow = NULL;
|
||||
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
||||
releaseCursor();
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.x11.restoreCursorPosX,
|
||||
_glfw.x11.restoreCursorPosY);
|
||||
@@ -728,7 +742,28 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
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
|
||||
{
|
||||
@@ -931,20 +966,6 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
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)
|
||||
{
|
||||
const XSelectionRequestEvent* request = &event->xselectionrequest;
|
||||
@@ -1002,7 +1023,7 @@ static const char* getSelectionString(Atom selection)
|
||||
SelectionNotify,
|
||||
¬ification))
|
||||
{
|
||||
waitForEvent(NULL);
|
||||
waitForX11Event(NULL);
|
||||
}
|
||||
|
||||
if (notification.xselection.property == None)
|
||||
@@ -1038,7 +1059,7 @@ static const char* getSelectionString(Atom selection)
|
||||
isSelPropNewValueNotify,
|
||||
(XPointer) ¬ification))
|
||||
{
|
||||
waitForEvent(NULL);
|
||||
waitForX11Event(NULL);
|
||||
}
|
||||
|
||||
XFree(data);
|
||||
@@ -1065,13 +1086,16 @@ static const char* getSelectionString(Atom selection)
|
||||
|
||||
if (!itemCount)
|
||||
{
|
||||
if (targets[i] == XA_STRING)
|
||||
if (string)
|
||||
{
|
||||
*selectionString = convertLatin1toUTF8(string);
|
||||
free(string);
|
||||
if (targets[i] == XA_STRING)
|
||||
{
|
||||
*selectionString = convertLatin1toUTF8(string);
|
||||
free(string);
|
||||
}
|
||||
else
|
||||
*selectionString = string;
|
||||
}
|
||||
else
|
||||
*selectionString = string;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1238,12 +1262,7 @@ static void processEvent(XEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == SelectionClear)
|
||||
{
|
||||
handleSelectionClear(event);
|
||||
return;
|
||||
}
|
||||
else if (event->type == SelectionRequest)
|
||||
if (event->type == SelectionRequest)
|
||||
{
|
||||
handleSelectionRequest(event);
|
||||
return;
|
||||
@@ -1283,7 +1302,7 @@ static void processEvent(XEvent *event)
|
||||
// (the server never sends a timestamp of zero)
|
||||
// NOTE: Timestamp difference is compared to handle wrap-around
|
||||
Time diff = event->xkey.time - window->x11.keyPressTimes[keycode];
|
||||
if (diff == event->xkey.time || (diff > 0 && diff < (1 << 31)))
|
||||
if (diff == event->xkey.time || (diff > 0 && diff < ((Time)1 << 31)))
|
||||
{
|
||||
if (keycode)
|
||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||
@@ -1359,9 +1378,9 @@ static void processEvent(XEvent *event)
|
||||
|
||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||
|
||||
const long character = _glfwKeySym2Unicode(keysym);
|
||||
if (character != -1)
|
||||
_glfwInputChar(window, character, mods, plain);
|
||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||
if (codepoint != GLFW_INVALID_CODEPOINT)
|
||||
_glfwInputChar(window, codepoint, mods, plain);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1759,7 +1778,7 @@ static void processEvent(XEvent *event)
|
||||
if (result)
|
||||
{
|
||||
int i, count;
|
||||
char** paths = parseUriList(data, &count);
|
||||
char** paths = _glfwParseUriList(data, &count);
|
||||
|
||||
_glfwInputDrop(window, count, (const char**) paths);
|
||||
|
||||
@@ -1948,10 +1967,6 @@ void _glfwPushSelectionToManagerX11(void)
|
||||
handleSelectionRequest(&event);
|
||||
break;
|
||||
|
||||
case SelectionClear:
|
||||
handleSelectionClear(&event);
|
||||
break;
|
||||
|
||||
case SelectionNotify:
|
||||
{
|
||||
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
|
||||
@@ -1969,7 +1984,7 @@ void _glfwPushSelectionToManagerX11(void)
|
||||
}
|
||||
}
|
||||
|
||||
waitForEvent(NULL);
|
||||
waitForX11Event(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2035,6 +2050,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
@@ -2042,6 +2060,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
_glfwPlatformShowWindow(window);
|
||||
updateWindowMode(window);
|
||||
acquireMonitor(window);
|
||||
|
||||
if (wndconfig->centerCursor)
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
_glfwPlatformShowWindow(window);
|
||||
if (wndconfig->focused)
|
||||
_glfwPlatformFocusWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
XFlush(_glfw.x11.display);
|
||||
@@ -2051,7 +2081,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.x11.disabledCursorWindow == window)
|
||||
_glfw.x11.disabledCursorWindow = NULL;
|
||||
enableCursor(window);
|
||||
|
||||
if (window->monitor)
|
||||
releaseMonitor(window);
|
||||
@@ -2123,8 +2153,8 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
for (i = 0; i < count; i++)
|
||||
longCount += 2 + images[i].width * images[i].height;
|
||||
|
||||
long* icon = calloc(longCount, sizeof(long));
|
||||
long* target = icon;
|
||||
unsigned long* icon = calloc(longCount, sizeof(unsigned long));
|
||||
unsigned long* target = icon;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
@@ -2133,13 +2163,19 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
|
||||
for (j = 0; j < images[i].width * images[i].height; j++)
|
||||
{
|
||||
*target++ = (images[i].pixels[j * 4 + 0] << 16) |
|
||||
(images[i].pixels[j * 4 + 1] << 8) |
|
||||
(images[i].pixels[j * 4 + 2] << 0) |
|
||||
(images[i].pixels[j * 4 + 3] << 24);
|
||||
*target++ = (((unsigned long) images[i].pixels[j * 4 + 0]) << 16) |
|
||||
(((unsigned long) images[i].pixels[j * 4 + 1]) << 8) |
|
||||
(((unsigned long) images[i].pixels[j * 4 + 2]) << 0) |
|
||||
(((unsigned long) images[i].pixels[j * 4 + 3]) << 24);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: XChangeProperty expects 32-bit values like the image data above to be
|
||||
// placed in the 32 least significant bits of individual longs. This is
|
||||
// true even if long is 64-bit and a WM protocol calls for "packed" data.
|
||||
// This is because of a historical mistake that then became part of the Xlib
|
||||
// ABI. Xlib will pack these values into a regular array of 32-bit values
|
||||
// before sending it over the wire.
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_ICON,
|
||||
XA_CARDINAL, 32,
|
||||
@@ -2281,7 +2317,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
isFrameExtentsEvent,
|
||||
(XPointer) window))
|
||||
{
|
||||
if (!waitForEvent(&timeout))
|
||||
if (!waitForX11Event(&timeout))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
|
||||
@@ -2773,7 +2809,7 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void)
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
drainEmptyEvents();
|
||||
|
||||
#if defined(__linux__)
|
||||
_glfwDetectJoystickConnectionLinux();
|
||||
@@ -2787,7 +2823,7 @@ void _glfwPlatformPollEvents(void)
|
||||
processEvent(&event);
|
||||
}
|
||||
|
||||
window = _glfw.x11.disabledCursorWindow;
|
||||
_GLFWwindow* window = _glfw.x11.disabledCursorWindow;
|
||||
if (window)
|
||||
{
|
||||
int width, height;
|
||||
@@ -2807,32 +2843,19 @@ void _glfwPlatformPollEvents(void)
|
||||
|
||||
void _glfwPlatformWaitEvents(void)
|
||||
{
|
||||
while (!XPending(_glfw.x11.display))
|
||||
waitForEvent(NULL);
|
||||
|
||||
waitForAnyEvent(NULL);
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
{
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
if (!waitForEvent(&timeout))
|
||||
break;
|
||||
}
|
||||
|
||||
waitForAnyEvent(&timeout);
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
XEvent event = { ClientMessage };
|
||||
event.xclient.window = _glfw.x11.helperWindowHandle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = _glfw.x11.NULL_;
|
||||
|
||||
XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
|
||||
XFlush(_glfw.x11.display);
|
||||
writeEmptyEvent();
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
@@ -2865,16 +2888,40 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
{
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
disableCursor(window);
|
||||
}
|
||||
else if (_glfw.x11.disabledCursorWindow == window)
|
||||
enableCursor(window);
|
||||
else
|
||||
updateCursorImage(window);
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.x11.restoreCursorPosX,
|
||||
&_glfw.x11.restoreCursorPosY);
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
if (window->rawMouseMotion)
|
||||
enableRawMouseMotion(window);
|
||||
}
|
||||
else if (_glfw.x11.disabledCursorWindow == window)
|
||||
{
|
||||
if (window->rawMouseMotion)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -2883,24 +2930,26 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
||||
if (!_glfw.x11.xkb.available)
|
||||
return NULL;
|
||||
|
||||
if (scancode < 0 || scancode > 0xff ||
|
||||
_glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||
if (scancode < 0 || scancode > 0xff)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int key = _glfw.x11.keycodes[scancode];
|
||||
if (key == GLFW_KEY_UNKNOWN)
|
||||
return NULL;
|
||||
|
||||
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display,
|
||||
scancode, _glfw.x11.xkb.group, 0);
|
||||
if (keysym == NoSymbol)
|
||||
return NULL;
|
||||
|
||||
const long ch = _glfwKeySym2Unicode(keysym);
|
||||
if (ch == -1)
|
||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||
if (codepoint == GLFW_INVALID_CODEPOINT)
|
||||
return NULL;
|
||||
|
||||
const size_t count = encodeUTF8(_glfw.x11.keynames[key], (unsigned int) ch);
|
||||
const size_t count = _glfwEncodeUTF8(_glfw.x11.keynames[key], codepoint);
|
||||
if (count == 0)
|
||||
return NULL;
|
||||
|
||||
@@ -2926,29 +2975,76 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
int native = 0;
|
||||
if (_glfw.x11.xcursor.handle)
|
||||
{
|
||||
char* theme = XcursorGetTheme(_glfw.x11.display);
|
||||
if (theme)
|
||||
{
|
||||
const int size = XcursorGetDefaultSize(_glfw.x11.display);
|
||||
const char* name = NULL;
|
||||
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
native = XC_left_ptr;
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
native = XC_xterm;
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
native = XC_crosshair;
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
native = XC_hand2;
|
||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||
native = XC_sb_h_double_arrow;
|
||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||
native = XC_sb_v_double_arrow;
|
||||
else
|
||||
return GLFW_FALSE;
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
name = "default";
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
name = "text";
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
name = "crosshair";
|
||||
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||
name = "pointer";
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
name = "ew-resize";
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
name = "ns-resize";
|
||||
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||
name = "nwse-resize";
|
||||
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||
name = "nesw-resize";
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
name = "all-scroll";
|
||||
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||
name = "not-allowed";
|
||||
|
||||
XcursorImage* image = XcursorLibraryLoadImage(name, theme, size);
|
||||
if (image)
|
||||
{
|
||||
cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, image);
|
||||
XcursorImageDestroy(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||
if (!cursor->x11.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create standard cursor");
|
||||
return GLFW_FALSE;
|
||||
unsigned int native = 0;
|
||||
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
native = XC_left_ptr;
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
native = XC_xterm;
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
native = XC_crosshair;
|
||||
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||
native = XC_hand2;
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
native = XC_sb_h_double_arrow;
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
native = XC_sb_v_double_arrow;
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
native = XC_fleur;
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
|
||||
"X11: Standard cursor shape unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||
if (!cursor->x11.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create standard cursor");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
|
||||
+2
-2
@@ -907,7 +907,7 @@ static const struct codepair {
|
||||
|
||||
// Convert XKB KeySym to Unicode
|
||||
//
|
||||
long _glfwKeySym2Unicode(unsigned int keysym)
|
||||
uint32_t _glfwKeySym2Unicode(unsigned int keysym)
|
||||
{
|
||||
int min = 0;
|
||||
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
|
||||
@@ -937,6 +937,6 @@ long _glfwKeySym2Unicode(unsigned int keysym)
|
||||
}
|
||||
|
||||
// No matching Unicode value found
|
||||
return -1;
|
||||
return GLFW_INVALID_CODEPOINT;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -24,5 +24,7 @@
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
long _glfwKeySym2Unicode(unsigned int keysym);
|
||||
#define GLFW_INVALID_CODEPOINT 0xffffffffu
|
||||
|
||||
uint32_t _glfwKeySym2Unicode(unsigned int keysym);
|
||||
|
||||
|
||||
+20
-25
@@ -69,7 +69,7 @@ static int swap_interval = 1;
|
||||
static int wait_events = GLFW_TRUE;
|
||||
static int animate_cursor = GLFW_FALSE;
|
||||
static int track_cursor = GLFW_FALSE;
|
||||
static GLFWcursor* standard_cursors[6];
|
||||
static GLFWcursor* standard_cursors[10];
|
||||
static GLFWcursor* tracking_cursor = NULL;
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
@@ -271,28 +271,24 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
|
||||
break;
|
||||
|
||||
case GLFW_KEY_1:
|
||||
glfwSetCursor(window, standard_cursors[0]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_2:
|
||||
glfwSetCursor(window, standard_cursors[1]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_3:
|
||||
glfwSetCursor(window, standard_cursors[2]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_4:
|
||||
glfwSetCursor(window, standard_cursors[3]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_5:
|
||||
glfwSetCursor(window, standard_cursors[4]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_6:
|
||||
glfwSetCursor(window, standard_cursors[5]);
|
||||
case GLFW_KEY_7:
|
||||
case GLFW_KEY_8:
|
||||
case GLFW_KEY_9:
|
||||
{
|
||||
int index = key - GLFW_KEY_1;
|
||||
if (mods & GLFW_MOD_SHIFT)
|
||||
index += 9;
|
||||
|
||||
if (index < sizeof(standard_cursors) / sizeof(standard_cursors[0]))
|
||||
glfwSetCursor(window, standard_cursors[index]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GLFW_KEY_F11:
|
||||
case GLFW_KEY_ENTER:
|
||||
@@ -358,17 +354,16 @@ int main(void)
|
||||
GLFW_ARROW_CURSOR,
|
||||
GLFW_IBEAM_CURSOR,
|
||||
GLFW_CROSSHAIR_CURSOR,
|
||||
GLFW_HAND_CURSOR,
|
||||
GLFW_HRESIZE_CURSOR,
|
||||
GLFW_VRESIZE_CURSOR
|
||||
GLFW_POINTING_HAND_CURSOR,
|
||||
GLFW_RESIZE_EW_CURSOR,
|
||||
GLFW_RESIZE_NS_CURSOR,
|
||||
GLFW_RESIZE_NWSE_CURSOR,
|
||||
GLFW_RESIZE_NESW_CURSOR,
|
||||
GLFW_RESIZE_ALL_CURSOR,
|
||||
GLFW_NOT_ALLOWED_CURSOR
|
||||
};
|
||||
|
||||
standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
|
||||
if (!standard_cursors[i])
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
|
||||
+24
-14
@@ -393,24 +393,34 @@ static void scroll_callback(GLFWwindow* window, double x, double y)
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
Slot* slot = glfwGetWindowUserPointer(window);
|
||||
const char* name = glfwGetKeyName(key, scancode);
|
||||
|
||||
if (name)
|
||||
if (key == GLFW_KEY_UNKNOWN)
|
||||
{
|
||||
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n",
|
||||
counter++, slot->number, glfwGetTime(), key, scancode,
|
||||
get_key_name(key),
|
||||
name,
|
||||
get_mods_name(mods),
|
||||
get_action_name(action));
|
||||
printf("%08x to %i at %0.3f: Key (%s) Scancode 0x%04x (with%s) was %s\n",
|
||||
counter++, slot->number, glfwGetTime(),
|
||||
get_key_name(key), scancode,
|
||||
get_mods_name(mods),
|
||||
get_action_name(action));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n",
|
||||
counter++, slot->number, glfwGetTime(), key, scancode,
|
||||
get_key_name(key),
|
||||
get_mods_name(mods),
|
||||
get_action_name(action));
|
||||
const char* name = glfwGetKeyName(key, scancode);
|
||||
if (name)
|
||||
{
|
||||
printf("%08x to %i at %0.3f: Key 0x%04x (%s) Scancode 0x%04x Name %s (with%s) was %s\n",
|
||||
counter++, slot->number, glfwGetTime(),
|
||||
key, get_key_name(key), scancode, name,
|
||||
get_mods_name(mods),
|
||||
get_action_name(action));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%08x to %i at %0.3f: Key 0x%04x (%s) Scancode 0x%04x (with%s) was %s\n",
|
||||
counter++, slot->number, glfwGetTime(),
|
||||
key, get_key_name(key), scancode,
|
||||
get_mods_name(mods),
|
||||
get_action_name(action));
|
||||
}
|
||||
}
|
||||
|
||||
if (action != GLFW_PRESS)
|
||||
@@ -621,7 +631,7 @@ int main(int argc, char** argv)
|
||||
|
||||
glfwMakeContextCurrent(slots[i].window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
glfwSwapInterval(1);
|
||||
glfwSwapBuffers(slots[i].window);
|
||||
}
|
||||
|
||||
printf("Main loop starting\n");
|
||||
|
||||
@@ -111,6 +111,12 @@ int main(int argc, char** argv)
|
||||
|
||||
{
|
||||
const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor);
|
||||
if (!ramp)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
const size_t array_size = ramp->size * sizeof(short);
|
||||
orig_ramp.size = ramp->size;
|
||||
orig_ramp.red = malloc(array_size);
|
||||
|
||||
+132
-81
@@ -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)
|
||||
{
|
||||
uint32_t i, lp_count = 0;
|
||||
@@ -254,39 +230,16 @@ static void list_vulkan_instance_layers(void)
|
||||
|
||||
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].specVersion >> 22,
|
||||
VK_VERSION_MAJOR(lp[i].specVersion),
|
||||
VK_VERSION_MINOR(lp[i].specVersion),
|
||||
lp[i].description);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
printf(" %s (v%u) \"%s\"\n",
|
||||
printf(" %s (spec version %u.%u) \"%s\"\n",
|
||||
lp[i].layerName,
|
||||
lp[i].specVersion >> 22,
|
||||
VK_VERSION_MAJOR(lp[i].specVersion),
|
||||
VK_VERSION_MINOR(lp[i].specVersion),
|
||||
lp[i].description);
|
||||
}
|
||||
|
||||
@@ -346,11 +300,6 @@ static void print_version(void)
|
||||
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 ch, client, major, minor, revision, profile;
|
||||
@@ -806,20 +755,33 @@ int main(int argc, char** argv)
|
||||
if (list_extensions)
|
||||
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",
|
||||
glfwVulkanSupported() ? "available" : "missing");
|
||||
|
||||
if (glfwVulkanSupported())
|
||||
{
|
||||
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;
|
||||
VkApplicationInfo ai = {0};
|
||||
VkInstanceCreateInfo ici = {0};
|
||||
VkInstance instance;
|
||||
VkPhysicalDevice* pd;
|
||||
|
||||
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL);
|
||||
gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL);
|
||||
|
||||
if (vkEnumerateInstanceVersion)
|
||||
{
|
||||
@@ -832,20 +794,47 @@ int main(int argc, char** argv)
|
||||
VK_VERSION_MAJOR(loader_version),
|
||||
VK_VERSION_MINOR(loader_version));
|
||||
|
||||
re = glfwGetRequiredInstanceExtensions(&re_count);
|
||||
glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count);
|
||||
|
||||
printf("Vulkan required instance extensions:");
|
||||
if (re)
|
||||
re_count = glfw_re_count;
|
||||
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++)
|
||||
printf(" %s", re[i]);
|
||||
putchar('\n');
|
||||
for (i = 0; i < glfw_re_count; i++)
|
||||
{
|
||||
printf(" %s\n", glfw_re[i]);
|
||||
re[i] = glfw_re[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(" missing\n");
|
||||
|
||||
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL);
|
||||
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
||||
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep);
|
||||
|
||||
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)
|
||||
list_vulkan_instance_layers();
|
||||
@@ -866,34 +855,40 @@ int main(int argc, char** argv)
|
||||
ici.enabledExtensionCount = re_count;
|
||||
ici.ppEnabledExtensionNames = re;
|
||||
|
||||
if (portability_enumeration)
|
||||
ici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
|
||||
|
||||
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, instance);
|
||||
|
||||
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
|
||||
if (re)
|
||||
{
|
||||
vkDestroyInstance(instance, NULL);
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
|
||||
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));
|
||||
|
||||
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
|
||||
{
|
||||
free(pd);
|
||||
vkDestroyInstance(instance, NULL);
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
vkEnumeratePhysicalDevices(instance, &pd_count, pd);
|
||||
|
||||
for (i = 0; i < pd_count; i++)
|
||||
{
|
||||
VkPhysicalDeviceProperties pdp;
|
||||
uint32_t qfp_count, ep_count;
|
||||
|
||||
vkGetPhysicalDeviceProperties(pd[i], &pdp);
|
||||
|
||||
@@ -903,8 +898,62 @@ int main(int argc, char** argv)
|
||||
VK_VERSION_MAJOR(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)
|
||||
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)
|
||||
list_vulkan_device_layers(instance, pd[i]);
|
||||
@@ -914,6 +963,8 @@ int main(int argc, char** argv)
|
||||
vkDestroyInstance(instance, NULL);
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
static int windowed_xpos, windowed_ypos, windowed_width, windowed_height;
|
||||
static int windowed_xpos, windowed_ypos, windowed_width = 640, windowed_height = 480;
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
@@ -180,8 +180,8 @@ static GLFWwindow* create_window(GLFWmonitor* monitor)
|
||||
}
|
||||
else
|
||||
{
|
||||
width = 640;
|
||||
height = 480;
|
||||
width = windowed_width;
|
||||
height = windowed_height;
|
||||
}
|
||||
|
||||
window = glfwCreateWindow(width, height, "Iconify", monitor, NULL);
|
||||
|
||||
+15
-9
@@ -65,11 +65,6 @@
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
static GLADapiproc glad_vulkan_callback(const char* name, void* user)
|
||||
{
|
||||
return glfwGetInstanceProcAddress((VkInstance) user, name);
|
||||
}
|
||||
|
||||
static const uint32_t fragShaderCode[] = {
|
||||
0x07230203,0x00010000,0x00080007,0x00000014,0x00000000,0x00020011,0x00000001,0x0006000b,
|
||||
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
|
||||
@@ -1251,7 +1246,7 @@ static void demo_prepare_pipeline(struct demo *demo) {
|
||||
VkPipelineDepthStencilStateCreateInfo ds;
|
||||
VkPipelineViewportStateCreateInfo vp;
|
||||
VkPipelineMultisampleStateCreateInfo ms;
|
||||
VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE];
|
||||
VkDynamicState dynamicStateEnables[2];
|
||||
VkPipelineDynamicStateCreateInfo dynamicState;
|
||||
|
||||
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) {
|
||||
VkResult err;
|
||||
VkBool32 portability_enumeration = VK_FALSE;
|
||||
uint32_t i = 0;
|
||||
uint32_t required_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);
|
||||
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);
|
||||
@@ -1696,6 +1699,9 @@ static void demo_init_vk(struct demo *demo) {
|
||||
.ppEnabledExtensionNames = (const char *const *)demo->extension_names,
|
||||
};
|
||||
|
||||
if (portability_enumeration)
|
||||
inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
|
||||
|
||||
uint32_t gpu_count;
|
||||
|
||||
err = vkCreateInstance(&inst_info, NULL, &demo->inst);
|
||||
@@ -1715,7 +1721,7 @@ static void demo_init_vk(struct demo *demo) {
|
||||
"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*/
|
||||
err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL);
|
||||
@@ -1738,7 +1744,7 @@ static void demo_init_vk(struct demo *demo) {
|
||||
"vkEnumeratePhysicalDevices Failure");
|
||||
}
|
||||
|
||||
gladLoadVulkanUserPtr(demo->gpu, glad_vulkan_callback, demo->inst);
|
||||
gladLoadVulkanUserPtr(demo->gpu, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, demo->inst);
|
||||
|
||||
/* Look for device extensions */
|
||||
uint32_t device_extension_count = 0;
|
||||
@@ -1966,7 +1972,7 @@ static void demo_init_connection(struct demo *demo) {
|
||||
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[])
|
||||
|
||||
Reference in New Issue
Block a user