mirror of
https://github.com/glfw/glfw.git
synced 2025-02-28 13:52:54 +00:00
Merge remote-tracking branch 'glfw/master'
This commit is contained in:
commit
f6bd029869
@ -27,7 +27,6 @@ option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE})
|
||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ${GLFW_STANDALONE})
|
||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
||||
option(GLFW_INSTALL "Generate installation target" ON)
|
||||
option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the application" OFF)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(CMakeDependentOption)
|
||||
|
234
CONTRIBUTORS.md
Normal file
234
CONTRIBUTORS.md
Normal file
@ -0,0 +1,234 @@
|
||||
# Acknowledgements
|
||||
|
||||
GLFW exists because people around the world donated their time and lent their
|
||||
skills. This list only includes contributions to the main repository and
|
||||
excludes other invaluable contributions like language bindings and text and
|
||||
video tutorials.
|
||||
|
||||
- Bobyshev Alexander
|
||||
- Laurent Aphecetche
|
||||
- Matt Arsenault
|
||||
- ashishgamedev
|
||||
- David Avedissian
|
||||
- Keith Bauer
|
||||
- John Bartholomew
|
||||
- Coşku Baş
|
||||
- Niklas Behrens
|
||||
- Andrew Belt
|
||||
- Nevyn Bengtsson
|
||||
- Niklas Bergström
|
||||
- Denis Bernard
|
||||
- Doug Binks
|
||||
- blanco
|
||||
- Waris Boonyasiriwat
|
||||
- Kyle Brenneman
|
||||
- Rok Breulj
|
||||
- Kai Burjack
|
||||
- Martin Capitanio
|
||||
- Nicolas Caramelli
|
||||
- David Carlier
|
||||
- Arturo Castro
|
||||
- Chi-kwan Chan
|
||||
- Joseph Chua
|
||||
- Ian Clarkson
|
||||
- Michał Cichoń
|
||||
- Lambert Clara
|
||||
- Anna Clarke
|
||||
- Josh Codd
|
||||
- Yaron Cohen-Tal
|
||||
- Omar Cornut
|
||||
- Andrew Corrigan
|
||||
- Bailey Cosier
|
||||
- Noel Cower
|
||||
- CuriouserThing
|
||||
- Jason Daly
|
||||
- Jarrod Davis
|
||||
- Olivier Delannoy
|
||||
- Paul R. Deppe
|
||||
- Michael Dickens
|
||||
- Роман Донченко
|
||||
- Mario Dorn
|
||||
- Wolfgang Draxinger
|
||||
- Jonathan Dummer
|
||||
- Ralph Eastwood
|
||||
- Fredrik Ehnbom
|
||||
- Robin Eklind
|
||||
- Jan Ekström
|
||||
- Siavash Eliasi
|
||||
- Ahmad Fatoum
|
||||
- Felipe Ferreira
|
||||
- Michael Fogleman
|
||||
- Jason Francis
|
||||
- Gerald Franz
|
||||
- Mário Freitas
|
||||
- GeO4d
|
||||
- Marcus Geelnard
|
||||
- ghuser404
|
||||
- Charles Giessen
|
||||
- Ryan C. Gordon
|
||||
- Stephen Gowen
|
||||
- Kovid Goyal
|
||||
- Eloi Marín Gratacós
|
||||
- Stefan Gustavson
|
||||
- Andrew Gutekanst
|
||||
- Stephen Gutekanst
|
||||
- Jonathan Hale
|
||||
- hdf89shfdfs
|
||||
- Sylvain Hellegouarch
|
||||
- Matthew Henry
|
||||
- heromyth
|
||||
- Lucas Hinderberger
|
||||
- Paul Holden
|
||||
- Warren Hu
|
||||
- Charles Huber
|
||||
- InKryption
|
||||
- IntellectualKitty
|
||||
- Aaron Jacobs
|
||||
- Erik S. V. Jansson
|
||||
- Toni Jovanoski
|
||||
- Arseny Kapoulkine
|
||||
- Cem Karan
|
||||
- Osman Keskin
|
||||
- Koray Kilinc
|
||||
- Josh Kilmer
|
||||
- Byunghoon Kim
|
||||
- Cameron King
|
||||
- Peter Knut
|
||||
- Christoph Kubisch
|
||||
- Yuri Kunde Schlesner
|
||||
- Rokas Kupstys
|
||||
- Konstantin Käfer
|
||||
- Eric Larson
|
||||
- Francis Lecavalier
|
||||
- Jong Won Lee
|
||||
- Robin Leffmann
|
||||
- Glenn Lewis
|
||||
- Shane Liesegang
|
||||
- Anders Lindqvist
|
||||
- Leon Linhart
|
||||
- Marco Lizza
|
||||
- Eyal Lotem
|
||||
- Aaron Loucks
|
||||
- Luflosi
|
||||
- lukect
|
||||
- Tristam MacDonald
|
||||
- Hans Mackowiak
|
||||
- Дмитри Малышев
|
||||
- Zbigniew Mandziejewicz
|
||||
- Adam Marcus
|
||||
- Célestin Marot
|
||||
- Kyle McDonald
|
||||
- David V. McKay
|
||||
- David Medlock
|
||||
- Bryce Mehring
|
||||
- Jonathan Mercier
|
||||
- Marcel Metz
|
||||
- Liam Middlebrook
|
||||
- Ave Milia
|
||||
- Jonathan Miller
|
||||
- Kenneth Miller
|
||||
- Bruce Mitchener
|
||||
- Jack Moffitt
|
||||
- Jeff Molofee
|
||||
- Alexander Monakov
|
||||
- Pierre Morel
|
||||
- Jon Morton
|
||||
- Pierre Moulon
|
||||
- Martins Mozeiko
|
||||
- Pascal Muetschard
|
||||
- Julian Møller
|
||||
- ndogxj
|
||||
- n3rdopolis
|
||||
- Kristian Nielsen
|
||||
- Kamil Nowakowski
|
||||
- onox
|
||||
- Denis Ovod
|
||||
- Ozzy
|
||||
- Andri Pálsson
|
||||
- luz paz
|
||||
- Peoro
|
||||
- Braden Pellett
|
||||
- Christopher Pelloux
|
||||
- Arturo J. Pérez
|
||||
- Vladimir Perminov
|
||||
- Anthony Pesch
|
||||
- Orson Peters
|
||||
- Emmanuel Gil Peyrot
|
||||
- Cyril Pichard
|
||||
- Keith Pitt
|
||||
- Stanislav Podgorskiy
|
||||
- Konstantin Podsvirov
|
||||
- Nathan Poirier
|
||||
- Alexandre Pretyman
|
||||
- Pablo Prietz
|
||||
- przemekmirek
|
||||
- pthom
|
||||
- Guillaume Racicot
|
||||
- Philip Rideout
|
||||
- Eddie Ringle
|
||||
- Max Risuhin
|
||||
- Jorge Rodriguez
|
||||
- Jari Ronkainen
|
||||
- Luca Rood
|
||||
- Ed Ropple
|
||||
- Aleksey Rybalkin
|
||||
- Mikko Rytkönen
|
||||
- Riku Salminen
|
||||
- Brandon Schaefer
|
||||
- Sebastian Schuberth
|
||||
- Christian Sdunek
|
||||
- Matt Sealey
|
||||
- Steve Sexton
|
||||
- Arkady Shapkin
|
||||
- Ali Sherief
|
||||
- Yoshiki Shibukawa
|
||||
- Dmitri Shuralyov
|
||||
- Daniel Skorupski
|
||||
- Anthony Smith
|
||||
- Bradley Smith
|
||||
- Cliff Smolinsky
|
||||
- Patrick Snape
|
||||
- Erlend Sogge Heggen
|
||||
- Julian Squires
|
||||
- Johannes Stein
|
||||
- Pontus Stenetorp
|
||||
- Michael Stocker
|
||||
- Justin Stoecker
|
||||
- Elviss Strazdins
|
||||
- Paul Sultana
|
||||
- Nathan Sweet
|
||||
- TTK-Bandit
|
||||
- Jared Tiala
|
||||
- Sergey Tikhomirov
|
||||
- Arthur Tombs
|
||||
- Ioannis Tsakpinis
|
||||
- Samuli Tuomola
|
||||
- Matthew Turner
|
||||
- urraka
|
||||
- Elias Vanderstuyft
|
||||
- Stef Velzel
|
||||
- Jari Vetoniemi
|
||||
- Ricardo Vieira
|
||||
- Nicholas Vitovitch
|
||||
- Simon Voordouw
|
||||
- Corentin Wallez
|
||||
- Torsten Walluhn
|
||||
- Patrick Walton
|
||||
- Xo Wang
|
||||
- Jay Weisskopf
|
||||
- Frank Wille
|
||||
- Andy Williams
|
||||
- Joel Winarske
|
||||
- Richard A. Wilkes
|
||||
- Tatsuya Yatagawa
|
||||
- Ryogo Yoshimura
|
||||
- Lukas Zanner
|
||||
- Andrey Zholos
|
||||
- Aihui Zhu
|
||||
- Santi Zupancic
|
||||
- Jonas Ådahl
|
||||
- Lasse Öörni
|
||||
- Leonard König
|
||||
- All the unmentioned and anonymous contributors in the GLFW community, for bug
|
||||
reports, patches, feedback, testing and encouragement
|
||||
|
254
README.md
254
README.md
@ -39,6 +39,11 @@ you have used GLFW 2 in the past, there is a [transition
|
||||
guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
|
||||
3 API.
|
||||
|
||||
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
|
||||
around the world, whether by reporting bugs, providing community support, adding
|
||||
features, reviewing or testing code, debugging, proofreading docs, suggesting
|
||||
features or fixing bugs.
|
||||
|
||||
|
||||
## Compiling GLFW
|
||||
|
||||
@ -126,6 +131,7 @@ information on what to include when reporting a bug.
|
||||
- Added `glfwInitAllocator` for setting a custom memory allocator (#544,#1628,#1947)
|
||||
- Added `GLFWallocator` struct and `GLFWallocatefun`, `GLFWreallocatefun` and
|
||||
`GLFWdeallocatefun` types (#544,#1628,#1947)
|
||||
- Added `glfwInitVulkanLoader` for using a non-default Vulkan loader (#1374,#1890)
|
||||
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
|
||||
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427)
|
||||
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
||||
@ -150,6 +156,7 @@ information on what to include when reporting a bug.
|
||||
- Made joystick subsystem initialize at first use (#1284,#1646)
|
||||
- Made `GLFW_DOUBLEBUFFER` a read-only window attribute
|
||||
- Updated the minimum required CMake version to 3.1
|
||||
- Updated gamepad mappings from upstream
|
||||
- Disabled tests and examples by default when built as a CMake subdirectory
|
||||
- Renamed `GLFW_USE_WAYLAND` CMake option to `GLFW_BUILD_WAYLAND` (#1958)
|
||||
- Removed `GLFW_USE_OSMESA` CMake option enabling the Null platform (#1958)
|
||||
@ -195,6 +202,9 @@ information on what to include when reporting a bug.
|
||||
later (#1783,#1796)
|
||||
- [Win32] Bugfix: Compilation with LLVM for Windows failed (#1807,#1824,#1874)
|
||||
- [Win32] Bugfix: The foreground lock timeout was overridden, ignoring the user
|
||||
- [Win32] Bugfix: Content scale queries could fail silently (#1615)
|
||||
- [Win32] Bugfix: Content scales could have garbage values if monitor was recently
|
||||
disconnected (#1615)
|
||||
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
|
||||
@ -223,6 +233,7 @@ information on what to include when reporting a bug.
|
||||
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: The CMake files did not check for the XInput headers (#1480)
|
||||
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
||||
(#1462,#1528)
|
||||
@ -245,13 +256,17 @@ information on what to include when reporting a bug.
|
||||
- [X11] Bugfix: XKB path used keysyms instead of physical locations for
|
||||
non-printable keys (#1598)
|
||||
- [X11] Bugfix: Function keys were mapped to `GLFW_KEY_UNKNOWN` for some layout
|
||||
combinaitons (#1598)
|
||||
combinations (#1598)
|
||||
- [X11] Bugfix: Keys pressed simultaneously with others were not always
|
||||
reported (#1112,#1415,#1472,#1616)
|
||||
- [X11] Bugfix: Some window attributes were not applied on leaving fullscreen
|
||||
(#1863)
|
||||
- [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory
|
||||
- [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on
|
||||
undefined behavior (#1986)
|
||||
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
||||
- [Wayland] Added dynamic loading of all Wayland libraries
|
||||
- [Wayland] Added support for key names via xkbcommon
|
||||
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
||||
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
||||
@ -259,13 +274,24 @@ information on what to include when reporting a bug.
|
||||
- [Wayland] Bugfix: Retrieving partial framebuffer size would segfault
|
||||
- [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms
|
||||
(#1463)
|
||||
- [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder
|
||||
- [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong order
|
||||
(#1798)
|
||||
- [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792)
|
||||
- [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
|
||||
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
|
||||
- [Wayland] Bugfix: Activating a window would emit two input focus events
|
||||
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
|
||||
- [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731)
|
||||
- [Wayland] Bugfix: A key being repeated was not released when window lost focus
|
||||
- [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event
|
||||
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE`
|
||||
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN`
|
||||
- [Wayland] Bugfix: Text input did not repeat along with key repeat
|
||||
- [POSIX] Removed use of deprecated function `gettimeofday`
|
||||
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
||||
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
||||
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
||||
macOS versions (#1442)
|
||||
@ -296,227 +322,3 @@ request, please file it in the
|
||||
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.
|
||||
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
GLFW exists because people around the world donated their time and lent their
|
||||
skills.
|
||||
|
||||
- Bobyshev Alexander
|
||||
- Laurent Aphecetche
|
||||
- Matt Arsenault
|
||||
- ashishgamedev
|
||||
- David Avedissian
|
||||
- Keith Bauer
|
||||
- John Bartholomew
|
||||
- Coşku Baş
|
||||
- Niklas Behrens
|
||||
- Andrew Belt
|
||||
- Nevyn Bengtsson
|
||||
- Niklas Bergström
|
||||
- Denis Bernard
|
||||
- Doug Binks
|
||||
- blanco
|
||||
- Waris Boonyasiriwat
|
||||
- Kyle Brenneman
|
||||
- Rok Breulj
|
||||
- Kai Burjack
|
||||
- Martin Capitanio
|
||||
- Nicolas Caramelli
|
||||
- David Carlier
|
||||
- Arturo Castro
|
||||
- Chi-kwan Chan
|
||||
- Joseph Chua
|
||||
- Ian Clarkson
|
||||
- Michał Cichoń
|
||||
- Lambert Clara
|
||||
- Anna Clarke
|
||||
- Yaron Cohen-Tal
|
||||
- Omar Cornut
|
||||
- Andrew Corrigan
|
||||
- Bailey Cosier
|
||||
- Noel Cower
|
||||
- CuriouserThing
|
||||
- Jason Daly
|
||||
- Jarrod Davis
|
||||
- Olivier Delannoy
|
||||
- Paul R. Deppe
|
||||
- Michael Dickens
|
||||
- Роман Донченко
|
||||
- Mario Dorn
|
||||
- Wolfgang Draxinger
|
||||
- Jonathan Dummer
|
||||
- Ralph Eastwood
|
||||
- Fredrik Ehnbom
|
||||
- Robin Eklind
|
||||
- Siavash Eliasi
|
||||
- Ahmad Fatoum
|
||||
- Felipe Ferreira
|
||||
- Michael Fogleman
|
||||
- Gerald Franz
|
||||
- Mário Freitas
|
||||
- GeO4d
|
||||
- Marcus Geelnard
|
||||
- Charles Giessen
|
||||
- Ryan C. Gordon
|
||||
- Stephen Gowen
|
||||
- Kovid Goyal
|
||||
- Eloi Marín Gratacós
|
||||
- Stefan Gustavson
|
||||
- Jonathan Hale
|
||||
- hdf89shfdfs
|
||||
- Sylvain Hellegouarch
|
||||
- Matthew Henry
|
||||
- heromyth
|
||||
- Lucas Hinderberger
|
||||
- Paul Holden
|
||||
- Warren Hu
|
||||
- Charles Huber
|
||||
- IntellectualKitty
|
||||
- Aaron Jacobs
|
||||
- Erik S. V. Jansson
|
||||
- Toni Jovanoski
|
||||
- Arseny Kapoulkine
|
||||
- Cem Karan
|
||||
- Osman Keskin
|
||||
- Koray Kilinc
|
||||
- Josh Kilmer
|
||||
- Byunghoon Kim
|
||||
- Cameron King
|
||||
- Peter Knut
|
||||
- Christoph Kubisch
|
||||
- Yuri Kunde Schlesner
|
||||
- Rokas Kupstys
|
||||
- Konstantin Käfer
|
||||
- Eric Larson
|
||||
- Francis Lecavalier
|
||||
- Jong Won Lee
|
||||
- Robin Leffmann
|
||||
- Glenn Lewis
|
||||
- Shane Liesegang
|
||||
- Anders Lindqvist
|
||||
- Leon Linhart
|
||||
- Marco Lizza
|
||||
- Eyal Lotem
|
||||
- Aaron Loucks
|
||||
- Luflosi
|
||||
- lukect
|
||||
- Tristam MacDonald
|
||||
- Hans Mackowiak
|
||||
- Дмитри Малышев
|
||||
- Zbigniew Mandziejewicz
|
||||
- Adam Marcus
|
||||
- Célestin Marot
|
||||
- Kyle McDonald
|
||||
- David V. McKay
|
||||
- David Medlock
|
||||
- Bryce Mehring
|
||||
- Jonathan Mercier
|
||||
- Marcel Metz
|
||||
- Liam Middlebrook
|
||||
- Ave Milia
|
||||
- Jonathan Miller
|
||||
- Kenneth Miller
|
||||
- Bruce Mitchener
|
||||
- Jack Moffitt
|
||||
- Jeff Molofee
|
||||
- Alexander Monakov
|
||||
- Pierre Morel
|
||||
- Jon Morton
|
||||
- Pierre Moulon
|
||||
- Martins Mozeiko
|
||||
- Julian Møller
|
||||
- ndogxj
|
||||
- n3rdopolis
|
||||
- Kristian Nielsen
|
||||
- Kamil Nowakowski
|
||||
- onox
|
||||
- Denis Ovod
|
||||
- Ozzy
|
||||
- Andri Pálsson
|
||||
- Peoro
|
||||
- Braden Pellett
|
||||
- Christopher Pelloux
|
||||
- Arturo J. Pérez
|
||||
- Vladimir Perminov
|
||||
- Anthony Pesch
|
||||
- Orson Peters
|
||||
- Emmanuel Gil Peyrot
|
||||
- Cyril Pichard
|
||||
- Keith Pitt
|
||||
- Stanislav Podgorskiy
|
||||
- Konstantin Podsvirov
|
||||
- Nathan Poirier
|
||||
- Alexandre Pretyman
|
||||
- Pablo Prietz
|
||||
- przemekmirek
|
||||
- pthom
|
||||
- Guillaume Racicot
|
||||
- Philip Rideout
|
||||
- Eddie Ringle
|
||||
- Max Risuhin
|
||||
- Jorge Rodriguez
|
||||
- Jari Ronkainen
|
||||
- Luca Rood
|
||||
- Ed Ropple
|
||||
- Aleksey Rybalkin
|
||||
- Mikko Rytkönen
|
||||
- Riku Salminen
|
||||
- Brandon Schaefer
|
||||
- Sebastian Schuberth
|
||||
- Christian Sdunek
|
||||
- Matt Sealey
|
||||
- Steve Sexton
|
||||
- Arkady Shapkin
|
||||
- Ali Sherief
|
||||
- Yoshiki Shibukawa
|
||||
- Dmitri Shuralyov
|
||||
- Daniel Skorupski
|
||||
- Anthony Smith
|
||||
- Bradley Smith
|
||||
- Cliff Smolinsky
|
||||
- Patrick Snape
|
||||
- Erlend Sogge Heggen
|
||||
- Julian Squires
|
||||
- Johannes Stein
|
||||
- Pontus Stenetorp
|
||||
- Michael Stocker
|
||||
- Justin Stoecker
|
||||
- Elviss Strazdins
|
||||
- Paul Sultana
|
||||
- Nathan Sweet
|
||||
- TTK-Bandit
|
||||
- Jared Tiala
|
||||
- Sergey Tikhomirov
|
||||
- Arthur Tombs
|
||||
- Ioannis Tsakpinis
|
||||
- Samuli Tuomola
|
||||
- Matthew Turner
|
||||
- urraka
|
||||
- Elias Vanderstuyft
|
||||
- Stef Velzel
|
||||
- Jari Vetoniemi
|
||||
- Ricardo Vieira
|
||||
- Nicholas Vitovitch
|
||||
- Simon Voordouw
|
||||
- Corentin Wallez
|
||||
- Torsten Walluhn
|
||||
- Patrick Walton
|
||||
- Xo Wang
|
||||
- Jay Weisskopf
|
||||
- Frank Wille
|
||||
- Andy Williams
|
||||
- Joel Winarske
|
||||
- Richard A. Wilkes
|
||||
- Tatsuya Yatagawa
|
||||
- Ryogo Yoshimura
|
||||
- Lukas Zanner
|
||||
- Andrey Zholos
|
||||
- Aihui Zhu
|
||||
- Santi Zupancic
|
||||
- Jonas Ådahl
|
||||
- Lasse Öörni
|
||||
- Leonard König
|
||||
- All the unmentioned and anonymous contributors in the GLFW community, for bug
|
||||
reports, patches, feedback, testing and encouragement
|
||||
|
||||
|
@ -104,9 +104,8 @@ integration by libwayland-egl, and keyboard handling by
|
||||
from wayland-protocols to provide additional features if the compositor
|
||||
supports them.
|
||||
|
||||
GLFW uses xkbcommon 0.5.0 to provide compose key support. When it has been
|
||||
built against an older xkbcommon, the compose key will be disabled even if it
|
||||
has been configured in the compositor.
|
||||
GLFW uses xkbcommon 0.5.0 to provide key and text input support. Earlier
|
||||
versions are not supported.
|
||||
|
||||
GLFW uses the [xdg-shell
|
||||
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
|
||||
|
@ -10,8 +10,8 @@ build applications that use GLFW, see @ref build_guide.
|
||||
|
||||
@section compile_cmake Using CMake
|
||||
|
||||
@note GLFW behaves like most other libraries that use CMake so this guide mostly
|
||||
describes the basic configure/generate/compile sequence. If you are already
|
||||
GLFW behaves like most other libraries that use CMake so this guide mostly
|
||||
describes the standard configure, generate and compile sequence. If you are already
|
||||
familiar with this from other projects, you may want to focus on the @ref
|
||||
compile_deps and @ref compile_options sections for GLFW-specific information.
|
||||
|
||||
@ -40,7 +40,7 @@ all necessary dependencies for compiling GLFW, but on Unix-like systems like
|
||||
Linux and FreeBSD you will need a few extra packages.
|
||||
|
||||
|
||||
@subsubsection compile_deps_x11 Dependencies for X11 on Unix-like systems
|
||||
@subsubsection compile_deps_x11 Dependencies for X11
|
||||
|
||||
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.
|
||||
@ -74,7 +74,7 @@ install the headers and other development related files for all of X11.
|
||||
Once you have the required dependencies, move on to @ref compile_generate.
|
||||
|
||||
|
||||
@subsubsection compile_deps_wayland Dependencies for Wayland and X11 on Unix-like systems
|
||||
@subsubsection compile_deps_wayland Dependencies for Wayland and X11
|
||||
|
||||
To compile GLFW for both Wayland and X11, you need to have the X11, Wayland and xkbcommon
|
||||
development packages installed. They are not needed to build or run programs that use
|
||||
@ -131,7 +131,7 @@ A common pattern when building a single configuration is to have a build
|
||||
directory named `build` in the root of the source tree.
|
||||
|
||||
|
||||
@subsubsection compile_generate_gui Generating files with the CMake GUI
|
||||
@subsubsection compile_generate_gui Generating with the CMake GUI
|
||||
|
||||
Start the CMake GUI and set the paths to the source and build directories
|
||||
described above. Then press _Configure_ and _Generate_.
|
||||
@ -148,7 +148,7 @@ Once you have generated the project files or makefiles for your chosen
|
||||
development environment, move on to @ref compile_compile.
|
||||
|
||||
|
||||
@subsubsection compile_generate_cli Generating files with the CMake command-line tool
|
||||
@subsubsection compile_generate_cli Generating with command-line CMake
|
||||
|
||||
To make a build directory, pass the source and build directories to the `cmake`
|
||||
command. These can be relative or absolute paths. The build directory is
|
||||
@ -273,12 +273,8 @@ __GLFW_BUILD_DOCS__ determines whether the GLFW documentation is built along
|
||||
with the library. This is enabled by default if
|
||||
[Doxygen](https://www.doxygen.nl/) is found by CMake during configuration.
|
||||
|
||||
@anchor GLFW_VULKAN_STATIC
|
||||
__GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
|
||||
directly with the application. This is disabled by default.
|
||||
|
||||
|
||||
@subsection compile_options_win32 Windows specific CMake options
|
||||
@subsection compile_options_win32 Win32 specific CMake options
|
||||
|
||||
@anchor GLFW_BUILD_WIN32
|
||||
__GLFW_BUILD_WIN32__ determines whether to include support for Win32 when compiling the
|
||||
@ -383,10 +379,6 @@ attempts to detect the appropriate platform at initialization.
|
||||
If you are building GLFW as a shared library / dynamic library / DLL then you
|
||||
must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it.
|
||||
|
||||
If you are linking the Vulkan loader directly with your application then you
|
||||
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
|
||||
external version.
|
||||
|
||||
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
|
||||
or GLESv2 library, you can override the default names by defining those you need
|
||||
of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1,7 @@
|
||||
{"version":3,"sourceRoot":"","sources":["extra.scss"],"names":[],"mappings":"AA8EA,4GACI,gBACA,iBAGJ,yBACC,yDAGD,6HACC,sDAGD,yIACC,sDAGD,mBACI,WA9EuB,KA+EvB,iBAGJ,uBACC,MAzFoB,QA0FjB,iBAGJ,6UACC,gBAGD,mJACC,YAGD,yHACC,iBAGD,sBACC,gBAGD,4LACC,UAGD,yCACC,aAGD,kMACC,WAnHgC,QAsHjC,KACC,MA1HoB,QA6HrB,sDACC,MA/Ge,QAgHf,mBAGD,GACE,iBACA,eAGF,GACE,iBACA,gBACA,eAGF,GACE,iBACA,gBACA,eAGF,YACC,eACA,gBACA,gBACA,eACA,cAEA,aACA,mBACA,eACA,2BACA,mBACA,sBAGD,UACC,iBACA,mBACA,MA/J0B,KAgK1B,gBACA,qEAGD,YACC,qBACA,kBACA,YAGD,yBACC,WAGD,oCACC,iBACA,gBACA,cACA,MAlL0B,KAqL3B,YACC,eAGD,8CACC,qBAGD,mBACC,MA9L0B,KAiM3B,eACC,kBACA,YACA,eAGD,KACC,WAxM0B,KA2M3B,UACC,gBACA,cACA,eAGD,WACC,gBACA,cACA,eAGD,UACI,aAGJ,mBACI,iBACA,iBAGJ,WACC,gBACA,aACA,mBACA,eACA,2BACA,mBACA,sBAGD,mEACC,MA9OgC,QAiPjC,gCACC,MArPoB,QAwPrB,sCACC,MAjOoB,KAoOrB,yBACC,kBAGD,UACC,iBAGD,wBACC,gBACA,cACA,eACA,qBAGD,uDACC,gEACA,+BACA,+BACA,gBACA,MArPgB,KAwPjB,mBACC,MA5PoB,KA6PpB,aACA,kBACA,yBAGD,QACC,WACA,WAGD,WACC,iBAGD,WACC,mBAGD,WACC,cACA,eACA,qBAGD,oCACC,gEACA,kCACA,2BACA,MAlSe,QAmSf,yBACA,kBAGD,WACC,MA3QuB,QA8QxB,cACC,sBACA,2BACA,4BACA,mBAGD,cACC,sBACA,+BACA,8BACA,gBAGD,mCACC,wBACA,iBACA,sBACA,kBAGD,gIACC,MAxToB,KAyTpB,qBAGD,cACC,wBACA,iBACA,sBACA,kBAGD,iBACC,WACA,4EAGD,oCApSC,gEACA,kCACA,cACA,yBAqSD,wBAxSC,gEACA,kCACA,cACA,yBAySD,qBA5SC,gEACA,kCACA,cACA,yBA6SD,gBAhTC,gEACA,kCACA,cACA,yBAiTD,iGACC,kBACA,YACA,2BACA,aAGD,kRACC,cAGD,SACC,oBAGD,0BACC,mBACA,kBACA,YACA,YACA,cACA,2BACA,aAGD,+CACC,MA1YoB,QA6YrB,+BACC,cAGD,sBACC,cAGD,+CACC,cACA,iBAGD,mBACC,cAGD,KACC,aACA","file":"extra.css"}
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AA8EA,2GAA4G,CAC3G,UAAU,CAAC,IAAI,CACf,WAAW,CAAC,IAAI,CAGjB,wBAAyB,CACxB,YAAY,CAAC,2CAAsD,CAGpE,4HAA6H,CAC5H,YAAY,CAAC,wCAAuD,CAGrE,wIAAyI,CACxI,YAAY,CAAC,wCAAuD,CAGrE,kBAAmB,CAClB,UAAU,CA9EgB,IAAa,CA+EvC,WAAW,CAAC,IAAI,CAGjB,sBAAuB,CACtB,KAAK,CAzFe,OAAa,CA0FjC,WAAW,CAAC,IAAI,CAGjB,4UAA6U,CAC5U,UAAU,CAAC,IAAI,CAGhB,kJAAmJ,CAClJ,MAAM,CAAC,IAAI,CAGZ,wHAAyH,CACxH,WAAW,CAAC,IAAI,CAGjB,qBAAsB,CACrB,UAAU,CAAC,IAAI,CAGhB,2LAA4L,CAC3L,OAAO,CAAC,CAAC,CAGV,wCAAyC,CACxC,OAAO,CAAC,IAAI,CAGb,iMAAkM,CACjM,UAAU,CApGW,OAA+B,CAuGrD,IAAK,CACJ,KAAK,CA1He,OAAa,CA6HlC,SAAU,CACN,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,aAAa,CAGzB,qDAAsD,CACrD,KAAK,CApHU,OAAa,CAqH5B,aAAa,CAAC,IAAI,CAGnB,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,SAAS,CAAC,IAAI,CAGf,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,aAAa,CAAC,CAAC,CACf,SAAS,CAAC,IAAI,CAGf,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,aAAa,CAAC,CAAC,CACf,SAAS,CAAC,IAAI,CAGf,WAAY,CACX,SAAS,CAAC,IAAI,CACd,UAAU,CAAC,IAAI,CACf,SAAS,CAAC,KAAK,CACf,OAAO,CAAC,MAAM,CACd,MAAM,CAAC,MAAM,CAEb,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,CACnB,SAAS,CAAE,IAAI,CACf,eAAe,CAAE,UAAU,CAC3B,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,OAAO,CAGvB,SAAU,CACT,WAAW,CAAC,IAAI,CAChB,aAAa,CAAC,IAAI,CAClB,KAAK,CApKqB,IAAa,CAqKvC,SAAS,CAAC,KAAK,CACf,UAAU,CAAC,yDAAyD,CAGrE,WAAY,CACX,eAAe,CAAC,IAAI,CACpB,MAAM,CAAC,UAAU,CACjB,KAAK,CAAC,KAAK,CAGZ,wBAAyB,CACxB,KAAK,CAAC,IAAI,CAGX,mCAAoC,CACnC,WAAW,CAAC,IAAI,CAChB,WAAW,CAAC,GAAG,CACf,OAAO,CAAC,KAAK,CACb,KAAK,CAvLqB,IAAa,CA0LxC,WAAY,CACX,YAAY,CAAE,CAAC,CAGhB,6CAA8C,CAC7C,UAAU,CAAC,SAAS,CAGrB,kBAAmB,CAClB,KAAK,CAnMqB,IAAa,CAsMxC,cAAe,CACd,UAAU,CAAC,MAAM,CACjB,OAAO,CAAC,GAAG,CACX,UAAU,CAAC,GAAG,CAGf,IAAK,CACJ,UAAU,CA7MgB,IAAa,CAgNxC,SAAU,CACT,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,SAAS,CAAC,IAAI,CAGf,UAAW,CACV,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,SAAS,CAAC,IAAI,CAGf,SAAU,CACT,OAAO,CAAC,IAAI,CAGb,kBAAmB,CAClB,WAAW,CAAC,IAAI,CAChB,WAAW,CAAC,IAAI,CAGjB,UAAW,CACV,UAAU,CAAC,IAAI,CACf,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,CACnB,SAAS,CAAE,IAAI,CACf,eAAe,CAAE,UAAU,CAC3B,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,OAAO,CAGvB,kEAAmE,CAClE,KAAK,CApOgB,OAA+B,CAuOrD,+BAAgC,CAC/B,KAAK,CA1Pe,OAAa,CA6PlC,qCAAsC,CACrC,KAAK,CA1NoB,IAAsB,CA6NhD,wBAA2B,CAC1B,MAAM,CAAE,UAAU,CAGnB,SAAU,CACT,UAAU,CAAC,KAAK,CAGjB,uBAAwB,CACvB,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,OAAO,CAAC,MAAM,CACd,UAAU,CAAC,SAA8B,CAG1C,sDAAuD,CACtD,UAAU,CAAC,iDAAoF,CAC/F,UAAU,CAAC,mBAAuC,CAClD,WAAW,CAAC,kBAAgD,CAC5D,UAAU,CAAC,IAAI,CACf,KAAK,CAlPa,IAAe,CAqPlC,kBAAmB,CAClB,KAAK,CArPoB,IAAsB,CAsP/C,OAAO,CAAC,IAAI,CACZ,aAAa,CAAC,GAAG,CACjB,gBAAgB,CAAC,OAAiC,CAGnD,OAAQ,CACP,KAAK,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAGV,oCAAoC,CACnC,OAAQ,CACP,KAAK,CAAC,IAAI,CACV,KAAK,CAAC,OAAO,CACb,MAAM,CAAC,CAAC,EAIV,UAAW,CACV,SAAS,CAAC,MAAM,CAGjB,UAAW,CACV,YAAY,CAAC,KAAK,CAGnB,UAAW,CACV,SAAS,CAAC,GAAG,CACb,YAAY,CAAC,CAAC,CACd,eAAe,CAAC,IAAI,CAIjB,mCAAqB,CACjB,WAAW,CAAC,KAAK,CAIzB,mCAAoC,CACnC,UAAU,CAAC,oDAAgF,CAC3F,UAAU,CAAC,sBAAqC,CAChD,WAAW,CAAC,cAA8C,CAC1D,KAAK,CArTU,OAAa,CAsT5B,MAAM,CAAC,iBAAgC,CACvC,aAAa,CAAC,GAAG,CAGlB,UAAW,CACV,KAAK,CA9RkB,OAAgC,CAiSxD,aAAc,CACb,MAAM,CAAC,cAA+B,CACtC,sBAAsB,CAAC,GAAG,CAC1B,uBAAuB,CAAC,GAAG,CAC3B,aAAa,CAAC,IAAI,CAGnB,aAAc,CACb,MAAM,CAAC,cAA+B,CACtC,0BAA0B,CAAC,GAAG,CAC9B,yBAAyB,CAAC,GAAG,CAC7B,UAAU,CAAC,IAAI,CAGhB,kCAAmC,CAClC,eAAe,CAAC,OAAO,CACvB,cAAc,CAAC,CAAC,CAChB,MAAM,CAAC,cAA+B,CACtC,aAAa,CAAC,GAAG,CAGlB,+HAAgI,CAC/H,KAAK,CA/ToB,IAAsB,CAgU/C,eAAe,CAAC,IAAI,CAGrB,aAAc,CACb,eAAe,CAAC,OAAO,CACvB,cAAc,CAAC,CAAC,CAChB,MAAM,CAAC,cAA+B,CACtC,aAAa,CAAC,GAAG,CAGlB,gBAAiB,CAChB,MAAM,CAAC,GAAG,CACV,UAAU,CAAC,gEAAiH,CAG7H,mCAAoC,CAvTnC,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAwT3D,uBAAwB,CA3TvB,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CA4T3D,oBAAqB,CA/TpB,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAgU3D,eAAgB,CAnUf,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAoU3D,gGAAiG,CAChG,aAAa,CAAC,GAAG,CACjB,OAAO,CAAC,GAAG,CACX,WAAW,CAAC,cAAwB,CACpC,MAAM,CAAC,KAAK,CAGb,iRAAkR,CACjR,KAAK,CAAC,OAAO,CAGd,QAAS,CACR,WAAW,CAAC,OAAO,CAGpB,yBAA0B,CACzB,UAAU,CAAC,OAAa,CACxB,aAAa,CAAC,GAAG,CACjB,MAAM,CAAC,IAAI,CACX,OAAO,CAAC,GAAG,CACX,QAAQ,CAAC,IAAI,CACb,WAAW,CAAC,cAAuB,CACnC,MAAM,CAAC,KAAK,CAGb,8CAA+C,CAC9C,KAAK,CA7Ze,OAAa,CAgalC,8BAA+B,CAC9B,KAAK,CAAC,OAAiB,CAGxB,qBAAsB,CACrB,KAAK,CAAC,OAAgB,CAGvB,8CAA+C,CAC9C,KAAK,CAAC,OAA+B,CACrC,WAAW,CAAC,IAAI,CAGjB,kBAAmB,CAClB,KAAK,CAAC,OAAiB,CAGxB,IAAK,CACJ,OAAO,CAAC,IAAI,CACZ,aAAa,CAAC,GAAG",
|
||||
"sources": ["extra.scss"],
|
||||
"names": [],
|
||||
"file": "extra.css"
|
||||
}
|
||||
|
@ -135,6 +135,11 @@ body {
|
||||
color:$default-text-color;
|
||||
}
|
||||
|
||||
div.title {
|
||||
font-size: 170%;
|
||||
margin: 1em 0 0.5em 0;
|
||||
}
|
||||
|
||||
h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em {
|
||||
color:$heading-color;
|
||||
border-bottom:none;
|
||||
@ -142,13 +147,13 @@ h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em {
|
||||
|
||||
h1 {
|
||||
padding-top:0.5em;
|
||||
font-size:180%;
|
||||
font-size:150%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-top:0.5em;
|
||||
margin-bottom:0;
|
||||
font-size:140%;
|
||||
font-size:130%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@ -292,9 +297,17 @@ dl.reflist dt a.el {
|
||||
background-color:lighten($default-link-color, 40%);
|
||||
}
|
||||
|
||||
div.toc {
|
||||
float:right;
|
||||
width:35%;
|
||||
}
|
||||
|
||||
@media screen and (max-width:600px) {
|
||||
div.toc {
|
||||
float:none;
|
||||
width:auto;
|
||||
width:inherit;
|
||||
margin:0;
|
||||
}
|
||||
}
|
||||
|
||||
div.toc h3 {
|
||||
@ -311,6 +324,12 @@ div.toc li {
|
||||
list-style-type:disc;
|
||||
}
|
||||
|
||||
div.toc {
|
||||
li.level2, li.level3 {
|
||||
margin-left:0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
div.toc,.memproto,div.qindex,div.ah {
|
||||
background:linear-gradient(to bottom,$toc-background-color2 0%,$toc-background-color1 100%);
|
||||
box-shadow:inset 0 0 32px $toc-background-color1;
|
||||
|
@ -35,6 +35,7 @@ successfully initialized, and only from the main thread.
|
||||
- @ref glfwSetErrorCallback
|
||||
- @ref glfwInitHint
|
||||
- @ref glfwInitAllocator
|
||||
- @ref glfwInitVulkanLoader
|
||||
- @ref glfwInit
|
||||
- @ref glfwTerminate
|
||||
|
||||
|
@ -150,6 +150,17 @@ GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off
|
||||
|
||||
@subsection removals_34 Removals in 3.4
|
||||
|
||||
@subsubsection vulkan_static_34 GLFW_VULKAN_STATIC CMake option has been removed
|
||||
|
||||
This option was used to compile GLFW directly linked with the Vulkan loader, instead of
|
||||
using dynamic loading to get hold of `vkGetInstanceProcAddr` at initialization. This is
|
||||
now done by calling the @ref glfwInitVulkanLoader function before initialization.
|
||||
|
||||
If you need backward compatibility, this macro can still be defined for GLFW 3.4 and will
|
||||
have no effect. The call to @ref glfwInitVulkanLoader can be conditionally enabled in
|
||||
your code by checking the @ref GLFW_VERSION_MAJOR and @ref GLFW_VERSION_MINOR macros.
|
||||
|
||||
|
||||
@subsubsection osmesa_option_34 GLFW_USE_OSMESA CMake option has been removed
|
||||
|
||||
This option was used to compile GLFW for the Null platform. The Null platform is now
|
||||
@ -177,6 +188,7 @@ then GLFW will fail to initialize.
|
||||
- @ref glfwInitAllocator
|
||||
- @ref glfwGetPlatform
|
||||
- @ref glfwPlatformSupported
|
||||
- @ref glfwInitVulkanLoader
|
||||
|
||||
|
||||
@subsubsection types_34 New types in version 3.4
|
||||
|
@ -29,28 +29,34 @@ are also guides for the other areas of the GLFW API.
|
||||
- @ref input_guide
|
||||
|
||||
|
||||
@section vulkan_loader Linking against the Vulkan loader
|
||||
@section vulkan_loader Finding the Vulkan loader
|
||||
|
||||
By default, GLFW will look for the Vulkan loader on demand at runtime via its
|
||||
standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other
|
||||
Unix-like systems and `libvulkan.1.dylib` on macOS). This means that GLFW does
|
||||
not need to be linked against the loader. However, it also means that if you
|
||||
are using the static library form of the Vulkan loader GLFW will either fail to
|
||||
find it or (worse) use the wrong one.
|
||||
GLFW itself does not ever need to be linked against the Vulkan loader.
|
||||
|
||||
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.
|
||||
By default, GLFW will load the Vulkan loader dynamically at runtime via its standard name:
|
||||
`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and
|
||||
`libvulkan.1.dylib` on macOS.
|
||||
|
||||
@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 GLFW will also look up and search the executable subdirectory of your application
|
||||
bundle.
|
||||
|
||||
If your code is using a Vulkan loader with a different name or in a non-standard location
|
||||
you will need to direct GLFW to it. Pass your version of `vkGetInstanceProcAddr` to @ref
|
||||
glfwInitVulkanLoader before initializing GLFW and it will use that function for all Vulkan
|
||||
entry point retrieval. This prevents GLFW from dynamically loading the Vulkan loader.
|
||||
|
||||
@code
|
||||
glfwInitVulkanLoader(vkGetInstanceProcAddr);
|
||||
@endcode
|
||||
|
||||
@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).
|
||||
|
||||
|
||||
@section vulkan_include Including the Vulkan and GLFW header files
|
||||
@section vulkan_include Including the Vulkan header file
|
||||
|
||||
To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including
|
||||
To have GLFW include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including
|
||||
the GLFW header.
|
||||
|
||||
@code
|
||||
@ -66,8 +72,13 @@ your own custom Vulkan header then do this before the GLFW header.
|
||||
#include <GLFW/glfw3.h>
|
||||
@endcode
|
||||
|
||||
Unless a Vulkan header is included, either by the GLFW header or above it, any
|
||||
GLFW functions that take or return Vulkan types will not be declared.
|
||||
Unless a Vulkan header is included, either by the GLFW header or above it, the following
|
||||
GLFW functions will not be declared, as depend on Vulkan types.
|
||||
|
||||
- @ref glfwInitVulkanLoader
|
||||
- @ref glfwGetInstanceProcAddress
|
||||
- @ref glfwGetPhysicalDevicePresentationSupport
|
||||
- @ref glfwCreateWindowSurface
|
||||
|
||||
The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part
|
||||
of GLFW to work. Define them only if you are using these extensions directly.
|
||||
|
@ -447,7 +447,7 @@ The no error mode for OpenGL and OpenGL ES is described in detail by the
|
||||
extension.
|
||||
|
||||
|
||||
@subsubsection window_hints_win32 Windows specific window hints
|
||||
@subsubsection window_hints_win32 Win32 specific hints
|
||||
|
||||
@anchor GLFW_WIN32_KEYBOARD_MENU_hint
|
||||
__GLFW_WIN32_KEYBOARD_MENU__ specifies whether to allow access to the window
|
||||
@ -455,7 +455,7 @@ menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. This is
|
||||
ignored on other platforms.
|
||||
|
||||
|
||||
@subsubsection window_hints_osx macOS specific window hints
|
||||
@subsubsection window_hints_osx macOS specific hints
|
||||
|
||||
@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint
|
||||
__GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution
|
||||
|
@ -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.
|
||||
//
|
||||
|
@ -190,6 +190,9 @@ extern "C" {
|
||||
#else /*__APPLE__*/
|
||||
|
||||
#include <GL/glcorearb.h>
|
||||
#if defined(GLFW_INCLUDE_GLEXT)
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
#endif /*__APPLE__*/
|
||||
|
||||
@ -372,7 +375,7 @@ extern "C" {
|
||||
*
|
||||
* The naming of the key codes follow these rules:
|
||||
* - The US keyboard layout is used
|
||||
* - Names of printable alpha-numeric characters are used (e.g. "A", "R",
|
||||
* - Names of printable alphanumeric characters are used (e.g. "A", "R",
|
||||
* "3", etc.)
|
||||
* - For non-alphanumeric characters, Unicode:ish names are used (e.g.
|
||||
* "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
|
||||
@ -1025,7 +1028,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).
|
||||
@ -2221,6 +2224,54 @@ GLFWAPI void glfwInitHint(int hint, int value);
|
||||
*/
|
||||
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator);
|
||||
|
||||
#if defined(VK_VERSION_1_0)
|
||||
|
||||
/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function.
|
||||
*
|
||||
* This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all
|
||||
* Vulkan related entry point queries.
|
||||
*
|
||||
* This feature is mostly useful on macOS, if your copy of the Vulkan loader is in
|
||||
* a location where GLFW cannot find it through dynamic loading, or if you are still
|
||||
* using the static library version of the loader.
|
||||
*
|
||||
* If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard
|
||||
* name and get this function from there. This is the default behavior.
|
||||
*
|
||||
* The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on
|
||||
* Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is
|
||||
* also loading it via these names then you probably don't need to use this function.
|
||||
*
|
||||
* The function address you set is never reset by GLFW, but it only takes effect during
|
||||
* initialization. Once GLFW has been initialized, any updates will be ignored until the
|
||||
* library is terminated and initialized again.
|
||||
*
|
||||
* @param[in] loader The address of the function to use, or `NULL`.
|
||||
*
|
||||
* @par Loader function signature
|
||||
* @code
|
||||
* PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name)
|
||||
* @endcode
|
||||
* For more information about this function, see the
|
||||
* [Vulkan Registry](https://www.khronos.org/registry/vulkan/).
|
||||
*
|
||||
* @errors None.
|
||||
*
|
||||
* @remark This function may be called before @ref glfwInit.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref vulkan_loader
|
||||
* @sa @ref glfwInit
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader);
|
||||
|
||||
#endif /*VK_VERSION_1_0*/
|
||||
|
||||
/*! @brief Retrieves the version of the GLFW library.
|
||||
*
|
||||
* This function retrieves the major, minor and revision numbers of the GLFW
|
||||
@ -3713,6 +3764,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
|
||||
@ -5652,6 +5708,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.
|
||||
@ -5741,8 +5799,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
|
||||
@ -6136,9 +6194,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.
|
||||
@ -6277,17 +6332,20 @@ 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.
|
||||
*
|
||||
* @remark @x11 GLFW by default attempts to use the `VK_KHR_xcb_surface`
|
||||
* extension, if available. You can make it prefer the `VK_KHR_xlib_surface`
|
||||
* extension by setting the
|
||||
* @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension,
|
||||
* with the `VK_KHR_xlib_surface` extension as a fallback. You can make
|
||||
* `VK_KHR_xlib_surface` the preferred extension by setting the
|
||||
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
|
||||
* hint.
|
||||
* hint. The name of the selected extension, if any, is included in the array
|
||||
* returned by @ref glfwGetRequiredInstanceExtensions.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. For
|
||||
* synchronization details of Vulkan objects, see the Vulkan specification.
|
||||
|
@ -65,10 +65,6 @@ endif()
|
||||
if (GLFW_BUILD_WAYLAND)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckFunctionExists)
|
||||
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
|
||||
if (HAVE_XKBCOMMON_COMPOSE_H)
|
||||
target_compile_definitions(glfw PRIVATE HAVE_XKBCOMMON_COMPOSE_H)
|
||||
endif()
|
||||
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
|
||||
if (HAVE_MEMFD_CREATE)
|
||||
target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE)
|
||||
@ -155,11 +151,6 @@ if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE)
|
||||
LANGUAGE C)
|
||||
endif()
|
||||
|
||||
if (GLFW_VULKAN_STATIC)
|
||||
target_compile_definitions(glfw PRIVATE _GLFW_VULKAN_STATIC)
|
||||
list(APPEND glfw_PKG_DEPS "vulkan")
|
||||
endif()
|
||||
|
||||
if (GLFW_BUILD_WIN32)
|
||||
list(APPEND glfw_PKG_LIBS "-lgdi32")
|
||||
endif()
|
||||
@ -178,7 +169,7 @@ if (GLFW_BUILD_WAYLAND)
|
||||
wayland-client>=0.2.7
|
||||
wayland-cursor>=0.2.7
|
||||
wayland-egl>=0.2.7
|
||||
xkbcommon)
|
||||
xkbcommon>=0.5.0)
|
||||
|
||||
target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS})
|
||||
|
||||
@ -199,31 +190,37 @@ if (GLFW_BUILD_X11)
|
||||
if (NOT X11_Xrandr_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
|
||||
endif()
|
||||
target_include_directories(glfw PRIVATE "${X11_Xrandr_INCLUDE_PATH}")
|
||||
|
||||
# Check for Xinerama (legacy multi-monitor support)
|
||||
if (NOT X11_Xinerama_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
|
||||
endif()
|
||||
target_include_directories(glfw PRIVATE "${X11_Xinerama_INCLUDE_PATH}")
|
||||
|
||||
# Check for Xkb (X keyboard extension)
|
||||
if (NOT X11_Xkb_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "XKB headers not found; install X11 development package")
|
||||
endif()
|
||||
target_include_directories(glfw PRIVATE "${X11_Xkb_INCLUDE_PATH}")
|
||||
|
||||
# Check for Xcursor (cursor creation from RGBA images)
|
||||
if (NOT X11_Xcursor_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
|
||||
endif()
|
||||
target_include_directories(glfw PRIVATE "${X11_Xcursor_INCLUDE_PATH}")
|
||||
|
||||
# Check for XInput (modern HID input)
|
||||
if (NOT X11_Xi_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "XInput headers not found; install libxi development package")
|
||||
endif()
|
||||
target_include_directories(glfw PRIVATE "${X11_Xi_INCLUDE_PATH}")
|
||||
|
||||
# Check for X Shape (custom window input shape)
|
||||
if (NOT X11_Xshape_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "X Shape headers not found; install libxext development package")
|
||||
endif()
|
||||
target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}")
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
|
@ -75,7 +75,6 @@ static void changeToResourcesDirectory(void)
|
||||
//
|
||||
static void createMenuBar(void)
|
||||
{
|
||||
size_t i;
|
||||
NSString* appName = nil;
|
||||
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
|
||||
NSString* nameKeys[] =
|
||||
@ -87,7 +86,7 @@ static void createMenuBar(void)
|
||||
|
||||
// Try to figure out what the calling application is called
|
||||
|
||||
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
|
||||
for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
|
||||
{
|
||||
id name = bundleInfo[nameKeys[i]];
|
||||
if (name &&
|
||||
@ -177,8 +176,6 @@ static void createMenuBar(void)
|
||||
//
|
||||
static void createKeyTables(void)
|
||||
{
|
||||
int scancode;
|
||||
|
||||
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
|
||||
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
|
||||
|
||||
@ -297,7 +294,7 @@ static void createKeyTables(void)
|
||||
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
|
||||
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
|
||||
|
||||
for (scancode = 0; scancode < 256; scancode++)
|
||||
for (int scancode = 0; scancode < 256; scancode++)
|
||||
{
|
||||
// Store the reverse translation for faster key name lookup
|
||||
if (_glfw.ns.keycodes[scancode] >= 0)
|
||||
@ -403,9 +400,7 @@ static GLFWbool initializeTIS(void)
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
for (window = _glfw.windowListHead; window; window = window->next)
|
||||
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||
_glfwInputWindowCloseRequest(window);
|
||||
|
||||
return NSTerminateCancel;
|
||||
@ -413,9 +408,7 @@ static GLFWbool initializeTIS(void)
|
||||
|
||||
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
for (window = _glfw.windowListHead; window; window = window->next)
|
||||
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||
{
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
[window->context.nsgl.object update];
|
||||
@ -450,9 +443,7 @@ static GLFWbool initializeTIS(void)
|
||||
|
||||
- (void)applicationDidHide:(NSNotification *)notification
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _glfw.monitorCount; i++)
|
||||
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||
_glfwRestoreVideoModeCocoa(_glfw.monitors[i]);
|
||||
}
|
||||
|
||||
|
@ -96,20 +96,18 @@ static CFComparisonResult compareElements(const void* fp,
|
||||
//
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!js->present)
|
||||
return;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||
CFRelease(js->ns.axes);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
||||
CFRelease(js->ns.buttons);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
|
||||
CFRelease(js->ns.hats);
|
||||
|
||||
@ -127,7 +125,6 @@ static void matchCallback(void* context,
|
||||
int jid;
|
||||
char name[256];
|
||||
char guid[33];
|
||||
CFIndex i;
|
||||
CFTypeRef property;
|
||||
uint32_t vendor = 0, product = 0, version = 0;
|
||||
_GLFWjoystick* js;
|
||||
@ -185,7 +182,7 @@ static void matchCallback(void* context,
|
||||
CFArrayRef elements =
|
||||
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(elements); i++)
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(elements); i++)
|
||||
{
|
||||
IOHIDElementRef native = (IOHIDElementRef)
|
||||
CFArrayGetValueAtIndex(elements, i);
|
||||
@ -290,9 +287,7 @@ static void removeCallback(void* context,
|
||||
void* sender,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].ns.device == device)
|
||||
{
|
||||
@ -386,9 +381,7 @@ GLFWbool _glfwInitJoysticksCocoa(void)
|
||||
|
||||
void _glfwTerminateJoysticksCocoa(void)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
closeJoystick(_glfw.joysticks + jid);
|
||||
|
||||
if (_glfw.ns.hidManager)
|
||||
@ -403,9 +396,7 @@ int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
if (mode & _GLFW_POLL_AXES)
|
||||
{
|
||||
CFIndex i;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
{
|
||||
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->ns.axes, i);
|
||||
@ -430,9 +421,7 @@ int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
|
||||
|
||||
if (mode & _GLFW_POLL_BUTTONS)
|
||||
{
|
||||
CFIndex i;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
{
|
||||
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->ns.buttons, i);
|
||||
@ -441,7 +430,7 @@ int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
|
||||
_glfwInputJoystickButton(js, (int) i, state);
|
||||
}
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
{
|
||||
const int states[9] =
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
|
||||
io_service_t service;
|
||||
CFDictionaryRef info;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
|
||||
IOServiceMatching("IODisplayConnect"),
|
||||
&it) != 0)
|
||||
{
|
||||
@ -231,7 +231,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||
io_iterator_t it;
|
||||
io_service_t service;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
|
||||
IOServiceMatching("IOFramebuffer"),
|
||||
&it) != 0)
|
||||
{
|
||||
|
@ -231,6 +231,15 @@ static void swapBuffersEGL(_GLFWwindow* window)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
if (_glfw.platform.platformID == GLFW_PLATFORM_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);
|
||||
}
|
||||
|
||||
@ -316,6 +325,8 @@ GLFWbool _glfwInitEGL(void)
|
||||
"libEGL.dylib",
|
||||
#elif defined(__CYGWIN__)
|
||||
"libEGL-1.so",
|
||||
#elif defined(__OpenBSD__)
|
||||
"libEGL.so",
|
||||
#else
|
||||
"libEGL.so.1",
|
||||
#endif
|
||||
@ -472,6 +483,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;
|
||||
}
|
||||
@ -646,6 +659,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (!fbconfig->doublebuffer)
|
||||
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
||||
|
||||
if (_glfw.egl.EXT_present_opaque)
|
||||
setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
||||
|
||||
setAttrib(EGL_NONE, EGL_NONE);
|
||||
|
||||
native = _glfw.platform.getEGLNativeWindow(window);
|
||||
@ -686,6 +702,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
"libGLES_CM.dll",
|
||||
#elif defined(_GLFW_COCOA)
|
||||
"libGLESv1_CM.dylib",
|
||||
#elif defined(__OpenBSD__)
|
||||
"libGLESv1_CM.so",
|
||||
#else
|
||||
"libGLESv1_CM.so.1",
|
||||
"libGLES_CM.so.1",
|
||||
@ -703,6 +721,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
"libGLESv2.dylib",
|
||||
#elif defined(__CYGWIN__)
|
||||
"libGLESv2-2.so",
|
||||
#elif defined(__OpenBSD__)
|
||||
"libGLESv2.so",
|
||||
#else
|
||||
"libGLESv2.so.2",
|
||||
#endif
|
||||
@ -714,6 +734,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_GLFW_OPENGL_LIBRARY,
|
||||
#elif defined(_GLFW_WIN32)
|
||||
#elif defined(_GLFW_COCOA)
|
||||
#elif defined(__OpenBSD__)
|
||||
"libGL.so",
|
||||
#else
|
||||
"libGL.so.1",
|
||||
#endif
|
||||
@ -821,7 +843,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
|
||||
|
||||
if (window->context.client != GLFW_EGL_CONTEXT_API)
|
||||
if (window->context.source != GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return EGL_NO_CONTEXT;
|
||||
@ -835,7 +857,7 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
|
||||
|
||||
if (window->context.client != GLFW_EGL_CONTEXT_API)
|
||||
if (window->context.source != GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return EGL_NO_SURFACE;
|
||||
|
@ -55,7 +55,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
GLXFBConfig* nativeConfigs;
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, nativeCount, usableCount;
|
||||
int nativeCount, usableCount;
|
||||
const char* vendor;
|
||||
GLFWbool trustWindowBit = GLFW_TRUE;
|
||||
|
||||
@ -76,7 +76,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
for (int i = 0; i < nativeCount; i++)
|
||||
{
|
||||
const GLXFBConfig n = nativeConfigs[i];
|
||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||
@ -258,13 +258,14 @@ static void destroyContextGLX(_GLFWwindow* window)
|
||||
//
|
||||
GLFWbool _glfwInitGLX(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
{
|
||||
#if defined(_GLFW_GLX_LIBRARY)
|
||||
_GLFW_GLX_LIBRARY,
|
||||
#elif defined(__CYGWIN__)
|
||||
"libGL-1.so",
|
||||
#elif defined(__OpenBSD__)
|
||||
"libGL.so",
|
||||
#else
|
||||
"libGL.so.1",
|
||||
"libGL.so",
|
||||
@ -275,7 +276,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
if (_glfw.glx.handle)
|
||||
return GLFW_TRUE;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
for (int i = 0; sonames[i]; i++)
|
||||
{
|
||||
_glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]);
|
||||
if (_glfw.glx.handle)
|
||||
@ -687,7 +688,7 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NATIVE_CONTEXT_API)
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
@ -707,7 +708,7 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
return None;
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NATIVE_CONTEXT_API)
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return None;
|
||||
|
48
src/init.c
48
src/init.c
@ -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,6 +54,7 @@ static _GLFWinitconfig _glfwInitHints =
|
||||
GLFW_TRUE, // hat buttons
|
||||
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
|
||||
GLFW_ANY_PLATFORM, // preferred platform
|
||||
NULL, // vkGetInstanceProcAddr function
|
||||
{
|
||||
GLFW_TRUE, // macOS menu bar
|
||||
GLFW_TRUE // macOS bundle chdir
|
||||
@ -140,6 +140,37 @@ 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;
|
||||
}
|
||||
|
||||
char* _glfw_strdup(const char* source)
|
||||
{
|
||||
const size_t length = strlen(source);
|
||||
@ -404,6 +435,11 @@ GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
|
||||
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
|
||||
}
|
||||
|
||||
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
|
||||
{
|
||||
_glfwInitHints.vulkanLoader = loader;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||
{
|
||||
if (major != NULL)
|
||||
@ -440,7 +476,7 @@ GLFWAPI int glfwGetError(const char** description)
|
||||
|
||||
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
||||
{
|
||||
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
|
||||
_GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
44
src/input.c
44
src/input.c
@ -295,7 +295,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;
|
||||
@ -522,7 +522,9 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (mode == GLFW_CURSOR)
|
||||
switch (mode)
|
||||
{
|
||||
case GLFW_CURSOR:
|
||||
{
|
||||
if (value != GLFW_CURSOR_NORMAL &&
|
||||
value != GLFW_CURSOR_HIDDEN &&
|
||||
@ -543,8 +545,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
&window->virtualCursorPosX,
|
||||
&window->virtualCursorPosY);
|
||||
_glfw.platform.setCursorMode(window, value);
|
||||
return;
|
||||
}
|
||||
else if (mode == GLFW_STICKY_KEYS)
|
||||
|
||||
case GLFW_STICKY_KEYS:
|
||||
{
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
if (window->stickyKeys == value)
|
||||
@ -563,8 +567,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
}
|
||||
|
||||
window->stickyKeys = value;
|
||||
return;
|
||||
}
|
||||
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
||||
|
||||
case GLFW_STICKY_MOUSE_BUTTONS:
|
||||
{
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
if (window->stickyMouseButtons == value)
|
||||
@ -583,12 +589,16 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
}
|
||||
|
||||
window->stickyMouseButtons = value;
|
||||
return;
|
||||
}
|
||||
else if (mode == GLFW_LOCK_KEY_MODS)
|
||||
|
||||
case GLFW_LOCK_KEY_MODS:
|
||||
{
|
||||
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
return;
|
||||
}
|
||||
else if (mode == GLFW_RAW_MOUSE_MOTION)
|
||||
|
||||
case GLFW_RAW_MOUSE_MOTION:
|
||||
{
|
||||
if (!_glfw.platform.rawMouseMotionSupported())
|
||||
{
|
||||
@ -603,8 +613,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
|
||||
window->rawMouseMotion = value;
|
||||
_glfw.platform.setRawMouseMotion(window, value);
|
||||
return;
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||
}
|
||||
|
||||
@ -856,7 +868,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
|
||||
_GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -866,7 +878,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
|
||||
_GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -876,7 +888,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
|
||||
_GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -887,7 +899,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
|
||||
_GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -898,7 +910,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
|
||||
_GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -909,7 +921,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
|
||||
_GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -920,7 +932,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
|
||||
_GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -930,7 +942,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
|
||||
_GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1154,7 +1166,7 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
||||
if (!initJoysticks())
|
||||
return NULL;
|
||||
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
|
||||
_GLFW_SWAP(GLFWjoystickfun, _glfw.callbacks.joystick, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
@ -177,6 +177,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
|
||||
#define EGL_PLATFORM_X11_EXT 0x31d5
|
||||
#define EGL_PLATFORM_WAYLAND_EXT 0x31d8
|
||||
#define EGL_PRESENT_OPAQUE_EXT 0x31df
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d
|
||||
@ -323,15 +324,9 @@ typedef struct VkExtensionProperties
|
||||
|
||||
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
|
||||
#if defined(_GLFW_VULKAN_STATIC)
|
||||
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);
|
||||
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);
|
||||
#else
|
||||
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
|
||||
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
|
||||
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
|
||||
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
@ -357,9 +352,9 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
}
|
||||
|
||||
// Swaps the provided pointers
|
||||
#define _GLFW_SWAP_POINTERS(x, y) \
|
||||
#define _GLFW_SWAP(type, x, y) \
|
||||
{ \
|
||||
void* t; \
|
||||
type t; \
|
||||
t = x; \
|
||||
x = y; \
|
||||
y = t; \
|
||||
@ -383,6 +378,7 @@ struct _GLFWinitconfig
|
||||
GLFWbool hatButtons;
|
||||
int angleType;
|
||||
int platformID;
|
||||
PFN_vkGetInstanceProcAddr vulkanLoader;
|
||||
struct {
|
||||
GLFWbool menubar;
|
||||
GLFWbool chdir;
|
||||
@ -808,6 +804,7 @@ struct _GLFWlibrary
|
||||
GLFWbool EXT_platform_base;
|
||||
GLFWbool EXT_platform_x11;
|
||||
GLFWbool EXT_platform_wayland;
|
||||
GLFWbool EXT_present_opaque;
|
||||
GLFWbool ANGLE_platform_angle;
|
||||
GLFWbool ANGLE_platform_angle_opengl;
|
||||
GLFWbool ANGLE_platform_angle_d3d;
|
||||
@ -854,10 +851,7 @@ struct _GLFWlibrary
|
||||
GLFWbool available;
|
||||
void* handle;
|
||||
char* extensions[2];
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||
#endif
|
||||
GLFWbool KHR_surface;
|
||||
GLFWbool KHR_win32_surface;
|
||||
GLFWbool MVK_macos_surface;
|
||||
@ -925,7 +919,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);
|
||||
@ -1001,6 +995,8 @@ GLFWbool _glfwInitVulkan(int mode);
|
||||
void _glfwTerminateVulkan(void);
|
||||
const char* _glfwGetVulkanResultString(VkResult result);
|
||||
|
||||
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
||||
|
||||
char* _glfw_strdup(const char* source);
|
||||
float _glfw_fminf(float a, float b);
|
||||
float _glfw_fmaxf(float a, float b);
|
||||
|
@ -363,9 +363,7 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
||||
|
||||
void _glfwTerminateJoysticksLinux(void)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
|
@ -419,7 +419,7 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
|
||||
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun);
|
||||
_GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,7 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NATIVE_CONTEXT_API)
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return nil;
|
||||
|
@ -116,7 +116,6 @@ GLFWbool _glfwRawMouseMotionSupportedNull(void);
|
||||
void _glfwShowWindowNull(_GLFWwindow* window);
|
||||
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
|
||||
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
|
||||
void _glfwUnhideWindowNull(_GLFWwindow* window);
|
||||
void _glfwHideWindowNull(_GLFWwindow* window);
|
||||
void _glfwFocusWindowNull(_GLFWwindow* window);
|
||||
int _glfwWindowFocusedNull(_GLFWwindow* window);
|
||||
|
@ -409,10 +409,6 @@ void _glfwRequestWindowAttentionNull(_GLFWwindow* window)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwUnhideWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwHideWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.null.focusedWindow == window)
|
||||
|
@ -124,6 +124,8 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
"libOSMesa.8.dylib",
|
||||
#elif defined(__CYGWIN__)
|
||||
"libOSMesa-8.so",
|
||||
#elif defined(__OpenBSD__)
|
||||
"libOSMesa.so",
|
||||
#else
|
||||
"libOSMesa.so.8",
|
||||
"libOSMesa.so.6",
|
||||
@ -302,7 +304,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (window->context.client != GLFW_OSMESA_CONTEXT_API)
|
||||
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
@ -341,7 +343,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (window->context.client != GLFW_OSMESA_CONTEXT_API)
|
||||
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
@ -373,7 +375,7 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (window->context.client != GLFW_OSMESA_CONTEXT_API)
|
||||
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
|
@ -72,32 +72,37 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
|
||||
// Only allow the Null platform if specifically requested
|
||||
if (desiredID == GLFW_PLATFORM_NULL)
|
||||
return _glfwConnectNull(desiredID, platform);
|
||||
|
||||
// If there is only one platform available for auto-selection, let it emit the error
|
||||
// on failure as the platform-specific error description may be more helpful
|
||||
if (desiredID == GLFW_ANY_PLATFORM && count == 1)
|
||||
return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
else if (count == 0)
|
||||
{
|
||||
if (desiredID == GLFW_ANY_PLATFORM || desiredID == supportedPlatforms[i].ID)
|
||||
{
|
||||
if (supportedPlatforms[i].connect(desiredID, platform))
|
||||
return GLFW_TRUE;
|
||||
else if (desiredID == supportedPlatforms[i].ID)
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (desiredID == GLFW_ANY_PLATFORM)
|
||||
{
|
||||
if (count)
|
||||
// If there is exactly one platform available for auto-selection, let it emit the
|
||||
// error on failure as the platform-specific error description may be more helpful
|
||||
if (count == 1)
|
||||
return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (supportedPlatforms[i].connect(desiredID, platform))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform");
|
||||
else
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (supportedPlatforms[i].ID == desiredID)
|
||||
return supportedPlatforms[i].connect(desiredID, platform);
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported");
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
29
src/vulkan.c
29
src/vulkan.c
@ -45,12 +45,16 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
{
|
||||
VkResult err;
|
||||
VkExtensionProperties* ep;
|
||||
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
||||
uint32_t i, count;
|
||||
|
||||
if (_glfw.vk.available)
|
||||
return GLFW_TRUE;
|
||||
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
if (_glfw.hints.init.vulkanLoader)
|
||||
_glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader;
|
||||
else
|
||||
{
|
||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
|
||||
#elif defined(_GLFW_WIN32)
|
||||
@ -59,6 +63,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
|
||||
if (!_glfw.vk.handle)
|
||||
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
||||
#else
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
|
||||
#endif
|
||||
@ -80,10 +86,11 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
|
||||
if (!_glfw.vk.EnumerateInstanceExtensionProperties)
|
||||
if (!vkEnumerateInstanceExtensionProperties)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||
@ -91,7 +98,6 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
#endif // _GLFW_VULKAN_STATIC
|
||||
|
||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||
if (err)
|
||||
@ -151,10 +157,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
|
||||
void _glfwTerminateVulkan(void)
|
||||
{
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
if (_glfw.vk.handle)
|
||||
_glfwPlatformFreeModule(_glfw.vk.handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* _glfwGetVulkanResultString(VkResult result)
|
||||
@ -252,17 +256,16 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||
return NULL;
|
||||
|
||||
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
|
||||
#if defined(_GLFW_VULKAN_STATIC)
|
||||
if (!proc)
|
||||
{
|
||||
// NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself
|
||||
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
|
||||
return (GLFWvkproc) vkGetInstanceProcAddr;
|
||||
}
|
||||
#else
|
||||
|
||||
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
|
||||
if (!proc)
|
||||
{
|
||||
if (_glfw.vk.handle)
|
||||
proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
|
||||
#endif
|
||||
}
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
@ -322,14 +322,12 @@ static void swapBuffersWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
// HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
|
||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
||||
{
|
||||
// DWM Composition is always enabled on Win8+
|
||||
BOOL enabled = IsWindows8OrGreater();
|
||||
BOOL enabled = FALSE;
|
||||
|
||||
// HACK: Use DwmFlush when desktop composition is enabled
|
||||
if (enabled ||
|
||||
(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
|
||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||
{
|
||||
int count = abs(window->context.wgl.interval);
|
||||
while (count--)
|
||||
@ -349,15 +347,13 @@ static void swapIntervalWGL(int interval)
|
||||
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled on Windows
|
||||
// Vista and 7 to avoid interfering with DWM vsync
|
||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
||||
{
|
||||
// DWM Composition is always enabled on Win8+
|
||||
BOOL enabled = IsWindows8OrGreater();
|
||||
BOOL enabled = FALSE;
|
||||
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||
// avoid interfering with DWM vsync
|
||||
if (enabled ||
|
||||
(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
|
||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||
interval = 0;
|
||||
}
|
||||
}
|
||||
@ -783,7 +779,7 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NATIVE_CONTEXT_API)
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
|
@ -317,8 +317,19 @@ void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* ys
|
||||
{
|
||||
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);
|
||||
|
@ -428,7 +428,7 @@ typedef struct _GLFWwindowWin32
|
||||
|
||||
// The last received cursor position, regardless of source
|
||||
int lastCursorPosX, lastCursorPosY;
|
||||
// The last recevied high surrogate when decoding pairs of UTF-16 messages
|
||||
// The last received high surrogate when decoding pairs of UTF-16 messages
|
||||
WCHAR highSurrogate;
|
||||
} _GLFWwindowWin32;
|
||||
|
||||
|
@ -649,7 +649,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)
|
||||
{
|
||||
@ -683,7 +683,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;
|
||||
}
|
||||
|
||||
@ -1304,9 +1304,13 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
{
|
||||
float xscale, yscale;
|
||||
_glfwGetWindowContentScaleWin32(window, &xscale, &yscale);
|
||||
|
||||
if (xscale > 0.f && yscale > 0.f)
|
||||
{
|
||||
rect.right = (int) (rect.right * xscale);
|
||||
rect.bottom = (int) (rect.bottom * yscale);
|
||||
}
|
||||
}
|
||||
|
||||
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
||||
@ -1645,8 +1649,7 @@ void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window,
|
||||
*bottom = rect.bottom - height;
|
||||
}
|
||||
|
||||
void _glfwGetWindowContentScaleWin32(_GLFWwindow* window,
|
||||
float* xscale, float* yscale)
|
||||
void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, float* xscale, float* yscale)
|
||||
{
|
||||
const HANDLE handle = MonitorFromWindow(window->win32.handle,
|
||||
MONITOR_DEFAULTTONEAREST);
|
||||
|
52
src/window.c
52
src/window.c
@ -882,34 +882,40 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
||||
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
|
||||
if (attrib == GLFW_AUTO_ICONIFY)
|
||||
window->autoIconify = value;
|
||||
else if (attrib == GLFW_RESIZABLE)
|
||||
switch (attrib)
|
||||
{
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
window->autoIconify = value;
|
||||
return;
|
||||
|
||||
case GLFW_RESIZABLE:
|
||||
window->resizable = value;
|
||||
if (!window->monitor)
|
||||
_glfw.platform.setWindowResizable(window, value);
|
||||
}
|
||||
else if (attrib == GLFW_DECORATED)
|
||||
{
|
||||
return;
|
||||
|
||||
case GLFW_DECORATED:
|
||||
window->decorated = value;
|
||||
if (!window->monitor)
|
||||
_glfw.platform.setWindowDecorated(window, value);
|
||||
}
|
||||
else if (attrib == GLFW_FLOATING)
|
||||
{
|
||||
return;
|
||||
|
||||
case GLFW_FLOATING:
|
||||
window->floating = value;
|
||||
if (!window->monitor)
|
||||
_glfw.platform.setWindowFloating(window, value);
|
||||
}
|
||||
else if (attrib == GLFW_FOCUS_ON_SHOW)
|
||||
return;
|
||||
|
||||
case GLFW_FOCUS_ON_SHOW:
|
||||
window->focusOnShow = value;
|
||||
else if (attrib == GLFW_MOUSE_PASSTHROUGH)
|
||||
{
|
||||
return;
|
||||
|
||||
case GLFW_MOUSE_PASSTHROUGH:
|
||||
window->mousePassthrough = value;
|
||||
_glfw.platform.setWindowMousePassthrough(window, value);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
||||
}
|
||||
|
||||
@ -986,7 +992,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -997,7 +1003,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.size, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1008,7 +1014,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.close, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1019,7 +1025,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1030,7 +1036,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1041,7 +1047,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1052,7 +1058,7 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1063,7 +1069,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun);
|
||||
_GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
@ -1074,7 +1080,7 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.scale, cbfun);
|
||||
_GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
127
src/wl_init.c
127
src/wl_init.c
@ -207,12 +207,12 @@ static void pointerHandleMotion(void* data,
|
||||
return;
|
||||
x = wl_fixed_to_double(sx);
|
||||
y = wl_fixed_to_double(sy);
|
||||
window->wl.cursorPosX = x;
|
||||
window->wl.cursorPosY = y;
|
||||
|
||||
switch (window->wl.decorations.focus)
|
||||
{
|
||||
case mainWindow:
|
||||
window->wl.cursorPosX = x;
|
||||
window->wl.cursorPosY = y;
|
||||
_glfwInputCursorPos(window, x, y);
|
||||
_glfw.wl.cursorPreviousName = NULL;
|
||||
return;
|
||||
@ -272,9 +272,7 @@ static void pointerHandleButton(void* data,
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||
else
|
||||
{
|
||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||
}
|
||||
break;
|
||||
case leftDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
@ -303,6 +301,7 @@ static void pointerHandleButton(void* data,
|
||||
{
|
||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
||||
serial, edges);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (button == BTN_RIGHT)
|
||||
@ -378,11 +377,8 @@ static void keyboardHandleKeymap(void* data,
|
||||
{
|
||||
struct xkb_keymap* keymap;
|
||||
struct xkb_state* state;
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
struct xkb_compose_table* composeTable;
|
||||
struct xkb_compose_state* composeState;
|
||||
#endif
|
||||
|
||||
char* mapStr;
|
||||
const char* locale;
|
||||
@ -431,7 +427,6 @@ static void keyboardHandleKeymap(void* data,
|
||||
if (!locale)
|
||||
locale = "C";
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
composeTable =
|
||||
xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
|
||||
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||
@ -451,7 +446,6 @@ static void keyboardHandleKeymap(void* data,
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to create XKB compose table");
|
||||
}
|
||||
#endif
|
||||
|
||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||
xkb_state_unref(_glfw.wl.xkb.state);
|
||||
@ -505,20 +499,22 @@ static void keyboardHandleLeave(void* data,
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
struct itimerspec timer = {};
|
||||
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
||||
|
||||
_glfw.wl.serial = serial;
|
||||
_glfw.wl.keyboardFocus = NULL;
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
}
|
||||
|
||||
static int toGLFWKeyCode(uint32_t key)
|
||||
static int translateKey(uint32_t scancode)
|
||||
{
|
||||
if (key < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
|
||||
return _glfw.wl.keycodes[key];
|
||||
if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
|
||||
return _glfw.wl.keycodes[scancode];
|
||||
|
||||
return GLFW_KEY_UNKNOWN;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
||||
{
|
||||
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
|
||||
@ -538,77 +534,65 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static GLFWbool inputChar(_GLFWwindow* window, uint32_t key)
|
||||
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode)
|
||||
{
|
||||
uint32_t code, numSyms;
|
||||
long cp;
|
||||
const xkb_keysym_t *syms;
|
||||
xkb_keysym_t sym;
|
||||
const xkb_keysym_t* keysyms;
|
||||
const xkb_keycode_t keycode = scancode + 8;
|
||||
|
||||
code = key + 8;
|
||||
numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms);
|
||||
|
||||
if (numSyms == 1)
|
||||
if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)
|
||||
{
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
sym = composeSymbol(syms[0]);
|
||||
#else
|
||||
sym = syms[0];
|
||||
#endif
|
||||
cp = _glfwKeySym2Unicode(sym);
|
||||
if (cp != -1)
|
||||
const xkb_keysym_t keysym = composeSymbol(keysyms[0]);
|
||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||
if (codepoint != GLFW_INVALID_CODEPOINT)
|
||||
{
|
||||
const int mods = _glfw.wl.xkb.modifiers;
|
||||
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
||||
_glfwInputChar(window, cp, mods, plain);
|
||||
_glfwInputChar(window, codepoint, mods, plain);
|
||||
}
|
||||
}
|
||||
|
||||
return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, code);
|
||||
return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode);
|
||||
}
|
||||
|
||||
static void keyboardHandleKey(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t scancode,
|
||||
uint32_t state)
|
||||
{
|
||||
int keyCode;
|
||||
int action;
|
||||
_GLFWwindow* window = _glfw.wl.keyboardFocus;
|
||||
GLFWbool shouldRepeat;
|
||||
struct itimerspec timer = {};
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
keyCode = toGLFWKeyCode(key);
|
||||
action = state == WL_KEYBOARD_KEY_STATE_PRESSED
|
||||
? GLFW_PRESS : GLFW_RELEASE;
|
||||
const int key = translateKey(scancode);
|
||||
const int action =
|
||||
state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
||||
|
||||
_glfw.wl.serial = serial;
|
||||
_glfwInputKey(window, keyCode, key, action,
|
||||
_glfw.wl.xkb.modifiers);
|
||||
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
||||
|
||||
struct itimerspec timer = {};
|
||||
|
||||
if (action == GLFW_PRESS)
|
||||
{
|
||||
shouldRepeat = inputChar(window, key);
|
||||
const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode);
|
||||
|
||||
if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0)
|
||||
{
|
||||
_glfw.wl.keyboardLastKey = keyCode;
|
||||
_glfw.wl.keyboardLastScancode = key;
|
||||
_glfw.wl.keyboardLastKey = key;
|
||||
_glfw.wl.keyboardLastScancode = scancode;
|
||||
if (_glfw.wl.keyboardRepeatRate > 1)
|
||||
timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate;
|
||||
else
|
||||
timer.it_interval.tv_sec = 1;
|
||||
|
||||
timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000;
|
||||
timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
||||
}
|
||||
|
||||
@ -620,9 +604,6 @@ static void keyboardHandleModifiers(void* data,
|
||||
uint32_t modsLocked,
|
||||
uint32_t group)
|
||||
{
|
||||
xkb_mod_mask_t mask;
|
||||
unsigned int modifiers = 0;
|
||||
|
||||
_glfw.wl.serial = serial;
|
||||
|
||||
if (!_glfw.wl.xkb.keymap)
|
||||
@ -636,24 +617,29 @@ static void keyboardHandleModifiers(void* data,
|
||||
0,
|
||||
group);
|
||||
|
||||
mask = xkb_state_serialize_mods(_glfw.wl.xkb.state,
|
||||
const xkb_mod_mask_t mask =
|
||||
xkb_state_serialize_mods(_glfw.wl.xkb.state,
|
||||
XKB_STATE_MODS_DEPRESSED |
|
||||
XKB_STATE_LAYOUT_DEPRESSED |
|
||||
XKB_STATE_MODS_LATCHED |
|
||||
XKB_STATE_LAYOUT_LATCHED);
|
||||
|
||||
unsigned int mods = 0;
|
||||
|
||||
if (mask & _glfw.wl.xkb.controlMask)
|
||||
modifiers |= GLFW_MOD_CONTROL;
|
||||
mods |= GLFW_MOD_CONTROL;
|
||||
if (mask & _glfw.wl.xkb.altMask)
|
||||
modifiers |= GLFW_MOD_ALT;
|
||||
mods |= GLFW_MOD_ALT;
|
||||
if (mask & _glfw.wl.xkb.shiftMask)
|
||||
modifiers |= GLFW_MOD_SHIFT;
|
||||
mods |= GLFW_MOD_SHIFT;
|
||||
if (mask & _glfw.wl.xkb.superMask)
|
||||
modifiers |= GLFW_MOD_SUPER;
|
||||
mods |= GLFW_MOD_SUPER;
|
||||
if (mask & _glfw.wl.xkb.capsLockMask)
|
||||
modifiers |= GLFW_MOD_CAPS_LOCK;
|
||||
mods |= GLFW_MOD_CAPS_LOCK;
|
||||
if (mask & _glfw.wl.xkb.numLockMask)
|
||||
modifiers |= GLFW_MOD_NUM_LOCK;
|
||||
_glfw.wl.xkb.modifiers = modifiers;
|
||||
mods |= GLFW_MOD_NUM_LOCK;
|
||||
|
||||
_glfw.wl.xkb.modifiers = mods;
|
||||
}
|
||||
|
||||
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
||||
@ -886,10 +872,9 @@ static void registryHandleGlobalRemove(void *data,
|
||||
struct wl_registry *registry,
|
||||
uint32_t name)
|
||||
{
|
||||
int i;
|
||||
_GLFWmonitor* monitor;
|
||||
|
||||
for (i = 0; i < _glfw.monitorCount; ++i)
|
||||
for (int i = 0; i < _glfw.monitorCount; ++i)
|
||||
{
|
||||
monitor = _glfw.monitors[i];
|
||||
if (monitor->wl.name == name)
|
||||
@ -910,8 +895,6 @@ static const struct wl_registry_listener registryListener = {
|
||||
//
|
||||
static void createKeyTables(void)
|
||||
{
|
||||
int scancode;
|
||||
|
||||
memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes));
|
||||
memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));
|
||||
|
||||
@ -973,7 +956,7 @@ static void createKeyTables(void)
|
||||
_glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
|
||||
_glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
|
||||
_glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
|
||||
_glfw.wl.keycodes[KEY_MENU] = GLFW_KEY_MENU;
|
||||
_glfw.wl.keycodes[KEY_COMPOSE] = GLFW_KEY_MENU;
|
||||
_glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
|
||||
_glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
|
||||
_glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
|
||||
@ -1016,7 +999,7 @@ static void createKeyTables(void)
|
||||
_glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23;
|
||||
_glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24;
|
||||
_glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
|
||||
_glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY;
|
||||
_glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY;
|
||||
_glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
|
||||
_glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
|
||||
_glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
|
||||
@ -1029,11 +1012,12 @@ static void createKeyTables(void)
|
||||
_glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
|
||||
_glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
|
||||
_glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
|
||||
_glfw.wl.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL;
|
||||
_glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_DECIMAL;
|
||||
_glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
|
||||
_glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
|
||||
_glfw.wl.keycodes[KEY_102ND] = GLFW_KEY_WORLD_2;
|
||||
|
||||
for (scancode = 0; scancode < 256; scancode++)
|
||||
for (int scancode = 0; scancode < 256; scancode++)
|
||||
{
|
||||
if (_glfw.wl.keycodes[scancode] > 0)
|
||||
_glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode;
|
||||
@ -1290,6 +1274,8 @@ int _glfwInitWayland(void)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
|
||||
_glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
|
||||
_glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level");
|
||||
_glfw.wl.xkb.state_new = (PFN_xkb_state_new)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new");
|
||||
_glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
|
||||
@ -1300,8 +1286,8 @@ int _glfwInitWayland(void)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask");
|
||||
_glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
_glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout");
|
||||
_glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
|
||||
_glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
|
||||
@ -1316,7 +1302,6 @@ int _glfwInitWayland(void)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
|
||||
_glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
|
||||
#endif
|
||||
|
||||
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||
@ -1339,7 +1324,7 @@ int _glfwInitWayland(void)
|
||||
|
||||
_glfw.wl.timerfd = -1;
|
||||
if (_glfw.wl.seatVersion >= 4)
|
||||
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||
|
||||
if (!_glfw.wl.wmBase)
|
||||
{
|
||||
@ -1373,7 +1358,7 @@ int _glfwInitWayland(void)
|
||||
wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
|
||||
_glfw.wl.cursorSurface =
|
||||
wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||
}
|
||||
|
||||
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
|
||||
@ -1404,10 +1389,8 @@ void _glfwTerminateWayland(void)
|
||||
_glfw.wl.egl.handle = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
if (_glfw.wl.xkb.composeState)
|
||||
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
||||
#endif
|
||||
if (_glfw.wl.xkb.keymap)
|
||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||
if (_glfw.wl.xkb.state)
|
||||
|
@ -26,9 +26,7 @@
|
||||
|
||||
#include <wayland-client-core.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
#endif
|
||||
|
||||
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||
|
||||
@ -163,24 +161,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);
|
||||
#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
|
||||
|
||||
#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);
|
||||
@ -195,7 +196,6 @@ 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
|
||||
@ -311,6 +311,7 @@ typedef struct _GLFWlibraryWayland
|
||||
int timerfd;
|
||||
short int keycodes[256];
|
||||
short int scancodes[GLFW_KEY_LAST + 1];
|
||||
char keynames[GLFW_KEY_LAST + 1][5];
|
||||
|
||||
struct {
|
||||
void* handle;
|
||||
@ -318,9 +319,7 @@ typedef struct _GLFWlibraryWayland
|
||||
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;
|
||||
@ -336,13 +335,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;
|
||||
|
||||
#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;
|
||||
@ -350,7 +350,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;
|
||||
@ -496,4 +495,5 @@ GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode);
|
||||
|
||||
|
229
src/wl_window.c
229
src/wl_window.c
@ -144,9 +144,8 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
int stride = image->width * 4;
|
||||
int length = image->width * image->height * 4;
|
||||
void* data;
|
||||
int fd, i;
|
||||
|
||||
fd = createAnonymousFile(length);
|
||||
const int fd = createAnonymousFile(length);
|
||||
if (fd < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
@ -169,7 +168,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
close(fd);
|
||||
unsigned char* source = (unsigned char*) image->pixels;
|
||||
unsigned char* target = data;
|
||||
for (i = 0; i < image->width * image->height; i++, source += 4)
|
||||
for (int i = 0; i < image->width * image->height; i++, source += 4)
|
||||
{
|
||||
unsigned int alpha = source[3];
|
||||
|
||||
@ -347,7 +346,6 @@ static void resizeWindow(_GLFWwindow* window)
|
||||
static void checkScaleChange(_GLFWwindow* window)
|
||||
{
|
||||
int scale = 1;
|
||||
int i;
|
||||
int monitorScale;
|
||||
|
||||
// Check if we will be able to set the buffer scale or not.
|
||||
@ -355,7 +353,7 @@ static void checkScaleChange(_GLFWwindow* window)
|
||||
return;
|
||||
|
||||
// Get the scale factor from the highest scale monitor.
|
||||
for (i = 0; i < window->wl.monitorsCount; ++i)
|
||||
for (int i = 0; i < window->wl.monitorsCount; ++i)
|
||||
{
|
||||
monitorScale = window->wl.monitors[i]->wl.scale;
|
||||
if (scale < monitorScale)
|
||||
@ -397,10 +395,9 @@ static void surfaceHandleLeave(void *data,
|
||||
{
|
||||
_GLFWwindow* window = data;
|
||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||
GLFWbool found;
|
||||
int i;
|
||||
GLFWbool found = GLFW_FALSE;
|
||||
|
||||
for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
|
||||
for (int i = 0; i < window->wl.monitorsCount - 1; ++i)
|
||||
{
|
||||
if (monitor == window->wl.monitors[i])
|
||||
found = GLFW_TRUE;
|
||||
@ -435,35 +432,6 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
||||
}
|
||||
}
|
||||
|
||||
static GLFWbool createSurface(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig)
|
||||
{
|
||||
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
if (!window->wl.surface)
|
||||
return GLFW_FALSE;
|
||||
|
||||
wl_surface_add_listener(window->wl.surface,
|
||||
&surfaceListener,
|
||||
window);
|
||||
|
||||
wl_surface_set_user_data(window->wl.surface, window);
|
||||
|
||||
window->wl.native = wl_egl_window_create(window->wl.surface,
|
||||
wndconfig->width,
|
||||
wndconfig->height);
|
||||
if (!window->wl.native)
|
||||
return GLFW_FALSE;
|
||||
|
||||
window->wl.width = wndconfig->width;
|
||||
window->wl.height = wndconfig->height;
|
||||
window->wl.scale = 1;
|
||||
|
||||
if (!window->wl.transparent)
|
||||
setOpaqueRegion(window);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||
int refreshRate)
|
||||
{
|
||||
@ -540,7 +508,6 @@ static void xdgToplevelHandleConfigure(void* data,
|
||||
}
|
||||
if (fullscreen && activated)
|
||||
window->wl.wasFullscreen = GLFW_TRUE;
|
||||
_glfwInputWindowFocus(window, activated);
|
||||
}
|
||||
|
||||
static void xdgToplevelHandleClose(void* data,
|
||||
@ -648,6 +615,46 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static GLFWbool createSurface(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
if (!window->wl.surface)
|
||||
return GLFW_FALSE;
|
||||
|
||||
wl_surface_add_listener(window->wl.surface,
|
||||
&surfaceListener,
|
||||
window);
|
||||
|
||||
wl_surface_set_user_data(window->wl.surface, window);
|
||||
|
||||
window->wl.native = wl_egl_window_create(window->wl.surface,
|
||||
wndconfig->width,
|
||||
wndconfig->height);
|
||||
if (!window->wl.native)
|
||||
return GLFW_FALSE;
|
||||
|
||||
window->wl.width = wndconfig->width;
|
||||
window->wl.height = wndconfig->height;
|
||||
window->wl.scale = 1;
|
||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||
|
||||
window->wl.transparent = fbconfig->transparent;
|
||||
if (!window->wl.transparent)
|
||||
setOpaqueRegion(window);
|
||||
|
||||
if (window->monitor || wndconfig->visible)
|
||||
{
|
||||
if (!createXdgSurface(window))
|
||||
return GLFW_FALSE;
|
||||
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static void setCursorImage(_GLFWwindow* window,
|
||||
_GLFWcursorWayland* cursorWayland)
|
||||
{
|
||||
@ -712,22 +719,19 @@ static void incrementCursorImage(_GLFWwindow* window)
|
||||
|
||||
static void handleEvents(int timeout)
|
||||
{
|
||||
struct wl_display* display = _glfw.wl.display;
|
||||
struct pollfd fds[] = {
|
||||
{ wl_display_get_fd(display), POLLIN },
|
||||
struct pollfd fds[] =
|
||||
{
|
||||
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
||||
{ _glfw.wl.timerfd, POLLIN },
|
||||
{ _glfw.wl.cursorTimerfd, POLLIN },
|
||||
};
|
||||
ssize_t read_ret;
|
||||
uint64_t repeats, i;
|
||||
|
||||
while (wl_display_prepare_read(display) != 0)
|
||||
wl_display_dispatch_pending(display);
|
||||
while (wl_display_prepare_read(_glfw.wl.display) != 0)
|
||||
wl_display_dispatch_pending(_glfw.wl.display);
|
||||
|
||||
// If an error different from EAGAIN happens, we have likely been
|
||||
// disconnected from the Wayland session, try to handle that the best we
|
||||
// can.
|
||||
if (wl_display_flush(display) < 0 && errno != EAGAIN)
|
||||
// If an error other than EAGAIN happens, we have likely been disconnected
|
||||
// from the Wayland session; try to handle that the best we can.
|
||||
if (wl_display_flush(_glfw.wl.display) < 0 && errno != EAGAIN)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.windowListHead;
|
||||
while (window)
|
||||
@ -735,7 +739,8 @@ static void handleEvents(int timeout)
|
||||
_glfwInputWindowCloseRequest(window);
|
||||
window = window->next;
|
||||
}
|
||||
wl_display_cancel_read(display);
|
||||
|
||||
wl_display_cancel_read(_glfw.wl.display);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -743,46 +748,41 @@ static void handleEvents(int timeout)
|
||||
{
|
||||
if (fds[0].revents & POLLIN)
|
||||
{
|
||||
wl_display_read_events(display);
|
||||
wl_display_dispatch_pending(display);
|
||||
wl_display_read_events(_glfw.wl.display);
|
||||
wl_display_dispatch_pending(_glfw.wl.display);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_display_cancel_read(display);
|
||||
}
|
||||
wl_display_cancel_read(_glfw.wl.display);
|
||||
|
||||
if (fds[1].revents & POLLIN)
|
||||
{
|
||||
read_ret = read(_glfw.wl.timerfd, &repeats, sizeof(repeats));
|
||||
if (read_ret != 8)
|
||||
return;
|
||||
uint64_t repeats;
|
||||
|
||||
if (_glfw.wl.keyboardFocus)
|
||||
if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8)
|
||||
{
|
||||
for (i = 0; i < repeats; ++i)
|
||||
for (uint64_t i = 0; i < repeats; i++)
|
||||
{
|
||||
_glfwInputKey(_glfw.wl.keyboardFocus,
|
||||
_glfw.wl.keyboardLastKey,
|
||||
_glfw.wl.keyboardLastScancode,
|
||||
GLFW_REPEAT,
|
||||
GLFW_PRESS,
|
||||
_glfw.wl.xkb.modifiers);
|
||||
_glfwInputTextWayland(_glfw.wl.keyboardFocus,
|
||||
_glfw.wl.keyboardLastScancode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fds[2].revents & POLLIN)
|
||||
{
|
||||
read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats));
|
||||
if (read_ret != 8)
|
||||
return;
|
||||
uint64_t repeats;
|
||||
|
||||
if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)
|
||||
incrementCursorImage(_glfw.wl.pointerFocus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_display_cancel_read(display);
|
||||
}
|
||||
wl_display_cancel_read(_glfw.wl.display);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -794,9 +794,7 @@ int _glfwCreateWindowWayland(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
window->wl.transparent = fbconfig->transparent;
|
||||
|
||||
if (!createSurface(window, wndconfig))
|
||||
if (!createSurface(window, wndconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
@ -818,29 +816,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
if (wndconfig->title)
|
||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
if (!createXdgSurface(window))
|
||||
return GLFW_FALSE;
|
||||
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
window->wl.xdg.surface = NULL;
|
||||
window->wl.xdg.toplevel = NULL;
|
||||
window->wl.visible = GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->wl.currentCursor = NULL;
|
||||
|
||||
window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*));
|
||||
window->wl.monitorsCount = 0;
|
||||
window->wl.monitorsSize = 1;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -1027,21 +1002,24 @@ void _glfwShowWindowWayland(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->wl.visible)
|
||||
{
|
||||
// NOTE: The XDG surface and role are created here so command-line applications
|
||||
// with off-screen windows do not appear in for example the Unity dock
|
||||
if (!window->wl.xdg.toplevel)
|
||||
createXdgSurface(window);
|
||||
|
||||
window->wl.visible = GLFW_TRUE;
|
||||
_glfwInputWindowDamage(window);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwHideWindowWayland(_GLFWwindow* window)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
if (window->wl.visible)
|
||||
{
|
||||
xdg_toplevel_destroy(window->wl.xdg.toplevel);
|
||||
xdg_surface_destroy(window->wl.xdg.surface);
|
||||
window->wl.xdg.toplevel = NULL;
|
||||
window->wl.xdg.surface = NULL;
|
||||
}
|
||||
window->wl.visible = GLFW_FALSE;
|
||||
wl_surface_attach(window->wl.surface, NULL, 0, 0);
|
||||
wl_surface_commit(window->wl.surface);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)
|
||||
@ -1217,12 +1195,59 @@ void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
|
||||
|
||||
const char* _glfwGetScancodeNameWayland(int scancode)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||
"Wayland: Key names not yet implemented");
|
||||
if (scancode < 0 || scancode > 255 ||
|
||||
_glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Wayland: Invalid scancode %i",
|
||||
scancode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int key = _glfw.wl.keycodes[scancode];
|
||||
const xkb_keycode_t keycode = scancode + 8;
|
||||
const xkb_layout_index_t layout =
|
||||
xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode);
|
||||
if (layout == XKB_LAYOUT_INVALID)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to retrieve layout for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const xkb_keysym_t* keysyms = NULL;
|
||||
xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap,
|
||||
keycode,
|
||||
layout,
|
||||
0,
|
||||
&keysyms);
|
||||
if (keysyms == NULL)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to retrieve keysym for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]);
|
||||
if (codepoint == GLFW_INVALID_CODEPOINT)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to retrieve codepoint for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], codepoint);
|
||||
if (count == 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to encode codepoint for key name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_glfw.wl.keynames[key][count] = '\0';
|
||||
return _glfw.wl.keynames[key];
|
||||
}
|
||||
|
||||
int _glfwGetKeyScancodeWayland(int key)
|
||||
{
|
||||
return _glfw.wl.scancodes[key];
|
||||
|
@ -209,7 +209,7 @@ static int translateKeySyms(const KeySym* keysyms, int width)
|
||||
//
|
||||
static void createKeyTables(void)
|
||||
{
|
||||
int scancode, scancodeMin, scancodeMax;
|
||||
int scancodeMin, scancodeMax;
|
||||
|
||||
memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
|
||||
memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
|
||||
@ -355,7 +355,7 @@ static void createKeyTables(void)
|
||||
};
|
||||
|
||||
// Find the X11 key code -> GLFW key code mapping
|
||||
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||
for (int scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||
{
|
||||
int key = GLFW_KEY_UNKNOWN;
|
||||
|
||||
@ -414,7 +414,7 @@ static void createKeyTables(void)
|
||||
scancodeMax - scancodeMin + 1,
|
||||
&width);
|
||||
|
||||
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||
for (int scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||
{
|
||||
// Translate the un-translated key codes using traditional X11 KeySym
|
||||
// lookups
|
||||
@ -601,7 +601,11 @@ static void detectEWMH(void)
|
||||
//
|
||||
static GLFWbool initExtensions(void)
|
||||
{
|
||||
#if defined(__OpenBSD__)
|
||||
_glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so");
|
||||
#else
|
||||
_glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so.1");
|
||||
#endif
|
||||
if (_glfw.x11.vidmode.handle)
|
||||
{
|
||||
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
||||
@ -621,6 +625,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi-6.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so");
|
||||
#else
|
||||
_glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so.6");
|
||||
#endif
|
||||
@ -651,6 +657,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr-2.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so");
|
||||
#else
|
||||
_glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so.2");
|
||||
#endif
|
||||
@ -743,6 +751,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor-1.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so");
|
||||
#else
|
||||
_glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so.1");
|
||||
#endif
|
||||
@ -764,6 +774,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama-1.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so");
|
||||
#else
|
||||
_glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so.1");
|
||||
#endif
|
||||
@ -817,6 +829,8 @@ static GLFWbool initExtensions(void)
|
||||
{
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb-1.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so");
|
||||
#else
|
||||
_glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so.1");
|
||||
#endif
|
||||
@ -830,6 +844,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender-1.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so");
|
||||
#else
|
||||
_glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so.1");
|
||||
#endif
|
||||
@ -857,6 +873,8 @@ static GLFWbool initExtensions(void)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext-6.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so");
|
||||
#else
|
||||
_glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so.6");
|
||||
#endif
|
||||
@ -1072,7 +1090,6 @@ void _glfwInputErrorX11(int error, const char* message)
|
||||
//
|
||||
Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot)
|
||||
{
|
||||
int i;
|
||||
Cursor cursor;
|
||||
|
||||
if (!_glfw.x11.xcursor.handle)
|
||||
@ -1088,7 +1105,7 @@ Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot)
|
||||
unsigned char* source = (unsigned char*) image->pixels;
|
||||
XcursorPixel* target = native->pixels;
|
||||
|
||||
for (i = 0; i < image->width * image->height; i++, target++, source += 4)
|
||||
for (int i = 0; i < image->width * image->height; i++, target++, source += 4)
|
||||
{
|
||||
unsigned int alpha = source[3];
|
||||
|
||||
@ -1204,6 +1221,8 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
void* module = _glfwPlatformLoadModule("libX11-6.so");
|
||||
#elif defined(__OpenBSD__)
|
||||
void* module = _glfwPlatformLoadModule("libX11.so");
|
||||
#else
|
||||
void* module = _glfwPlatformLoadModule("libX11.so.6");
|
||||
#endif
|
||||
|
121
src/x11_window.c
121
src/x11_window.c
@ -429,44 +429,13 @@ static char** parseUriList(char* text, int* count)
|
||||
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)
|
||||
//
|
||||
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
|
||||
@ -474,13 +443,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];
|
||||
}
|
||||
|
||||
// Convert the specified Latin-1 string to UTF-8
|
||||
@ -497,7 +466,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;
|
||||
}
|
||||
@ -788,7 +757,6 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
//
|
||||
static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
{
|
||||
int i;
|
||||
char* selectionString = NULL;
|
||||
const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
|
||||
const int formatCount = sizeof(formats) / sizeof(formats[0]);
|
||||
@ -831,14 +799,13 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
// Multiple conversions were requested
|
||||
|
||||
Atom* targets;
|
||||
unsigned long i, count;
|
||||
|
||||
count = _glfwGetWindowPropertyX11(request->requestor,
|
||||
const unsigned long count =
|
||||
_glfwGetWindowPropertyX11(request->requestor,
|
||||
request->property,
|
||||
_glfw.x11.ATOM_PAIR,
|
||||
(unsigned char**) &targets);
|
||||
|
||||
for (i = 0; i < count; i += 2)
|
||||
for (unsigned long i = 0; i < count; i += 2)
|
||||
{
|
||||
int j;
|
||||
|
||||
@ -896,7 +863,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
|
||||
// Conversion to a data target was requested
|
||||
|
||||
for (i = 0; i < formatCount; i++)
|
||||
for (int i = 0; i < formatCount; i++)
|
||||
{
|
||||
if (request->target == formats[i])
|
||||
{
|
||||
@ -1319,9 +1286,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;
|
||||
@ -1588,7 +1555,7 @@ static void processEvent(XEvent *event)
|
||||
else if (event->xclient.message_type == _glfw.x11.XdndEnter)
|
||||
{
|
||||
// A drag operation has entered the window
|
||||
unsigned long i, count;
|
||||
unsigned long count;
|
||||
Atom* formats = NULL;
|
||||
const GLFWbool list = event->xclient.data.l[1] & 1;
|
||||
|
||||
@ -1612,7 +1579,7 @@ static void processEvent(XEvent *event)
|
||||
formats = (Atom*) event->xclient.data.l + 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (formats[i] == _glfw.x11.text_uri_list)
|
||||
{
|
||||
@ -1718,12 +1685,12 @@ static void processEvent(XEvent *event)
|
||||
|
||||
if (result)
|
||||
{
|
||||
int i, count;
|
||||
int count;
|
||||
char** paths = parseUriList(data, &count);
|
||||
|
||||
_glfwInputDrop(window, count, (const char**) paths);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (int i = 0; i < count; i++)
|
||||
_glfw_free(paths[i]);
|
||||
_glfw_free(paths);
|
||||
}
|
||||
@ -2102,28 +2069,34 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
int i, j, longCount = 0;
|
||||
int longCount = 0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (int i = 0; i < count; i++)
|
||||
longCount += 2 + images[i].width * images[i].height;
|
||||
|
||||
long* icon = _glfw_calloc(longCount, sizeof(long));
|
||||
long* target = icon;
|
||||
unsigned long* icon = _glfw_calloc(longCount, sizeof(unsigned long));
|
||||
unsigned long* target = icon;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
*target++ = images[i].width;
|
||||
*target++ = images[i].height;
|
||||
|
||||
for (j = 0; j < images[i].width * images[i].height; j++)
|
||||
for (int 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,
|
||||
@ -2537,7 +2510,6 @@ int _glfwWindowVisibleX11(_GLFWwindow* window)
|
||||
int _glfwWindowMaximizedX11(_GLFWwindow* window)
|
||||
{
|
||||
Atom* states;
|
||||
unsigned long i;
|
||||
GLFWbool maximized = GLFW_FALSE;
|
||||
|
||||
if (!_glfw.x11.NET_WM_STATE ||
|
||||
@ -2553,7 +2525,7 @@ int _glfwWindowMaximizedX11(_GLFWwindow* window)
|
||||
XA_ATOM,
|
||||
(unsigned char**) &states);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (unsigned long i = 0; i < count; i++)
|
||||
{
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
|
||||
states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||
@ -2651,9 +2623,8 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
|
||||
else
|
||||
{
|
||||
Atom* states = NULL;
|
||||
unsigned long i, count;
|
||||
|
||||
count = _glfwGetWindowPropertyX11(window->x11.handle,
|
||||
const unsigned long count =
|
||||
_glfwGetWindowPropertyX11(window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE,
|
||||
XA_ATOM,
|
||||
(unsigned char**) &states);
|
||||
@ -2663,6 +2634,8 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
||||
@ -2680,20 +2653,16 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled)
|
||||
}
|
||||
else if (states)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
for (unsigned long i = 0; i < count; i++)
|
||||
{
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < count)
|
||||
{
|
||||
states[i] = states[count - 1];
|
||||
count--;
|
||||
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) states, count);
|
||||
PropModeReplace, (unsigned char*) states, count - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2899,11 +2868,11 @@ const char* _glfwGetScancodeNameX11(int scancode)
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -24,5 +24,7 @@
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
long _glfwKeySym2Unicode(unsigned int keysym);
|
||||
#define GLFW_INVALID_CODEPOINT 0xffffffffu
|
||||
|
||||
uint32_t _glfwKeySym2Unicode(unsigned int keysym);
|
||||
|
||||
|
@ -113,6 +113,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);
|
||||
|
@ -462,7 +462,9 @@ int main(int argc, char** argv)
|
||||
switch (ch)
|
||||
{
|
||||
case PLATFORM:
|
||||
if (strcasecmp(optarg, PLATFORM_NAME_WIN32) == 0)
|
||||
if (strcasecmp(optarg, PLATFORM_NAME_ANY) == 0)
|
||||
platform = GLFW_ANY_PLATFORM;
|
||||
else if (strcasecmp(optarg, PLATFORM_NAME_WIN32) == 0)
|
||||
platform = GLFW_PLATFORM_WIN32;
|
||||
else if (strcasecmp(optarg, PLATFORM_NAME_COCOA) == 0)
|
||||
platform = GLFW_PLATFORM_COCOA;
|
||||
|
@ -38,7 +38,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)
|
||||
{
|
||||
@ -181,8 +181,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);
|
||||
|
@ -121,7 +121,7 @@ int main(int argc, char** argv)
|
||||
nk_glfw3_new_frame();
|
||||
if (nk_begin(nk, "main", area, 0))
|
||||
{
|
||||
nk_layout_row_dynamic(nk, 30, 4);
|
||||
nk_layout_row_dynamic(nk, 30, 5);
|
||||
|
||||
if (nk_button_label(nk, "Toggle Fullscreen"))
|
||||
{
|
||||
@ -149,6 +149,16 @@ int main(int argc, char** argv)
|
||||
glfwIconifyWindow(window);
|
||||
if (nk_button_label(nk, "Restore"))
|
||||
glfwRestoreWindow(window);
|
||||
if (nk_button_label(nk, "Hide (briefly)"))
|
||||
{
|
||||
glfwHideWindow(window);
|
||||
|
||||
const double time = glfwGetTime() + 3.0;
|
||||
while (glfwGetTime() < time)
|
||||
glfwWaitEventsTimeout(1.0);
|
||||
|
||||
glfwShowWindow(window);
|
||||
}
|
||||
|
||||
nk_layout_row_dynamic(nk, 30, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user