mirror of
https://github.com/glfw/glfw.git
synced 2025-10-03 13:20:58 +00:00
commit
10884b9a1f
1
.gitignore
vendored
1
.gitignore
vendored
@ -100,5 +100,6 @@ tests/threads
|
|||||||
tests/timeout
|
tests/timeout
|
||||||
tests/title
|
tests/title
|
||||||
tests/triangle-vulkan
|
tests/triangle-vulkan
|
||||||
|
tests/window
|
||||||
tests/windows
|
tests/windows
|
||||||
|
|
||||||
|
32
.travis.yml
32
.travis.yml
@ -9,7 +9,6 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
sudo: false
|
|
||||||
name: "X11 shared library"
|
name: "X11 shared library"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
@ -18,12 +17,12 @@ matrix:
|
|||||||
- libxinerama-dev
|
- libxinerama-dev
|
||||||
- libxcursor-dev
|
- libxcursor-dev
|
||||||
- libxi-dev
|
- libxi-dev
|
||||||
|
- libxext-dev
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=ON
|
- BUILD_SHARED_LIBS=ON
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
sudo: false
|
|
||||||
name: "X11 static library"
|
name: "X11 static library"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
@ -32,12 +31,12 @@ matrix:
|
|||||||
- libxinerama-dev
|
- libxinerama-dev
|
||||||
- libxcursor-dev
|
- libxcursor-dev
|
||||||
- libxi-dev
|
- libxi-dev
|
||||||
|
- libxext-dev
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=OFF
|
- BUILD_SHARED_LIBS=OFF
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
sudo: required
|
|
||||||
name: "Wayland shared library"
|
name: "Wayland shared library"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
@ -54,7 +53,6 @@ matrix:
|
|||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: xenial
|
dist: xenial
|
||||||
sudo: required
|
|
||||||
name: "Wayland static library"
|
name: "Wayland static library"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
@ -69,15 +67,35 @@ matrix:
|
|||||||
- USE_WAYLAND=ON
|
- USE_WAYLAND=ON
|
||||||
- BUILD_SHARED_LIBS=OFF
|
- BUILD_SHARED_LIBS=OFF
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
|
- os: linux
|
||||||
|
dist: bionic
|
||||||
|
name: "Null shared library"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libosmesa6-dev
|
||||||
|
env:
|
||||||
|
- BUILD_SHARED_LIBS=ON
|
||||||
|
- USE_OSMESA=ON
|
||||||
|
- CFLAGS=-Werror
|
||||||
|
- os: linux
|
||||||
|
dist: bionic
|
||||||
|
name: "Null static library"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libosmesa6-dev
|
||||||
|
env:
|
||||||
|
- BUILD_SHARED_LIBS=OFF
|
||||||
|
- USE_OSMESA=ON
|
||||||
|
- CFLAGS=-Werror
|
||||||
- os: osx
|
- os: osx
|
||||||
sudo: false
|
|
||||||
name: "Cocoa shared library"
|
name: "Cocoa shared library"
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=ON
|
- BUILD_SHARED_LIBS=ON
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- MACOSX_DEPLOYMENT_TARGET=10.8
|
- MACOSX_DEPLOYMENT_TARGET=10.8
|
||||||
- os: osx
|
- os: osx
|
||||||
sudo: false
|
|
||||||
name: "Cocoa static library"
|
name: "Cocoa static library"
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=OFF
|
- BUILD_SHARED_LIBS=OFF
|
||||||
@ -96,7 +114,7 @@ script:
|
|||||||
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
||||||
popd;
|
popd;
|
||||||
fi
|
fi
|
||||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} ..
|
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} -DGLFW_USE_OSMESA=${USE_OSMESA} ..
|
||||||
- cmake --build .
|
- cmake --build .
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
|
@ -66,17 +66,6 @@ endif()
|
|||||||
# Set compiler specific flags
|
# Set compiler specific flags
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
if (MSVC90)
|
|
||||||
# Workaround for VS 2008 not shipping with the DirectX 9 SDK
|
|
||||||
include(CheckIncludeFile)
|
|
||||||
check_include_file(dinput.h DINPUT_H_FOUND)
|
|
||||||
if (NOT DINPUT_H_FOUND)
|
|
||||||
message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
|
|
||||||
endif()
|
|
||||||
# Workaround for VS 2008 not shipping with stdint.h
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
||||||
foreach (flag CMAKE_C_FLAGS
|
foreach (flag CMAKE_C_FLAGS
|
||||||
CMAKE_C_FLAGS_DEBUG
|
CMAKE_C_FLAGS_DEBUG
|
||||||
@ -95,41 +84,6 @@ if (MSVC)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MINGW)
|
|
||||||
# Workaround for legacy MinGW not providing XInput and DirectInput
|
|
||||||
include(CheckIncludeFile)
|
|
||||||
|
|
||||||
check_include_file(dinput.h DINPUT_H_FOUND)
|
|
||||||
check_include_file(xinput.h XINPUT_H_FOUND)
|
|
||||||
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Enable link-time exploit mitigation features enabled by default on MSVC
|
|
||||||
include(CheckCCompilerFlag)
|
|
||||||
|
|
||||||
# Compatibility with data execution prevention (DEP)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
|
|
||||||
check_c_compiler_flag("" _GLFW_HAS_DEP)
|
|
||||||
if (_GLFW_HAS_DEP)
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Compatibility with address space layout randomization (ASLR)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
|
|
||||||
check_c_compiler_flag("" _GLFW_HAS_ASLR)
|
|
||||||
if (_GLFW_HAS_ASLR)
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Compatibility with 64-bit address space layout randomization (ASLR)
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
|
|
||||||
check_c_compiler_flag("" _GLFW_HAS_64ASLR)
|
|
||||||
if (_GLFW_HAS_64ASLR)
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Detect and select backend APIs
|
# Detect and select backend APIs
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@ -222,6 +176,11 @@ if (_GLFW_X11)
|
|||||||
if (NOT X11_Xi_INCLUDE_PATH)
|
if (NOT X11_Xi_INCLUDE_PATH)
|
||||||
message(FATAL_ERROR "XInput headers not found; install libxi development package")
|
message(FATAL_ERROR "XInput headers not found; install libxi development package")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# 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()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@ -257,13 +216,6 @@ if (_GLFW_WAYLAND)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
# Use OSMesa for offscreen context creation
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
if (_GLFW_OSMESA)
|
|
||||||
find_package(OSMesa REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Use Cocoa for window creation and NSOpenGL for context creation
|
# Use Cocoa for window creation and NSOpenGL for context creation
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
45
README.md
45
README.md
@ -124,6 +124,13 @@ information on what to include when reporting a bug.
|
|||||||
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
||||||
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
|
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
|
||||||
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
|
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
|
||||||
|
- Added `GLFW_MOUSE_PASSTHROUGH` window hint for letting mouse input pass
|
||||||
|
through the window (#1236,#1568)
|
||||||
|
- Added `GLFW_FEATURE_UNAVAILABLE` error for platform limitations (#1692)
|
||||||
|
- Added `GLFW_FEATURE_UNIMPLEMENTED` error for incomplete backends (#1692)
|
||||||
|
- Added `GLFW_ANGLE_PLATFORM_TYPE` init hint and `GLFW_ANGLE_PLATFORM_TYPE_*`
|
||||||
|
values to select ANGLE backend (#1380)
|
||||||
|
- Made joystick subsystem initialize at first use (#1284,#1646)
|
||||||
- Updated the minimum required CMake version to 3.1
|
- Updated the minimum required CMake version to 3.1
|
||||||
- Disabled tests and examples by default when built as a CMake subdirectory
|
- Disabled tests and examples by default when built as a CMake subdirectory
|
||||||
- Bugfix: The CMake config-file package used an absolute path and was not
|
- Bugfix: The CMake config-file package used an absolute path and was not
|
||||||
@ -131,9 +138,13 @@ information on what to include when reporting a bug.
|
|||||||
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
|
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
|
||||||
- Bugfix: Compiling with -Wextra-semi caused warnings (#1440)
|
- Bugfix: Compiling with -Wextra-semi caused warnings (#1440)
|
||||||
- Bugfix: Built-in mappings failed because some OEMs re-used VID/PID (#1583)
|
- Bugfix: Built-in mappings failed because some OEMs re-used VID/PID (#1583)
|
||||||
|
- Bugfix: Some extension loader headers did not prevent default OpenGL header
|
||||||
|
inclusion (#1695)
|
||||||
- [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access
|
- [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access
|
||||||
to the window menu
|
to the window menu
|
||||||
- [Win32] Added a version info resource to the GLFW DLL
|
- [Win32] Added a version info resource to the GLFW DLL
|
||||||
|
- [Win32] Disabled framebuffer transparency on Windows 7 when DWM windows are
|
||||||
|
opaque (#1512)
|
||||||
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
|
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
|
||||||
symbol redefinition (#1524)
|
symbol redefinition (#1524)
|
||||||
- [Win32] Bugfix: The cursor position event was emitted before its cursor enter
|
- [Win32] Bugfix: The cursor position event was emitted before its cursor enter
|
||||||
@ -146,14 +157,23 @@ information on what to include when reporting a bug.
|
|||||||
invalid pointer
|
invalid pointer
|
||||||
- [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN`
|
- [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN`
|
||||||
(#1623)
|
(#1623)
|
||||||
|
- [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
|
||||||
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||||
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||||
|
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
|
||||||
|
- [Cocoa] Changed `EGLNativeWindowType` from `NSView` to `CALayer` (#1169)
|
||||||
- [Cocoa] Removed dependency on the CoreVideo framework
|
- [Cocoa] Removed dependency on the CoreVideo framework
|
||||||
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
||||||
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
||||||
(#1412)
|
(#1412)
|
||||||
- [Cocoa] Bugfix: Event processing before window creation would assert (#1543)
|
- [Cocoa] Bugfix: Event processing before window creation would assert (#1543)
|
||||||
- [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS
|
- [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS
|
||||||
|
- [Cocoa] Bugfix: Touching event queue from secondary thread before main thread
|
||||||
|
would abort (#1649)
|
||||||
|
- [Cocoa] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
|
||||||
|
(#1635)
|
||||||
|
- [Cocoa] Bugfix: Failing to retrieve the refresh rate of built-in displays
|
||||||
|
could leak memory
|
||||||
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
|
- [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
|
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
||||||
(#1462,#1528)
|
(#1462,#1528)
|
||||||
@ -168,14 +188,32 @@ information on what to include when reporting a bug.
|
|||||||
- [X11] Bugfix: `glfwFocusWindow` could terminate on older WMs or without a WM
|
- [X11] Bugfix: `glfwFocusWindow` could terminate on older WMs or without a WM
|
||||||
- [X11] Bugfix: Querying a disconnected monitor could segfault (#1602)
|
- [X11] Bugfix: Querying a disconnected monitor could segfault (#1602)
|
||||||
- [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636)
|
- [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636)
|
||||||
|
- [X11] Bugfix: Termination would segfault if the IM had been destroyed
|
||||||
|
- [X11] Bugfix: Any IM started after initialization would not be detected
|
||||||
|
- [X11] Bugfix: Xlib errors caused by other parts of the application could be
|
||||||
|
reported as GLFW errors
|
||||||
|
- [X11] Bugfix: A handle race condition could cause a `BadWindow` error (#1633)
|
||||||
|
- [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)
|
||||||
|
- [X11] Bugfix: Keys pressed simultaneously with others were not always
|
||||||
|
reported (#1112,#1415,#1472,#1616)
|
||||||
- [Wayland] Removed support for `wl_shell` (#1443)
|
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||||
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
||||||
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
||||||
|
- [Wayland] Bugfix: Repeated keys could be reported with `NULL` window (#1704)
|
||||||
|
- [Wayland] Bugfix: Retrieving partial framebuffer size would segfault
|
||||||
|
- [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms
|
||||||
|
(#1463)
|
||||||
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||||
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
||||||
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
||||||
macOS versions (#1442)
|
macOS versions (#1442)
|
||||||
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
|
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
|
||||||
|
- [EGL] Added platform selection via the `EGL_EXT_platform_base` extension
|
||||||
|
- [EGL] Added ANGLE backend selection via `EGL_ANGLE_platform_angle` extension
|
||||||
|
(#1380)
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
@ -314,6 +352,7 @@ skills.
|
|||||||
- ndogxj
|
- ndogxj
|
||||||
- Kristian Nielsen
|
- Kristian Nielsen
|
||||||
- Kamil Nowakowski
|
- Kamil Nowakowski
|
||||||
|
- onox
|
||||||
- Denis Ovod
|
- Denis Ovod
|
||||||
- Ozzy
|
- Ozzy
|
||||||
- Andri Pálsson
|
- Andri Pálsson
|
||||||
@ -338,8 +377,10 @@ skills.
|
|||||||
- Eddie Ringle
|
- Eddie Ringle
|
||||||
- Max Risuhin
|
- Max Risuhin
|
||||||
- Jorge Rodriguez
|
- Jorge Rodriguez
|
||||||
|
- Luca Rood
|
||||||
- Ed Ropple
|
- Ed Ropple
|
||||||
- Aleksey Rybalkin
|
- Aleksey Rybalkin
|
||||||
|
- Mikko Rytkönen
|
||||||
- Riku Salminen
|
- Riku Salminen
|
||||||
- Brandon Schaefer
|
- Brandon Schaefer
|
||||||
- Sebastian Schuberth
|
- Sebastian Schuberth
|
||||||
@ -347,6 +388,7 @@ skills.
|
|||||||
- Matt Sealey
|
- Matt Sealey
|
||||||
- Steve Sexton
|
- Steve Sexton
|
||||||
- Arkady Shapkin
|
- Arkady Shapkin
|
||||||
|
- Ali Sherief
|
||||||
- Yoshiki Shibukawa
|
- Yoshiki Shibukawa
|
||||||
- Dmitri Shuralyov
|
- Dmitri Shuralyov
|
||||||
- Daniel Skorupski
|
- Daniel Skorupski
|
||||||
@ -380,11 +422,14 @@ skills.
|
|||||||
- Torsten Walluhn
|
- Torsten Walluhn
|
||||||
- Patrick Walton
|
- Patrick Walton
|
||||||
- Xo Wang
|
- Xo Wang
|
||||||
|
- Waris
|
||||||
- Jay Weisskopf
|
- Jay Weisskopf
|
||||||
- Frank Wille
|
- Frank Wille
|
||||||
|
- Tatsuya Yatagawa
|
||||||
- Ryogo Yoshimura
|
- Ryogo Yoshimura
|
||||||
- Lukas Zanner
|
- Lukas Zanner
|
||||||
- Andrey Zholos
|
- Andrey Zholos
|
||||||
|
- Aihui Zhu
|
||||||
- Santi Zupancic
|
- Santi Zupancic
|
||||||
- Jonas Ådahl
|
- Jonas Ådahl
|
||||||
- Lasse Öörni
|
- Lasse Öörni
|
||||||
|
221
deps/linmath.h
vendored
221
deps/linmath.h
vendored
@ -3,31 +3,40 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
/* 2020-03-02 Camilla Löwy <elmindreda@elmindreda.org>
|
||||||
#define inline __inline
|
* - Added inclusion of string.h for memcpy
|
||||||
|
* - Replaced tan and acos with tanf and acosf
|
||||||
|
* - Replaced double constants with float equivalents
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef LINMATH_NO_INLINE
|
||||||
|
#define LINMATH_H_FUNC static
|
||||||
|
#else
|
||||||
|
#define LINMATH_H_FUNC static inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LINMATH_H_DEFINE_VEC(n) \
|
#define LINMATH_H_DEFINE_VEC(n) \
|
||||||
typedef float vec##n[n]; \
|
typedef float vec##n[n]; \
|
||||||
static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
|
LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
int i; \
|
||||||
for(i=0; i<n; ++i) \
|
for(i=0; i<n; ++i) \
|
||||||
r[i] = a[i] + b[i]; \
|
r[i] = a[i] + b[i]; \
|
||||||
} \
|
} \
|
||||||
static inline void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
|
LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
int i; \
|
||||||
for(i=0; i<n; ++i) \
|
for(i=0; i<n; ++i) \
|
||||||
r[i] = a[i] - b[i]; \
|
r[i] = a[i] - b[i]; \
|
||||||
} \
|
} \
|
||||||
static inline void vec##n##_scale(vec##n r, vec##n const v, float const s) \
|
LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \
|
||||||
{ \
|
{ \
|
||||||
int i; \
|
int i; \
|
||||||
for(i=0; i<n; ++i) \
|
for(i=0; i<n; ++i) \
|
||||||
r[i] = v[i] * s; \
|
r[i] = v[i] * s; \
|
||||||
} \
|
} \
|
||||||
static inline float vec##n##_mul_inner(vec##n const a, vec##n const b) \
|
LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \
|
||||||
{ \
|
{ \
|
||||||
float p = 0.; \
|
float p = 0.; \
|
||||||
int i; \
|
int i; \
|
||||||
@ -35,28 +44,40 @@ static inline float vec##n##_mul_inner(vec##n const a, vec##n const b) \
|
|||||||
p += b[i]*a[i]; \
|
p += b[i]*a[i]; \
|
||||||
return p; \
|
return p; \
|
||||||
} \
|
} \
|
||||||
static inline float vec##n##_len(vec##n const v) \
|
LINMATH_H_FUNC float vec##n##_len(vec##n const v) \
|
||||||
{ \
|
{ \
|
||||||
return (float) sqrt(vec##n##_mul_inner(v,v)); \
|
return sqrtf(vec##n##_mul_inner(v,v)); \
|
||||||
} \
|
} \
|
||||||
static inline void vec##n##_norm(vec##n r, vec##n const v) \
|
LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) \
|
||||||
{ \
|
{ \
|
||||||
float k = 1.f / vec##n##_len(v); \
|
float k = 1.f / vec##n##_len(v); \
|
||||||
vec##n##_scale(r, v, k); \
|
vec##n##_scale(r, v, k); \
|
||||||
|
} \
|
||||||
|
LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
for(i=0; i<n; ++i) \
|
||||||
|
r[i] = a[i]<b[i] ? a[i] : b[i]; \
|
||||||
|
} \
|
||||||
|
LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
for(i=0; i<n; ++i) \
|
||||||
|
r[i] = a[i]>b[i] ? a[i] : b[i]; \
|
||||||
}
|
}
|
||||||
|
|
||||||
LINMATH_H_DEFINE_VEC(2)
|
LINMATH_H_DEFINE_VEC(2)
|
||||||
LINMATH_H_DEFINE_VEC(3)
|
LINMATH_H_DEFINE_VEC(3)
|
||||||
LINMATH_H_DEFINE_VEC(4)
|
LINMATH_H_DEFINE_VEC(4)
|
||||||
|
|
||||||
static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
|
LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
|
||||||
{
|
{
|
||||||
r[0] = a[1]*b[2] - a[2]*b[1];
|
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||||
r[1] = a[2]*b[0] - a[0]*b[2];
|
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||||
r[2] = a[0]*b[1] - a[1]*b[0];
|
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
|
LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
|
||||||
{
|
{
|
||||||
float p = 2.f*vec3_mul_inner(v, n);
|
float p = 2.f*vec3_mul_inner(v, n);
|
||||||
int i;
|
int i;
|
||||||
@ -64,7 +85,7 @@ static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
|
|||||||
r[i] = v[i] - p*n[i];
|
r[i] = v[i] - p*n[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
|
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
|
||||||
{
|
{
|
||||||
r[0] = a[1]*b[2] - a[2]*b[1];
|
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||||
r[1] = a[2]*b[0] - a[0]*b[2];
|
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||||
@ -72,7 +93,7 @@ static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
|
|||||||
r[3] = 1.f;
|
r[3] = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vec4_reflect(vec4 r, vec4 v, vec4 n)
|
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 v, vec4 n)
|
||||||
{
|
{
|
||||||
float p = 2.f*vec4_mul_inner(v, n);
|
float p = 2.f*vec4_mul_inner(v, n);
|
||||||
int i;
|
int i;
|
||||||
@ -81,58 +102,58 @@ static inline void vec4_reflect(vec4 r, vec4 v, vec4 n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef vec4 mat4x4[4];
|
typedef vec4 mat4x4[4];
|
||||||
static inline void mat4x4_identity(mat4x4 M)
|
LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
for(j=0; j<4; ++j)
|
for(j=0; j<4; ++j)
|
||||||
M[i][j] = i==j ? 1.f : 0.f;
|
M[i][j] = i==j ? 1.f : 0.f;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_dup(mat4x4 M, mat4x4 N)
|
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 N)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
for(j=0; j<4; ++j)
|
for(j=0; j<4; ++j)
|
||||||
M[i][j] = N[i][j];
|
M[i][j] = N[i][j];
|
||||||
}
|
}
|
||||||
static inline void mat4x4_row(vec4 r, mat4x4 M, int i)
|
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 M, int i)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
for(k=0; k<4; ++k)
|
for(k=0; k<4; ++k)
|
||||||
r[k] = M[k][i];
|
r[k] = M[k][i];
|
||||||
}
|
}
|
||||||
static inline void mat4x4_col(vec4 r, mat4x4 M, int i)
|
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 M, int i)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
for(k=0; k<4; ++k)
|
for(k=0; k<4; ++k)
|
||||||
r[k] = M[i][k];
|
r[k] = M[i][k];
|
||||||
}
|
}
|
||||||
static inline void mat4x4_transpose(mat4x4 M, mat4x4 N)
|
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 N)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for(j=0; j<4; ++j)
|
for(j=0; j<4; ++j)
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
M[i][j] = N[j][i];
|
M[i][j] = N[j][i];
|
||||||
}
|
}
|
||||||
static inline void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b)
|
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
vec4_add(M[i], a[i], b[i]);
|
vec4_add(M[i], a[i], b[i]);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b)
|
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
vec4_sub(M[i], a[i], b[i]);
|
vec4_sub(M[i], a[i], b[i]);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_scale(mat4x4 M, mat4x4 a, float k)
|
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 a, float k)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
vec4_scale(M[i], a[i], k);
|
vec4_scale(M[i], a[i], k);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z)
|
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
vec4_scale(M[0], a[0], x);
|
vec4_scale(M[0], a[0], x);
|
||||||
@ -142,7 +163,7 @@ static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, floa
|
|||||||
M[3][i] = a[3][i];
|
M[3][i] = a[3][i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
|
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||||
{
|
{
|
||||||
mat4x4 temp;
|
mat4x4 temp;
|
||||||
int k, r, c;
|
int k, r, c;
|
||||||
@ -153,7 +174,7 @@ static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
|
|||||||
}
|
}
|
||||||
mat4x4_dup(M, temp);
|
mat4x4_dup(M, temp);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
|
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for(j=0; j<4; ++j) {
|
for(j=0; j<4; ++j) {
|
||||||
@ -162,14 +183,14 @@ static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
|
|||||||
r[j] += M[i][j] * v[i];
|
r[j] += M[i][j] * v[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void mat4x4_translate(mat4x4 T, float x, float y, float z)
|
LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z)
|
||||||
{
|
{
|
||||||
mat4x4_identity(T);
|
mat4x4_identity(T);
|
||||||
T[3][0] = x;
|
T[3][0] = x;
|
||||||
T[3][1] = y;
|
T[3][1] = y;
|
||||||
T[3][2] = z;
|
T[3][2] = z;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
|
LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
|
||||||
{
|
{
|
||||||
vec4 t = {x, y, z, 0};
|
vec4 t = {x, y, z, 0};
|
||||||
vec4 r;
|
vec4 r;
|
||||||
@ -179,33 +200,32 @@ static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z
|
|||||||
M[3][i] += vec4_mul_inner(r, t);
|
M[3][i] += vec4_mul_inner(r, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
|
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
|
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
|
||||||
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
|
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle)
|
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle)
|
||||||
{
|
{
|
||||||
float s = sinf(angle);
|
float s = sinf(angle);
|
||||||
float c = cosf(angle);
|
float c = cosf(angle);
|
||||||
vec3 u = {x, y, z};
|
vec3 u = {x, y, z};
|
||||||
|
|
||||||
if(vec3_len(u) > 1e-4) {
|
if(vec3_len(u) > 1e-4) {
|
||||||
mat4x4 T, C, S = {{0}};
|
|
||||||
|
|
||||||
vec3_norm(u, u);
|
vec3_norm(u, u);
|
||||||
|
mat4x4 T;
|
||||||
mat4x4_from_vec3_mul_outer(T, u, u);
|
mat4x4_from_vec3_mul_outer(T, u, u);
|
||||||
|
|
||||||
S[1][2] = u[0];
|
mat4x4 S = {
|
||||||
S[2][1] = -u[0];
|
{ 0, u[2], -u[1], 0},
|
||||||
S[2][0] = u[1];
|
{-u[2], 0, u[0], 0},
|
||||||
S[0][2] = -u[1];
|
{ u[1], -u[0], 0, 0},
|
||||||
S[0][1] = u[2];
|
{ 0, 0, 0, 0}
|
||||||
S[1][0] = -u[2];
|
};
|
||||||
|
|
||||||
mat4x4_scale(S, S, s);
|
mat4x4_scale(S, S, s);
|
||||||
|
|
||||||
|
mat4x4 C;
|
||||||
mat4x4_identity(C);
|
mat4x4_identity(C);
|
||||||
mat4x4_sub(C, C, T);
|
mat4x4_sub(C, C, T);
|
||||||
|
|
||||||
@ -214,13 +234,13 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
|
|||||||
mat4x4_add(T, T, C);
|
mat4x4_add(T, T, C);
|
||||||
mat4x4_add(T, T, S);
|
mat4x4_add(T, T, S);
|
||||||
|
|
||||||
T[3][3] = 1.;
|
T[3][3] = 1.;
|
||||||
mat4x4_mul(R, M, T);
|
mat4x4_mul(R, M, T);
|
||||||
} else {
|
} else {
|
||||||
mat4x4_dup(R, M);
|
mat4x4_dup(R, M);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
|
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
|
||||||
{
|
{
|
||||||
float s = sinf(angle);
|
float s = sinf(angle);
|
||||||
float c = cosf(angle);
|
float c = cosf(angle);
|
||||||
@ -232,19 +252,19 @@ static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
|
|||||||
};
|
};
|
||||||
mat4x4_mul(Q, M, R);
|
mat4x4_mul(Q, M, R);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
|
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
|
||||||
{
|
{
|
||||||
float s = sinf(angle);
|
float s = sinf(angle);
|
||||||
float c = cosf(angle);
|
float c = cosf(angle);
|
||||||
mat4x4 R = {
|
mat4x4 R = {
|
||||||
{ c, 0.f, s, 0.f},
|
{ c, 0.f, -s, 0.f},
|
||||||
{ 0.f, 1.f, 0.f, 0.f},
|
{ 0.f, 1.f, 0.f, 0.f},
|
||||||
{ -s, 0.f, c, 0.f},
|
{ s, 0.f, c, 0.f},
|
||||||
{ 0.f, 0.f, 0.f, 1.f}
|
{ 0.f, 0.f, 0.f, 1.f}
|
||||||
};
|
};
|
||||||
mat4x4_mul(Q, M, R);
|
mat4x4_mul(Q, M, R);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
|
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
|
||||||
{
|
{
|
||||||
float s = sinf(angle);
|
float s = sinf(angle);
|
||||||
float c = cosf(angle);
|
float c = cosf(angle);
|
||||||
@ -256,9 +276,8 @@ static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
|
|||||||
};
|
};
|
||||||
mat4x4_mul(Q, M, R);
|
mat4x4_mul(Q, M, R);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 M)
|
||||||
{
|
{
|
||||||
float idet;
|
|
||||||
float s[6];
|
float s[6];
|
||||||
float c[6];
|
float c[6];
|
||||||
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
||||||
@ -274,10 +293,10 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
|||||||
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
|
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
|
||||||
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
|
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
|
||||||
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
||||||
|
|
||||||
/* Assumes it is invertible */
|
/* Assumes it is invertible */
|
||||||
idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
|
float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
|
||||||
|
|
||||||
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
|
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
|
||||||
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
|
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
|
||||||
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
|
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
|
||||||
@ -298,35 +317,34 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
|||||||
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
|
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
|
||||||
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
|
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
|
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
|
||||||
{
|
{
|
||||||
|
mat4x4_dup(R, M);
|
||||||
float s = 1.;
|
float s = 1.;
|
||||||
vec3 h;
|
vec3 h;
|
||||||
|
|
||||||
mat4x4_dup(R, M);
|
|
||||||
vec3_norm(R[2], R[2]);
|
vec3_norm(R[2], R[2]);
|
||||||
|
|
||||||
s = vec3_mul_inner(R[1], R[2]);
|
|
||||||
vec3_scale(h, R[2], s);
|
|
||||||
vec3_sub(R[1], R[1], h);
|
|
||||||
vec3_norm(R[2], R[2]);
|
|
||||||
|
|
||||||
s = vec3_mul_inner(R[1], R[2]);
|
s = vec3_mul_inner(R[1], R[2]);
|
||||||
vec3_scale(h, R[2], s);
|
vec3_scale(h, R[2], s);
|
||||||
vec3_sub(R[1], R[1], h);
|
vec3_sub(R[1], R[1], h);
|
||||||
vec3_norm(R[1], R[1]);
|
vec3_norm(R[1], R[1]);
|
||||||
|
|
||||||
|
s = vec3_mul_inner(R[0], R[2]);
|
||||||
|
vec3_scale(h, R[2], s);
|
||||||
|
vec3_sub(R[0], R[0], h);
|
||||||
|
|
||||||
s = vec3_mul_inner(R[0], R[1]);
|
s = vec3_mul_inner(R[0], R[1]);
|
||||||
vec3_scale(h, R[1], s);
|
vec3_scale(h, R[1], s);
|
||||||
vec3_sub(R[0], R[0], h);
|
vec3_sub(R[0], R[0], h);
|
||||||
vec3_norm(R[0], R[0]);
|
vec3_norm(R[0], R[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
||||||
{
|
{
|
||||||
M[0][0] = 2.f*n/(r-l);
|
M[0][0] = 2.f*n/(r-l);
|
||||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||||
|
|
||||||
M[1][1] = 2.f*n/(t-b);
|
M[1][1] = 2.f*n/(t-b);
|
||||||
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
||||||
|
|
||||||
@ -334,11 +352,11 @@ static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t,
|
|||||||
M[2][1] = (t+b)/(t-b);
|
M[2][1] = (t+b)/(t-b);
|
||||||
M[2][2] = -(f+n)/(f-n);
|
M[2][2] = -(f+n)/(f-n);
|
||||||
M[2][3] = -1.f;
|
M[2][3] = -1.f;
|
||||||
|
|
||||||
M[3][2] = -2.f*(f*n)/(f-n);
|
M[3][2] = -2.f*(f*n)/(f-n);
|
||||||
M[3][0] = M[3][1] = M[3][3] = 0.f;
|
M[3][0] = M[3][1] = M[3][3] = 0.f;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
||||||
{
|
{
|
||||||
M[0][0] = 2.f/(r-l);
|
M[0][0] = 2.f/(r-l);
|
||||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||||
@ -348,17 +366,17 @@ static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, fl
|
|||||||
|
|
||||||
M[2][2] = -2.f/(f-n);
|
M[2][2] = -2.f/(f-n);
|
||||||
M[2][0] = M[2][1] = M[2][3] = 0.f;
|
M[2][0] = M[2][1] = M[2][3] = 0.f;
|
||||||
|
|
||||||
M[3][0] = -(r+l)/(r-l);
|
M[3][0] = -(r+l)/(r-l);
|
||||||
M[3][1] = -(t+b)/(t-b);
|
M[3][1] = -(t+b)/(t-b);
|
||||||
M[3][2] = -(f+n)/(f-n);
|
M[3][2] = -(f+n)/(f-n);
|
||||||
M[3][3] = 1.f;
|
M[3][3] = 1.f;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
|
LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
|
||||||
{
|
{
|
||||||
/* NOTE: Degrees are an unhandy unit to work with.
|
/* NOTE: Degrees are an unhandy unit to work with.
|
||||||
* linmath.h uses radians for everything! */
|
* linmath.h uses radians for everything! */
|
||||||
float const a = 1.f / (float) tan(y_fov / 2.f);
|
float const a = 1.f / tanf(y_fov / 2.f);
|
||||||
|
|
||||||
m[0][0] = a / aspect;
|
m[0][0] = a / aspect;
|
||||||
m[0][1] = 0.f;
|
m[0][1] = 0.f;
|
||||||
@ -380,7 +398,7 @@ static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float
|
|||||||
m[3][2] = -((2.f * f * n) / (f - n));
|
m[3][2] = -((2.f * f * n) / (f - n));
|
||||||
m[3][3] = 0.f;
|
m[3][3] = 0.f;
|
||||||
}
|
}
|
||||||
static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
|
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
|
||||||
{
|
{
|
||||||
/* Adapted from Android's OpenGL Matrix.java. */
|
/* Adapted from Android's OpenGL Matrix.java. */
|
||||||
/* See the OpenGL GLUT documentation for gluLookAt for a description */
|
/* See the OpenGL GLUT documentation for gluLookAt for a description */
|
||||||
@ -389,15 +407,14 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
|
|||||||
/* TODO: The negation of of can be spared by swapping the order of
|
/* TODO: The negation of of can be spared by swapping the order of
|
||||||
* operands in the following cross products in the right way. */
|
* operands in the following cross products in the right way. */
|
||||||
vec3 f;
|
vec3 f;
|
||||||
|
vec3_sub(f, center, eye);
|
||||||
|
vec3_norm(f, f);
|
||||||
|
|
||||||
vec3 s;
|
vec3 s;
|
||||||
vec3 t;
|
|
||||||
|
|
||||||
vec3_sub(f, center, eye);
|
|
||||||
vec3_norm(f, f);
|
|
||||||
|
|
||||||
vec3_mul_cross(s, f, up);
|
vec3_mul_cross(s, f, up);
|
||||||
vec3_norm(s, s);
|
vec3_norm(s, s);
|
||||||
|
|
||||||
|
vec3 t;
|
||||||
vec3_mul_cross(t, s, f);
|
vec3_mul_cross(t, s, f);
|
||||||
|
|
||||||
m[0][0] = s[0];
|
m[0][0] = s[0];
|
||||||
@ -424,24 +441,24 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef float quat[4];
|
typedef float quat[4];
|
||||||
static inline void quat_identity(quat q)
|
LINMATH_H_FUNC void quat_identity(quat q)
|
||||||
{
|
{
|
||||||
q[0] = q[1] = q[2] = 0.f;
|
q[0] = q[1] = q[2] = 0.f;
|
||||||
q[3] = 1.f;
|
q[3] = 1.f;
|
||||||
}
|
}
|
||||||
static inline void quat_add(quat r, quat a, quat b)
|
LINMATH_H_FUNC void quat_add(quat r, quat a, quat b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
r[i] = a[i] + b[i];
|
r[i] = a[i] + b[i];
|
||||||
}
|
}
|
||||||
static inline void quat_sub(quat r, quat a, quat b)
|
LINMATH_H_FUNC void quat_sub(quat r, quat a, quat b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
r[i] = a[i] - b[i];
|
r[i] = a[i] - b[i];
|
||||||
}
|
}
|
||||||
static inline void quat_mul(quat r, quat p, quat q)
|
LINMATH_H_FUNC void quat_mul(quat r, quat p, quat q)
|
||||||
{
|
{
|
||||||
vec3 w;
|
vec3 w;
|
||||||
vec3_mul_cross(r, p, q);
|
vec3_mul_cross(r, p, q);
|
||||||
@ -451,13 +468,13 @@ static inline void quat_mul(quat r, quat p, quat q)
|
|||||||
vec3_add(r, r, w);
|
vec3_add(r, r, w);
|
||||||
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
|
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
|
||||||
}
|
}
|
||||||
static inline void quat_scale(quat r, quat v, float s)
|
LINMATH_H_FUNC void quat_scale(quat r, quat v, float s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<4; ++i)
|
for(i=0; i<4; ++i)
|
||||||
r[i] = v[i] * s;
|
r[i] = v[i] * s;
|
||||||
}
|
}
|
||||||
static inline float quat_inner_product(quat a, quat b)
|
LINMATH_H_FUNC float quat_inner_product(quat a, quat b)
|
||||||
{
|
{
|
||||||
float p = 0.f;
|
float p = 0.f;
|
||||||
int i;
|
int i;
|
||||||
@ -465,42 +482,43 @@ static inline float quat_inner_product(quat a, quat b)
|
|||||||
p += b[i]*a[i];
|
p += b[i]*a[i];
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
static inline void quat_conj(quat r, quat q)
|
LINMATH_H_FUNC void quat_conj(quat r, quat q)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<3; ++i)
|
for(i=0; i<3; ++i)
|
||||||
r[i] = -q[i];
|
r[i] = -q[i];
|
||||||
r[3] = q[3];
|
r[3] = q[3];
|
||||||
}
|
}
|
||||||
static inline void quat_rotate(quat r, float angle, vec3 axis) {
|
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 axis) {
|
||||||
int i;
|
|
||||||
vec3 v;
|
vec3 v;
|
||||||
vec3_scale(v, axis, sinf(angle / 2));
|
vec3_scale(v, axis, sinf(angle / 2));
|
||||||
|
int i;
|
||||||
for(i=0; i<3; ++i)
|
for(i=0; i<3; ++i)
|
||||||
r[i] = v[i];
|
r[i] = v[i];
|
||||||
r[3] = cosf(angle / 2);
|
r[3] = cosf(angle / 2);
|
||||||
}
|
}
|
||||||
#define quat_norm vec4_norm
|
#define quat_norm vec4_norm
|
||||||
static inline void quat_mul_vec3(vec3 r, quat q, vec3 v)
|
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat q, vec3 v)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Method by Fabian 'ryg' Giessen (of Farbrausch)
|
* Method by Fabian 'ryg' Giessen (of Farbrausch)
|
||||||
t = 2 * cross(q.xyz, v)
|
t = 2 * cross(q.xyz, v)
|
||||||
v' = v + q.w * t + cross(q.xyz, t)
|
v' = v + q.w * t + cross(q.xyz, t)
|
||||||
*/
|
*/
|
||||||
vec3 t = {q[0], q[1], q[2]};
|
vec3 t;
|
||||||
|
vec3 q_xyz = {q[0], q[1], q[2]};
|
||||||
vec3 u = {q[0], q[1], q[2]};
|
vec3 u = {q[0], q[1], q[2]};
|
||||||
|
|
||||||
vec3_mul_cross(t, t, v);
|
vec3_mul_cross(t, q_xyz, v);
|
||||||
vec3_scale(t, t, 2);
|
vec3_scale(t, t, 2);
|
||||||
|
|
||||||
vec3_mul_cross(u, u, t);
|
vec3_mul_cross(u, q_xyz, t);
|
||||||
vec3_scale(t, t, q[3]);
|
vec3_scale(t, t, q[3]);
|
||||||
|
|
||||||
vec3_add(r, v, t);
|
vec3_add(r, v, t);
|
||||||
vec3_add(r, r, u);
|
vec3_add(r, r, u);
|
||||||
}
|
}
|
||||||
static inline void mat4x4_from_quat(mat4x4 M, quat q)
|
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat q)
|
||||||
{
|
{
|
||||||
float a = q[3];
|
float a = q[3];
|
||||||
float b = q[0];
|
float b = q[0];
|
||||||
@ -510,7 +528,7 @@ static inline void mat4x4_from_quat(mat4x4 M, quat q)
|
|||||||
float b2 = b*b;
|
float b2 = b*b;
|
||||||
float c2 = c*c;
|
float c2 = c*c;
|
||||||
float d2 = d*d;
|
float d2 = d*d;
|
||||||
|
|
||||||
M[0][0] = a2 + b2 - c2 - d2;
|
M[0][0] = a2 + b2 - c2 - d2;
|
||||||
M[0][1] = 2.f*(b*c + a*d);
|
M[0][1] = 2.f*(b*c + a*d);
|
||||||
M[0][2] = 2.f*(b*d - a*c);
|
M[0][2] = 2.f*(b*d - a*c);
|
||||||
@ -530,7 +548,7 @@ static inline void mat4x4_from_quat(mat4x4 M, quat q)
|
|||||||
M[3][3] = 1.f;
|
M[3][3] = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q)
|
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q)
|
||||||
{
|
{
|
||||||
/* XXX: The way this is written only works for othogonal matrices. */
|
/* XXX: The way this is written only works for othogonal matrices. */
|
||||||
/* TODO: Take care of non-orthogonal case. */
|
/* TODO: Take care of non-orthogonal case. */
|
||||||
@ -541,7 +559,7 @@ static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q)
|
|||||||
R[3][0] = R[3][1] = R[3][2] = 0.f;
|
R[3][0] = R[3][1] = R[3][2] = 0.f;
|
||||||
R[3][3] = 1.f;
|
R[3][3] = 1.f;
|
||||||
}
|
}
|
||||||
static inline void quat_from_mat4x4(quat q, mat4x4 M)
|
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 M)
|
||||||
{
|
{
|
||||||
float r=0.f;
|
float r=0.f;
|
||||||
int i;
|
int i;
|
||||||
@ -557,7 +575,7 @@ static inline void quat_from_mat4x4(quat q, mat4x4 M)
|
|||||||
p = &perm[i];
|
p = &perm[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
r = (float) sqrt(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
|
r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
|
||||||
|
|
||||||
if(r < 1e-6) {
|
if(r < 1e-6) {
|
||||||
q[0] = 1.f;
|
q[0] = 1.f;
|
||||||
@ -571,4 +589,33 @@ static inline void quat_from_mat4x4(quat q, mat4x4 M)
|
|||||||
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
|
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s)
|
||||||
|
{
|
||||||
|
vec2 a; memcpy(a, _a, sizeof(a));
|
||||||
|
vec2 b; memcpy(b, _b, sizeof(b));
|
||||||
|
|
||||||
|
float z_a = 0.;
|
||||||
|
float z_b = 0.;
|
||||||
|
|
||||||
|
if(vec2_len(a) < 1.f) {
|
||||||
|
z_a = sqrtf(1.f - vec2_mul_inner(a, a));
|
||||||
|
} else {
|
||||||
|
vec2_norm(a, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vec2_len(b) < 1.f) {
|
||||||
|
z_b = sqrtf(1.f - vec2_mul_inner(b, b));
|
||||||
|
} else {
|
||||||
|
vec2_norm(b, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 a_ = {a[0], a[1], z_a};
|
||||||
|
vec3 b_ = {b[0], b[1], z_b};
|
||||||
|
|
||||||
|
vec3 c_;
|
||||||
|
vec3_mul_cross(c_, a_, b_);
|
||||||
|
|
||||||
|
float const angle = acosf(vec3_mul_inner(a_, b_)) * s;
|
||||||
|
mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
623
deps/nuklear.h
vendored
623
deps/nuklear.h
vendored
File diff suppressed because it is too large
Load Diff
8
deps/nuklear_glfw_gl2.h
vendored
8
deps/nuklear_glfw_gl2.h
vendored
@ -230,7 +230,7 @@ nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int m
|
|||||||
}
|
}
|
||||||
|
|
||||||
NK_INTERN void
|
NK_INTERN void
|
||||||
nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||||
{
|
{
|
||||||
const char *text = glfwGetClipboardString(glfw.win);
|
const char *text = glfwGetClipboardString(glfw.win);
|
||||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||||
@ -238,7 +238,7 @@ nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NK_INTERN void
|
NK_INTERN void
|
||||||
nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
|
nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||||
{
|
{
|
||||||
char *str = 0;
|
char *str = 0;
|
||||||
(void)usr;
|
(void)usr;
|
||||||
@ -261,8 +261,8 @@ nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
|
|||||||
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
||||||
}
|
}
|
||||||
nk_init_default(&glfw.ctx, 0);
|
nk_init_default(&glfw.ctx, 0);
|
||||||
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
|
glfw.ctx.clip.copy = nk_glfw3_clipboard_copy;
|
||||||
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
|
glfw.ctx.clip.paste = nk_glfw3_clipboard_paste;
|
||||||
glfw.ctx.clip.userdata = nk_handle_ptr(0);
|
glfw.ctx.clip.userdata = nk_handle_ptr(0);
|
||||||
nk_buffer_init_default(&glfw.ogl.cmds);
|
nk_buffer_init_default(&glfw.ogl.cmds);
|
||||||
|
|
||||||
|
2536
docs/Doxyfile.in
2536
docs/Doxyfile.in
File diff suppressed because it is too large
Load Diff
@ -25,39 +25,41 @@ GLFW.
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
This header declares the GLFW API and by default also includes the OpenGL header
|
This header defines all the constants and declares all the types and function
|
||||||
from your development environment. See below for how to control this.
|
prototypes of the GLFW API. By default it also includes the OpenGL header from
|
||||||
|
your development environment. See [option macros](@ref build_macros) below for
|
||||||
|
how to select OpenGL ES headers and more.
|
||||||
|
|
||||||
The GLFW header also defines any platform-specific macros needed by your OpenGL
|
The GLFW header also defines any platform-specific macros needed by your OpenGL
|
||||||
header, so it can be included without needing any window system headers.
|
header, so that it can be included without needing any window system headers.
|
||||||
|
|
||||||
For example, under Windows you are normally required to include `windows.h`
|
It does this only when needed, so if window system headers are included, the
|
||||||
before the OpenGL header, which would bring in the whole Win32 API. The GLFW
|
GLFW header does not try to redefine those symbols. The reverse is not true,
|
||||||
header duplicates the small number of macros needed.
|
i.e. `windows.h` cannot cope if any Win32 symbols have already been defined.
|
||||||
|
|
||||||
It does this only when needed, so if `windows.h` _is_ included, the GLFW header
|
|
||||||
does not try to redefine those symbols. The reverse is not true, i.e.
|
|
||||||
`windows.h` cannot cope if any of its symbols have already been defined.
|
|
||||||
|
|
||||||
In other words:
|
In other words:
|
||||||
|
|
||||||
- Do _not_ include the OpenGL headers yourself, as GLFW does this for you
|
- Use the GLFW header to include OpenGL or OpenGL ES headers portably
|
||||||
- Do _not_ include `windows.h` or other platform-specific headers unless you
|
- Do not include window system headers unless you will use those APIs directly
|
||||||
plan on using those APIs directly
|
- If you do need such headers, include them before the GLFW header
|
||||||
- If you _do_ need to include such headers, do it _before_ including
|
|
||||||
the GLFW header and it will handle this
|
|
||||||
|
|
||||||
If you are using an OpenGL extension loading library such as
|
If you are using an OpenGL extension loading library such as
|
||||||
[glad](https://github.com/Dav1dde/glad), the extension loader header should
|
[glad](https://github.com/Dav1dde/glad), the extension loader header should
|
||||||
be included _before_ the GLFW one.
|
be included before the GLFW one. GLFW attempts to detect any OpenGL or OpenGL
|
||||||
|
ES header or extension loader header included before it and will then disable
|
||||||
|
the inclusion of the default OpenGL header. Most extension loaders also define
|
||||||
|
macros that disable similar headers below it.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Alternatively the @ref GLFW_INCLUDE_NONE macro (described below) can be used to
|
Both of these mechanisms depend on the extension loader header defining a known
|
||||||
prevent the GLFW header from including the OpenGL header.
|
macro. If yours doesn't or you don't know which one your users will pick, the
|
||||||
|
@ref GLFW_INCLUDE_NONE macro will explicitly to prevent the GLFW header from
|
||||||
|
including the OpenGL header. This will also allow you to include the two
|
||||||
|
headers in any order.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
@ -105,7 +107,7 @@ __GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.1
|
|||||||
`GLES3/gl31.h` header instead of the regular OpenGL header.
|
`GLES3/gl31.h` header instead of the regular OpenGL header.
|
||||||
|
|
||||||
@anchor GLFW_INCLUDE_ES32
|
@anchor GLFW_INCLUDE_ES32
|
||||||
__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.2
|
__GLFW_INCLUDE_ES32__ makes the GLFW header include the OpenGL ES 3.2
|
||||||
`GLES3/gl32.h` header instead of the regular OpenGL header.
|
`GLES3/gl32.h` header instead of the regular OpenGL header.
|
||||||
|
|
||||||
@anchor GLFW_INCLUDE_NONE
|
@anchor GLFW_INCLUDE_NONE
|
||||||
@ -113,7 +115,8 @@ __GLFW_INCLUDE_NONE__ makes the GLFW header not include any OpenGL or OpenGL ES
|
|||||||
API header. This is useful in combination with an extension loading library.
|
API header. This is useful in combination with an extension loading library.
|
||||||
|
|
||||||
If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h`
|
If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h`
|
||||||
header (`OpenGL/gl.h` on macOS) is included.
|
header (`OpenGL/gl.h` on macOS) is included, unless GLFW detects the inclusion
|
||||||
|
guards of any OpenGL, OpenGL ES or extension loader header it knows about.
|
||||||
|
|
||||||
The following macros control the inclusion of additional API headers. Any
|
The following macros control the inclusion of additional API headers. Any
|
||||||
number of these may be defined simultaneously, and/or together with one of the
|
number of these may be defined simultaneously, and/or together with one of the
|
||||||
@ -209,12 +212,15 @@ find_package(OpenGL REQUIRED)
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
||||||
library and include directory paths. Link against this like above.
|
library and include directory paths. Link against this like any other library.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_link_libraries(myapp OpenGL::GL)
|
target_link_libraries(myapp OpenGL::GL)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
For a minimal example of a program and GLFW sources built with CMake, see the
|
||||||
|
[GLFW CMake Starter](https://github.com/juliettef/GLFW-CMake-starter) on GitHub.
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
||||||
|
|
||||||
@ -248,7 +254,7 @@ find_package(OpenGL REQUIRED)
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
||||||
library and include directory paths. Link against this like above.
|
library and include directory paths. Link against this like any other library.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_link_libraries(myapp OpenGL::GL)
|
target_link_libraries(myapp OpenGL::GL)
|
||||||
|
@ -163,10 +163,9 @@ multisampling anti-aliasing. Where this extension is unavailable, the
|
|||||||
GLFW uses the `GLX_ARB_create_context` extension when available, even when
|
GLFW uses the `GLX_ARB_create_context` extension when available, even when
|
||||||
creating OpenGL contexts of version 2.1 and below. Where this extension is
|
creating OpenGL contexts of version 2.1 and below. Where this extension is
|
||||||
unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
|
unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
|
||||||
hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint
|
hints will only be partially supported, the `GLFW_CONTEXT_DEBUG` hint will have
|
||||||
will have no effect, and setting the `GLFW_OPENGL_PROFILE` or
|
no effect, and setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT`
|
||||||
`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref
|
hints to `GLFW_TRUE` will cause @ref glfwCreateWindow to fail.
|
||||||
glfwCreateWindow to fail.
|
|
||||||
|
|
||||||
GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for
|
GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for
|
||||||
context profiles. Where this extension is unavailable, setting the
|
context profiles. Where this extension is unavailable, setting the
|
||||||
@ -206,10 +205,9 @@ unavailable, the `GLFW_SAMPLES` hint will have no effect.
|
|||||||
GLFW uses the `WGL_ARB_create_context` extension when available, even when
|
GLFW uses the `WGL_ARB_create_context` extension when available, even when
|
||||||
creating OpenGL contexts of version 2.1 and below. Where this extension is
|
creating OpenGL contexts of version 2.1 and below. Where this extension is
|
||||||
unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
|
unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
|
||||||
hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint
|
hints will only be partially supported, the `GLFW_CONTEXT_DEBUG` hint will have
|
||||||
will have no effect, and setting the `GLFW_OPENGL_PROFILE` or
|
no effect, and setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT`
|
||||||
`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref
|
hints to `GLFW_TRUE` will cause @ref glfwCreateWindow to fail.
|
||||||
glfwCreateWindow to fail.
|
|
||||||
|
|
||||||
GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for
|
GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for
|
||||||
context profiles. Where this extension is unavailable, setting the
|
context profiles. Where this extension is unavailable, setting the
|
||||||
@ -239,13 +237,13 @@ Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
|||||||
`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if
|
`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if
|
||||||
given version 3.0 or 3.1. The `GLFW_OPENGL_PROFILE` hint must be set to
|
given version 3.0 or 3.1. The `GLFW_OPENGL_PROFILE` hint must be set to
|
||||||
`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The
|
`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The
|
||||||
`GLFW_OPENGL_DEBUG_CONTEXT` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
|
`GLFW_CONTEXT_DEBUG` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
|
||||||
|
|
||||||
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
||||||
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
|
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
|
||||||
setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
|
setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
|
||||||
a non-default value will cause @ref glfwCreateWindow to fail and the
|
a non-default value will cause @ref glfwCreateWindow to fail and the
|
||||||
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
|
`GLFW_CONTEXT_DEBUG` hint is ignored.
|
||||||
|
|
||||||
|
|
||||||
@section compat_vulkan Vulkan loader and API
|
@section compat_vulkan Vulkan loader and API
|
||||||
|
@ -84,10 +84,6 @@ objects are recommended for rendering with such contexts.
|
|||||||
You should still [process events](@ref events) as long as you have at least one
|
You should still [process events](@ref events) as long as you have at least one
|
||||||
window, even if none of them are visible.
|
window, even if none of them are visible.
|
||||||
|
|
||||||
@macos The first time a window is created the menu bar is created. This is not
|
|
||||||
desirable for example when writing a command-line only application. Menu bar
|
|
||||||
creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection context_less Windows without contexts
|
@subsection context_less Windows without contexts
|
||||||
|
|
||||||
|
@ -550,10 +550,10 @@ int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
|
|||||||
Each joystick has zero or more axes, zero or more buttons, zero or more hats,
|
Each joystick has zero or more axes, zero or more buttons, zero or more hats,
|
||||||
a human-readable name, a user pointer and an SDL compatible GUID.
|
a human-readable name, a user pointer and an SDL compatible GUID.
|
||||||
|
|
||||||
When GLFW is initialized, detected joysticks are added to the beginning of
|
Detected joysticks are added to the beginning of the array. Once a joystick is
|
||||||
the array. Once a joystick is detected, it keeps its assigned ID until it is
|
detected, it keeps its assigned ID until it is disconnected or the library is
|
||||||
disconnected or the library is terminated, so as joysticks are connected and
|
terminated, so as joysticks are connected and disconnected, there may appear
|
||||||
disconnected, there may appear gaps in the IDs.
|
gaps in the IDs.
|
||||||
|
|
||||||
Joystick axis, button and hat state is updated when polled and does not require
|
Joystick axis, button and hat state is updated when polled and does not require
|
||||||
a window to be created or events to be processed. However, if you want joystick
|
a window to be created or events to be processed. However, if you want joystick
|
||||||
@ -648,7 +648,7 @@ const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Joystick names are not guaranteed to be unique. Two joysticks of the same model
|
Joystick names are not guaranteed to be unique. Two joysticks of the same model
|
||||||
and make may have the same name. Only the [joystick token](@ref joysticks) is
|
and make may have the same name. Only the [joystick ID](@ref joysticks) is
|
||||||
guaranteed to be unique, and only until that joystick is disconnected.
|
guaranteed to be unique, and only until that joystick is disconnected.
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ There are also guides for the other areas of GLFW.
|
|||||||
|
|
||||||
Before most GLFW functions may be called, the library must be initialized.
|
Before most GLFW functions may be called, the library must be initialized.
|
||||||
This initialization checks what features are available on the machine,
|
This initialization checks what features are available on the machine,
|
||||||
enumerates monitors and joysticks, initializes the timer and performs any
|
enumerates monitors, initializes the timer and performs any required
|
||||||
required platform-specific initialization.
|
platform-specific initialization.
|
||||||
|
|
||||||
Only the following functions may be called before the library has been
|
Only the following functions may be called before the library has been
|
||||||
successfully initialized, and only from the main thread.
|
successfully initialized, and only from the main thread.
|
||||||
@ -62,6 +62,11 @@ before the application exits. Modern systems are very good at freeing resources
|
|||||||
allocated by programs that exit, but GLFW sometimes has to change global system
|
allocated by programs that exit, but GLFW sometimes has to change global system
|
||||||
settings and these might not be restored without termination.
|
settings and these might not be restored without termination.
|
||||||
|
|
||||||
|
@macos When the library is initialized the main menu and dock icon are created.
|
||||||
|
These are not desirable for a command-line only program. The creation of the
|
||||||
|
main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init
|
||||||
|
hint.
|
||||||
|
|
||||||
|
|
||||||
@subsection init_hints Initialization hints
|
@subsection init_hints Initialization hints
|
||||||
|
|
||||||
@ -86,7 +91,22 @@ Setting these hints requires no platform specific headers or functions.
|
|||||||
@anchor GLFW_JOYSTICK_HAT_BUTTONS
|
@anchor GLFW_JOYSTICK_HAT_BUTTONS
|
||||||
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
|
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
|
||||||
buttons, for compatibility with earlier versions of GLFW that did not have @ref
|
buttons, for compatibility with earlier versions of GLFW that did not have @ref
|
||||||
glfwGetJoystickHats. Set this with @ref glfwInitHint.
|
glfwGetJoystickHats. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
|
|
||||||
|
@anchor GLFW_ANGLE_PLATFORM_TYPE_hint
|
||||||
|
__GLFW_ANGLE_PLATFORM_TYPE__ specifies the platform type (rendering backend) to
|
||||||
|
request when using OpenGL ES and EGL via
|
||||||
|
[ANGLE](https://chromium.googlesource.com/angle/angle/). If the requested
|
||||||
|
platform type is unavailable, ANGLE will use its default. Possible values are
|
||||||
|
one of `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`,
|
||||||
|
`GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`,
|
||||||
|
`GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` and
|
||||||
|
`GLFW_ANGLE_PLATFORM_TYPE_METAL`.
|
||||||
|
|
||||||
|
@par
|
||||||
|
The ANGLE platform type is specified via the `EGL_ANGLE_platform_angle`
|
||||||
|
extension. This extension is not used if this hint is
|
||||||
|
`GLFW_ANGLE_PLATFORM_TYPE_NONE`, which is the default value.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_osx macOS specific init hints
|
@subsubsection init_hints_osx macOS specific init hints
|
||||||
@ -94,21 +114,24 @@ glfwGetJoystickHats. Set this with @ref glfwInitHint.
|
|||||||
@anchor GLFW_COCOA_CHDIR_RESOURCES_hint
|
@anchor GLFW_COCOA_CHDIR_RESOURCES_hint
|
||||||
__GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to
|
__GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to
|
||||||
the application to the `Contents/Resources` subdirectory of the application's
|
the application to the `Contents/Resources` subdirectory of the application's
|
||||||
bundle, if present. Set this with @ref glfwInitHint.
|
bundle, if present. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is
|
||||||
|
ignored on other platforms.
|
||||||
|
|
||||||
@anchor GLFW_COCOA_MENUBAR_hint
|
@anchor GLFW_COCOA_MENUBAR_hint
|
||||||
__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar, either from
|
__GLFW_COCOA_MENUBAR__ specifies whether to create the menu bar and dock icon
|
||||||
a nib or manually, when the first window is created, which is when AppKit is
|
when GLFW is initialized. This applies whether the menu bar is created from
|
||||||
initialized. Set this with @ref glfwInitHint.
|
a nib or manually by GLFW. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
|
This is ignored on other platforms.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_values Supported and default values
|
@subsubsection init_hints_values Supported and default values
|
||||||
|
|
||||||
Initialization hint | Default value | Supported values
|
Initialization hint | Default value | Supported values
|
||||||
------------------------------- | ------------- | ----------------
|
------------------------------- | ------------------------------- | ----------------
|
||||||
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
@ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL`
|
||||||
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
|
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
|
|
||||||
|
|
||||||
@subsection intro_init_terminate Terminating GLFW
|
@subsection intro_init_terminate Terminating GLFW
|
||||||
|
@ -27,6 +27,23 @@ are still available.
|
|||||||
For more information see @ref cursor_standard.
|
For more information see @ref cursor_standard.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection mouse_passthrough_34 Mouse event passthrough
|
||||||
|
|
||||||
|
GLFW now provides the [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_hint)
|
||||||
|
window hint for making a window transparent to mouse input, lettings events pass
|
||||||
|
to whatever window is behind it. This can also be changed after window
|
||||||
|
creation with the matching [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib).
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection features_34_angle_backend Support for ANGLE rendering backend selection
|
||||||
|
|
||||||
|
GLFW now provides the
|
||||||
|
[GLFW_ANGLE_PLATFORM_TYPE](@ref GLFW_ANGLE_PLATFORM_TYPE_hint) init hint for
|
||||||
|
requesting a specific rendering backend when using
|
||||||
|
[ANGLE](https://chromium.googlesource.com/angle/angle/) to create OpenGL ES
|
||||||
|
contexts.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
|
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
|
||||||
|
|
||||||
GLFW now provides the
|
GLFW now provides the
|
||||||
@ -38,6 +55,21 @@ applications.
|
|||||||
|
|
||||||
@subsection caveats_34 Caveats for version 3.4
|
@subsection caveats_34 Caveats for version 3.4
|
||||||
|
|
||||||
|
@subsubsection joysticks_34 Joystick support is initialized on demand
|
||||||
|
|
||||||
|
The joystick part of GLFW is now initialized when first used, primarily to work
|
||||||
|
around faulty Windows drivers that cause DirectInput to take up to several
|
||||||
|
seconds to enumerate devices.
|
||||||
|
|
||||||
|
This change will usually not be observable. However, if your application waits
|
||||||
|
for events without having first called any joystick function or created any
|
||||||
|
visible windows, the wait may never unblock as GLFW may not yet have subscribed
|
||||||
|
to joystick related OS events.
|
||||||
|
|
||||||
|
To work around this, call any joystick function before waiting for events, for
|
||||||
|
example by setting a [joystick callback](@ref joystick_event).
|
||||||
|
|
||||||
|
|
||||||
@subsubsection standalone_34 Tests and examples are disabled when built as a sub-project
|
@subsubsection standalone_34 Tests and examples are disabled when built as a sub-project
|
||||||
|
|
||||||
GLFW now does not build the tests and examples when it is added as
|
GLFW now does not build the tests and examples when it is added as
|
||||||
@ -52,16 +84,37 @@ add_subdirectory(path/to/glfw)
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection initmenu_34 macOS main menu now created at initialization
|
||||||
|
|
||||||
|
GLFW now creates the main menu and completes the initialization of NSApplication
|
||||||
|
during initialization. Programs that do not want a main menu can disable it
|
||||||
|
with the [GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint) init hint.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection corevideo_34 CoreVideo dependency has been removed
|
@subsubsection corevideo_34 CoreVideo dependency has been removed
|
||||||
|
|
||||||
GLFW no longer depends on the CoreVideo framework on macOS and it no longer
|
GLFW no longer depends on the CoreVideo framework on macOS and it no longer
|
||||||
needs to be specified during compilation or linking.
|
needs to be specified during compilation or linking.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection caveat_fbtransparency_34 Framebuffer transparency requires DWM transparency
|
||||||
|
|
||||||
|
GLFW no longer supports framebuffer transparency enabled via @ref
|
||||||
|
GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off
|
||||||
|
(the Transparency setting under Personalization > Window Color).
|
||||||
|
|
||||||
|
|
||||||
@subsection deprecations_34 Deprecations in version 3.4
|
@subsection deprecations_34 Deprecations in version 3.4
|
||||||
|
|
||||||
@subsection removals_34 Removals in 3.4
|
@subsection removals_34 Removals in 3.4
|
||||||
|
|
||||||
|
@subsubsection wl_shell_34 Support for the wl_shell protocol has been removed
|
||||||
|
|
||||||
|
Support for the wl_shell protocol has been removed and GLFW now only supports
|
||||||
|
the XDG-Shell protocol. If your Wayland compositor does not support XDG-Shell
|
||||||
|
then GLFW will fail to initialize.
|
||||||
|
|
||||||
|
|
||||||
@subsection symbols_34 New symbols in version 3.4
|
@subsection symbols_34 New symbols in version 3.4
|
||||||
|
|
||||||
@subsubsection functions_34 New functions in version 3.4
|
@subsubsection functions_34 New functions in version 3.4
|
||||||
@ -74,9 +127,21 @@ needs to be specified during compilation or linking.
|
|||||||
- @ref GLFW_RESIZE_NWSE_CURSOR
|
- @ref GLFW_RESIZE_NWSE_CURSOR
|
||||||
- @ref GLFW_RESIZE_NESW_CURSOR
|
- @ref GLFW_RESIZE_NESW_CURSOR
|
||||||
- @ref GLFW_RESIZE_ALL_CURSOR
|
- @ref GLFW_RESIZE_ALL_CURSOR
|
||||||
|
- @ref GLFW_MOUSE_PASSTHROUGH
|
||||||
- @ref GLFW_NOT_ALLOWED_CURSOR
|
- @ref GLFW_NOT_ALLOWED_CURSOR
|
||||||
- @ref GLFW_CURSOR_UNAVAILABLE
|
- @ref GLFW_CURSOR_UNAVAILABLE
|
||||||
- @ref GLFW_WIN32_KEYBOARD_MENU
|
- @ref GLFW_WIN32_KEYBOARD_MENU
|
||||||
|
- @ref GLFW_CONTEXT_DEBUG
|
||||||
|
- @ref GLFW_FEATURE_UNAVAILABLE
|
||||||
|
- @ref GLFW_FEATURE_UNIMPLEMENTED
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_NONE
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGL
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGLES
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_D3D9
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_D3D11
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_VULKAN
|
||||||
|
- @ref GLFW_ANGLE_PLATFORM_TYPE_METAL
|
||||||
|
|
||||||
|
|
||||||
@section news_archive Release notes for earlier versions
|
@section news_archive Release notes for earlier versions
|
||||||
|
@ -18,43 +18,42 @@ behave differently in GLFW 3.
|
|||||||
|
|
||||||
@subsection quick_include Including the GLFW header
|
@subsection quick_include Including the GLFW header
|
||||||
|
|
||||||
In the source files of your application where you use OpenGL or GLFW, you need
|
In the source files of your application where you use GLFW, you need to include
|
||||||
to include the GLFW 3 header file.
|
its header file.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
This defines all the constants, types and function prototypes of the GLFW API.
|
This header provides all the constants, types and function prototypes of the
|
||||||
It also includes the OpenGL header from your development environment and
|
GLFW API.
|
||||||
defines all the constants and types necessary for it to work on your platform
|
|
||||||
without including any platform-specific headers.
|
|
||||||
|
|
||||||
In other words:
|
By default it also includes the OpenGL header from your development environment.
|
||||||
|
On some platforms this header only supports older versions of OpenGL. The most
|
||||||
|
extreme case is Windows, where it typically only supports OpenGL 1.2.
|
||||||
|
|
||||||
- Do _not_ include the OpenGL header yourself, as GLFW does this for you in
|
Most programs will instead use an
|
||||||
a platform-independent way
|
[extension loader library](@ref context_glext_auto) and include its header.
|
||||||
- Do _not_ include `windows.h` or other platform-specific headers unless
|
This example uses files generated by [glad](https://gen.glad.sh/). The GLFW
|
||||||
you plan on using those APIs yourself
|
header can detect most such headers if they are included first and will then not
|
||||||
- If you _do_ need to include such headers, include them _before_ the GLFW
|
include the one from your development environment.
|
||||||
header and it will detect this
|
|
||||||
|
|
||||||
On some platforms supported by GLFW the OpenGL header and link library only
|
|
||||||
expose older versions of OpenGL. The most extreme case is Windows, which only
|
|
||||||
exposes OpenGL 1.2. The easiest way to work around this is to use an
|
|
||||||
[extension loader library](@ref context_glext_auto).
|
|
||||||
|
|
||||||
If you are using such a library then you should include its header _before_ the
|
|
||||||
GLFW header. This lets it replace the OpenGL header included by GLFW without
|
|
||||||
conflicts. This example uses
|
|
||||||
[glad2](https://github.com/Dav1dde/glad), but the same rule applies to all such
|
|
||||||
libraries.
|
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
To make sure there will be no header conflicts, you can define @ref
|
||||||
|
GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the
|
||||||
|
development environment header. This also allows the two headers to be included
|
||||||
|
in any order.
|
||||||
|
|
||||||
|
@code
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glad/gl.h>
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@subsection quick_init_term Initializing and terminating GLFW
|
@subsection quick_init_term Initializing and terminating GLFW
|
||||||
|
|
||||||
@ -251,12 +250,16 @@ glViewport(0, 0, width, height);
|
|||||||
You can also set a framebuffer size callback using @ref
|
You can also set a framebuffer size callback using @ref
|
||||||
glfwSetFramebufferSizeCallback and be notified when the size changes.
|
glfwSetFramebufferSizeCallback and be notified when the size changes.
|
||||||
|
|
||||||
Actual rendering with OpenGL is outside the scope of this tutorial, but there
|
The details of how to render with OpenGL is outside the scope of this tutorial,
|
||||||
are [many](https://open.gl/) [excellent](https://learnopengl.com/)
|
but there are many excellent resources for learning modern OpenGL. Here are
|
||||||
[tutorial](http://openglbook.com/) [sites](http://ogldev.atspace.co.uk/) that
|
a few of them:
|
||||||
teach modern OpenGL. Some of them use GLFW to create the context and window
|
|
||||||
while others use GLUT or SDL, but remember that OpenGL itself always works the
|
- [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/)
|
||||||
same.
|
- [Learn OpenGL](https://learnopengl.com/)
|
||||||
|
- [Open.GL](https://open.gl/)
|
||||||
|
|
||||||
|
These all happen to use GLFW, but OpenGL itself works the same whatever API you
|
||||||
|
use to create the window and context.
|
||||||
|
|
||||||
|
|
||||||
@subsection quick_timer Reading the timer
|
@subsection quick_timer Reading the timer
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
@tableofcontents
|
@tableofcontents
|
||||||
|
|
||||||
This guide is intended to fill the gaps between the [Vulkan
|
This guide is intended to fill the gaps between the official [Vulkan
|
||||||
documentation](https://www.khronos.org/vulkan/) and the rest of the GLFW
|
resources](https://www.khronos.org/vulkan/) and the rest of the GLFW
|
||||||
documentation and is not a replacement for either. It assumes some familiarity
|
documentation and is not a replacement for either. It assumes some familiarity
|
||||||
with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to
|
with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to
|
||||||
the Vulkan documentation to explain the details of Vulkan functions.
|
the Vulkan documentation to explain the details of Vulkan functions.
|
||||||
@ -14,7 +14,12 @@ To develop for Vulkan you should download the [LunarG Vulkan
|
|||||||
SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link
|
SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link
|
||||||
libraries, they also provide the validation layers necessary for development.
|
libraries, they also provide the validation layers necessary for development.
|
||||||
|
|
||||||
For details on a specific function in this category, see the @ref vulkan. There
|
The [Vulkan Tutorial](https://vulkan-tutorial.com/) has more information on how
|
||||||
|
to use GLFW and Vulkan. The [Khronos Vulkan
|
||||||
|
Samples](https://github.com/KhronosGroup/Vulkan-Samples) also use GLFW, although
|
||||||
|
with a small framework in between.
|
||||||
|
|
||||||
|
For details on a specific Vulkan support function, see the @ref vulkan. There
|
||||||
are also guides for the other areas of the GLFW API.
|
are also guides for the other areas of the GLFW API.
|
||||||
|
|
||||||
- @ref intro_guide
|
- @ref intro_guide
|
||||||
|
@ -234,13 +234,6 @@ alpha channel will be used to combine the framebuffer with the background. This
|
|||||||
does not affect window decorations. Possible values are `GLFW_TRUE` and
|
does not affect window decorations. Possible values are `GLFW_TRUE` and
|
||||||
`GLFW_FALSE`.
|
`GLFW_FALSE`.
|
||||||
|
|
||||||
@par
|
|
||||||
@win32 GLFW sets a color key for the window to work around repainting issues
|
|
||||||
with a transparent framebuffer. The chosen color value is RGB 255,0,255
|
|
||||||
(magenta). This will make pixels with that exact color fully transparent
|
|
||||||
regardless of their alpha values. If this is a problem, make these pixels any
|
|
||||||
other color before buffer swap.
|
|
||||||
|
|
||||||
@anchor GLFW_FOCUS_ON_SHOW_hint
|
@anchor GLFW_FOCUS_ON_SHOW_hint
|
||||||
__GLFW_FOCUS_ON_SHOW__ specifies whether the window will be given input
|
__GLFW_FOCUS_ON_SHOW__ specifies whether the window will be given input
|
||||||
focus when @ref glfwShowWindow is called. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
focus when @ref glfwShowWindow is called. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
@ -255,6 +248,13 @@ This hint only has an effect on platforms where screen coordinates and pixels
|
|||||||
always map 1:1 such as Windows and X11. On platforms like macOS the resolution
|
always map 1:1 such as Windows and X11. On platforms like macOS the resolution
|
||||||
of the framebuffer is changed independently of the window size.
|
of the framebuffer is changed independently of the window size.
|
||||||
|
|
||||||
|
@anchor GLFW_MOUSE_PASSTHROUGH_hint
|
||||||
|
__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse
|
||||||
|
input, letting any mouse events pass through to whatever window is behind it.
|
||||||
|
This is only supported for undecorated windows. Decorated windows with this
|
||||||
|
enabled will behave differently between platforms. Possible values are
|
||||||
|
`GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_fb Framebuffer related hints
|
@subsubsection window_hints_fb Framebuffer related hints
|
||||||
|
|
||||||
@ -405,11 +405,16 @@ version is 3.0 or above. If OpenGL ES is requested, this hint is ignored.
|
|||||||
Forward-compatibility is described in detail in the
|
Forward-compatibility is described in detail in the
|
||||||
[OpenGL Reference Manual](https://www.opengl.org/registry/).
|
[OpenGL Reference Manual](https://www.opengl.org/registry/).
|
||||||
|
|
||||||
|
@anchor GLFW_CONTEXT_DEBUG_hint
|
||||||
@anchor GLFW_OPENGL_DEBUG_CONTEXT_hint
|
@anchor GLFW_OPENGL_DEBUG_CONTEXT_hint
|
||||||
__GLFW_OPENGL_DEBUG_CONTEXT__ specifies whether to create a debug OpenGL
|
__GLFW_CONTEXT_DEBUG__ specifies whether the context should be created in debug
|
||||||
context, which may have additional error and performance issue reporting
|
mode, which may provide additional error and diagnostic reporting functionality.
|
||||||
functionality. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If OpenGL ES
|
Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
is requested, this hint is ignored.
|
|
||||||
|
@par
|
||||||
|
Debug contexts for OpenGL and OpenGL ES are described in detail by the
|
||||||
|
[GL_KHR_debug](https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_debug.txt)
|
||||||
|
extension.
|
||||||
|
|
||||||
@anchor GLFW_OPENGL_PROFILE_hint
|
@anchor GLFW_OPENGL_PROFILE_hint
|
||||||
__GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context
|
__GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context
|
||||||
@ -518,6 +523,7 @@ GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GL
|
|||||||
GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
|
GLFW_MOUSE_PASSTHROUGH | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
@ -541,7 +547,7 @@ GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor ve
|
|||||||
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
|
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
|
||||||
GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`
|
GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`
|
||||||
GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_OPENGL_DEBUG_CONTEXT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_CONTEXT_DEBUG | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE`
|
GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE`
|
||||||
GLFW_WIN32_KEYBOARD_MENU | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_WIN32_KEYBOARD_MENU | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
@ -1218,7 +1224,11 @@ If the system does not support whole window transparency, this function always
|
|||||||
returns one.
|
returns one.
|
||||||
|
|
||||||
GLFW comes with a test program that lets you control whole window transparency
|
GLFW comes with a test program that lets you control whole window transparency
|
||||||
at run-time called `opacity`.
|
at run-time called `window`.
|
||||||
|
|
||||||
|
If you want to use either of these transparency methods to display a temporary
|
||||||
|
overlay like for example a notification, the @ref GLFW_FLOATING and @ref
|
||||||
|
GLFW_MOUSE_PASSTHROUGH window hints and attributes may be useful.
|
||||||
|
|
||||||
|
|
||||||
@subsection window_attribs Window attributes
|
@subsection window_attribs Window attributes
|
||||||
@ -1308,6 +1318,15 @@ focus when @ref glfwShowWindow is called. This can be set before creation
|
|||||||
with the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint or
|
with the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint or
|
||||||
after with @ref glfwSetWindowAttrib.
|
after with @ref glfwSetWindowAttrib.
|
||||||
|
|
||||||
|
@anchor GLFW_MOUSE_PASSTHROUGH_attrib
|
||||||
|
__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse
|
||||||
|
input, letting any mouse events pass through to whatever window is behind it.
|
||||||
|
This can be set before creation with the
|
||||||
|
[GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_hint) window hint or after
|
||||||
|
with @ref glfwSetWindowAttrib. This is only supported for undecorated windows.
|
||||||
|
Decorated windows with this enabled will behave differently between platforms.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_attribs_ctx Context related attributes
|
@subsubsection window_attribs_ctx Context related attributes
|
||||||
|
|
||||||
@anchor GLFW_CLIENT_API_attrib
|
@anchor GLFW_CLIENT_API_attrib
|
||||||
@ -1334,9 +1353,10 @@ of the GLFW header.
|
|||||||
__GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an
|
__GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an
|
||||||
OpenGL forward-compatible one, or `GLFW_FALSE` otherwise.
|
OpenGL forward-compatible one, or `GLFW_FALSE` otherwise.
|
||||||
|
|
||||||
|
@anchor GLFW_CONTEXT_DEBUG_attrib
|
||||||
@anchor GLFW_OPENGL_DEBUG_CONTEXT_attrib
|
@anchor GLFW_OPENGL_DEBUG_CONTEXT_attrib
|
||||||
__GLFW_OPENGL_DEBUG_CONTEXT__ is `GLFW_TRUE` if the window's context is an
|
__GLFW_CONTEXT_DEBUG__ is `GLFW_TRUE` if the window's context is in debug
|
||||||
OpenGL debug context, or `GLFW_FALSE` otherwise.
|
mode, or `GLFW_FALSE` otherwise.
|
||||||
|
|
||||||
@anchor GLFW_OPENGL_PROFILE_attrib
|
@anchor GLFW_OPENGL_PROFILE_attrib
|
||||||
__GLFW_OPENGL_PROFILE__ indicates the OpenGL profile used by the context. This
|
__GLFW_OPENGL_PROFILE__ indicates the OpenGL profile used by the context. This
|
||||||
|
@ -33,6 +33,7 @@ add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL})
|
|||||||
add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL})
|
add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL})
|
||||||
add_executable(triangle-opengl WIN32 MACOSX_BUNDLE triangle-opengl.c ${ICON} ${GLAD_GL})
|
add_executable(triangle-opengl WIN32 MACOSX_BUNDLE triangle-opengl.c ${ICON} ${GLAD_GL})
|
||||||
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
|
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
|
||||||
|
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL})
|
||||||
|
|
||||||
target_link_libraries(particles Threads::Threads)
|
target_link_libraries(particles Threads::Threads)
|
||||||
if (RT_LIBRARY)
|
if (RT_LIBRARY)
|
||||||
@ -40,7 +41,7 @@ if (RT_LIBRARY)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview
|
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview
|
||||||
triangle-opengl wave)
|
triangle-opengl wave windows)
|
||||||
set(CONSOLE_BINARIES offscreen)
|
set(CONSOLE_BINARIES offscreen)
|
||||||
|
|
||||||
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||||
@ -48,6 +49,7 @@ set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
|||||||
FOLDER "GLFW3/Examples")
|
FOLDER "GLFW3/Examples")
|
||||||
|
|
||||||
if (GLFW_USE_OSMESA)
|
if (GLFW_USE_OSMESA)
|
||||||
|
find_package(OSMesa REQUIRED)
|
||||||
target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA)
|
target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ if (APPLE)
|
|||||||
set_target_properties(triangle-opengl PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL Triangle")
|
set_target_properties(triangle-opengl PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL Triangle")
|
||||||
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
|
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
|
||||||
set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
|
set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
|
||||||
|
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
|
||||||
|
|
||||||
set_source_files_properties(glfw.icns PROPERTIES
|
set_source_files_properties(glfw.icns PROPERTIES
|
||||||
MACOSX_PACKAGE_LOCATION "Resources")
|
MACOSX_PACKAGE_LOCATION "Resources")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// Simple multi-window test
|
// Simple multi-window example
|
||||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||||
//
|
//
|
||||||
// This software is provided 'as-is', without any express or implied
|
// This software is provided 'as-is', without any express or implied
|
||||||
@ -22,10 +22,6 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
//
|
|
||||||
// This test creates four windows and clears each in a different color
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
@ -34,109 +30,60 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static GLFWwindow* windows[4];
|
|
||||||
static const char* titles[] =
|
|
||||||
{
|
|
||||||
"Red",
|
|
||||||
"Green",
|
|
||||||
"Blue",
|
|
||||||
"Yellow"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct
|
|
||||||
{
|
|
||||||
float r, g, b;
|
|
||||||
} colors[] =
|
|
||||||
{
|
|
||||||
{ 0.95f, 0.32f, 0.11f },
|
|
||||||
{ 0.50f, 0.80f, 0.16f },
|
|
||||||
{ 0.f, 0.68f, 0.94f },
|
|
||||||
{ 0.98f, 0.74f, 0.04f }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void error_callback(int error, const char* description)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: %s\n", description);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void arrange_windows(void)
|
|
||||||
{
|
|
||||||
int xbase, ybase;
|
|
||||||
glfwGetWindowPos(windows[0], &xbase, &ybase);
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
int left, top, right, bottom;
|
|
||||||
glfwGetWindowFrameSize(windows[i], &left, &top, &right, &bottom);
|
|
||||||
glfwSetWindowPos(windows[i],
|
|
||||||
xbase + (i & 1) * (200 + left + right),
|
|
||||||
ybase + (i >> 1) * (200 + top + bottom));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
||||||
{
|
|
||||||
if (action != GLFW_PRESS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (key)
|
|
||||||
{
|
|
||||||
case GLFW_KEY_SPACE:
|
|
||||||
{
|
|
||||||
int xpos, ypos;
|
|
||||||
glfwGetWindowPos(window, &xpos, &ypos);
|
|
||||||
glfwSetWindowPos(window, xpos, ypos);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case GLFW_KEY_ESCAPE:
|
|
||||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_KEY_D:
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
const int decorated = glfwGetWindowAttrib(windows[i], GLFW_DECORATED);
|
|
||||||
glfwSetWindowAttrib(windows[i], GLFW_DECORATED, !decorated);
|
|
||||||
}
|
|
||||||
|
|
||||||
arrange_windows();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
glfwSetErrorCallback(error_callback);
|
int xpos, ypos, height;
|
||||||
|
const char* description;
|
||||||
|
GLFWwindow* windows[4];
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
|
{
|
||||||
|
glfwGetError(&description);
|
||||||
|
printf("Error: %s\n", description);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
|
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
|
||||||
|
|
||||||
|
glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &xpos, &ypos, NULL, &height);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
const int size = height / 5;
|
||||||
|
const struct
|
||||||
|
{
|
||||||
|
float r, g, b;
|
||||||
|
} colors[] =
|
||||||
|
{
|
||||||
|
{ 0.95f, 0.32f, 0.11f },
|
||||||
|
{ 0.50f, 0.80f, 0.16f },
|
||||||
|
{ 0.f, 0.68f, 0.94f },
|
||||||
|
{ 0.98f, 0.74f, 0.04f }
|
||||||
|
};
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
||||||
|
|
||||||
windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL);
|
windows[i] = glfwCreateWindow(size, size, "Multi-Window Example", NULL, NULL);
|
||||||
if (!windows[i])
|
if (!windows[i])
|
||||||
{
|
{
|
||||||
|
glfwGetError(&description);
|
||||||
|
printf("Error: %s\n", description);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSetKeyCallback(windows[i], key_callback);
|
glfwSetWindowPos(windows[i],
|
||||||
|
xpos + size * (1 + (i & 1)),
|
||||||
|
ypos + size * (1 + (i >> 1)));
|
||||||
|
glfwSetInputMode(windows[i], GLFW_STICKY_KEYS, GLFW_TRUE);
|
||||||
|
|
||||||
glfwMakeContextCurrent(windows[i]);
|
glfwMakeContextCurrent(windows[i]);
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f);
|
glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
arrange_windows();
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
glfwShowWindow(windows[i]);
|
glfwShowWindow(windows[i]);
|
||||||
|
|
||||||
@ -148,7 +95,8 @@ int main(int argc, char** argv)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glfwSwapBuffers(windows[i]);
|
glfwSwapBuffers(windows[i]);
|
||||||
|
|
||||||
if (glfwWindowShouldClose(windows[i]))
|
if (glfwWindowShouldClose(windows[i]) ||
|
||||||
|
glfwGetKey(windows[i], GLFW_KEY_ESCAPE))
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
@ -52,7 +52,7 @@ extern "C" {
|
|||||||
* This is the reference documentation for OpenGL and OpenGL ES context related
|
* This is the reference documentation for OpenGL and OpenGL ES context related
|
||||||
* functions. For more task-oriented information, see the @ref context_guide.
|
* functions. For more task-oriented information, see the @ref context_guide.
|
||||||
*/
|
*/
|
||||||
/*! @defgroup vulkan Vulkan reference
|
/*! @defgroup vulkan Vulkan support reference
|
||||||
* @brief Functions and types related to Vulkan.
|
* @brief Functions and types related to Vulkan.
|
||||||
*
|
*
|
||||||
* This is the reference documentation for Vulkan related functions and types.
|
* This is the reference documentation for Vulkan related functions and types.
|
||||||
@ -193,7 +193,38 @@ extern "C" {
|
|||||||
|
|
||||||
#endif /*__APPLE__*/
|
#endif /*__APPLE__*/
|
||||||
|
|
||||||
#elif !defined(GLFW_INCLUDE_NONE)
|
#elif defined(GLFW_INCLUDE_GLU)
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
|
||||||
|
#if defined(GLFW_INCLUDE_GLU)
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /*__APPLE__*/
|
||||||
|
|
||||||
|
#if defined(GLFW_INCLUDE_GLU)
|
||||||
|
#include <GL/glu.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__APPLE__*/
|
||||||
|
|
||||||
|
#elif !defined(GLFW_INCLUDE_NONE) && \
|
||||||
|
!defined(__gl_h_) && \
|
||||||
|
!defined(__gles1_gl_h_) && \
|
||||||
|
!defined(__gles2_gl2_h_) && \
|
||||||
|
!defined(__gles2_gl3_h_) && \
|
||||||
|
!defined(__gles2_gl31_h_) && \
|
||||||
|
!defined(__gles2_gl32_h_) && \
|
||||||
|
!defined(__gl_glcorearb_h_) && \
|
||||||
|
!defined(__gl2_h_) /*legacy*/ && \
|
||||||
|
!defined(__gl3_h_) /*legacy*/ && \
|
||||||
|
!defined(__gl31_h_) /*legacy*/ && \
|
||||||
|
!defined(__gl32_h_) /*legacy*/ && \
|
||||||
|
!defined(__glcorearb_h_) /*legacy*/ && \
|
||||||
|
!defined(__GL_H__) /*non-standard*/ && \
|
||||||
|
!defined(__gltypes_h_) /*non-standard*/ && \
|
||||||
|
!defined(__glee_h_) /*non-standard*/
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
|
||||||
@ -201,9 +232,6 @@ extern "C" {
|
|||||||
#define GL_GLEXT_LEGACY
|
#define GL_GLEXT_LEGACY
|
||||||
#endif
|
#endif
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
#if defined(GLFW_INCLUDE_GLU)
|
|
||||||
#include <OpenGL/glu.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /*__APPLE__*/
|
#else /*__APPLE__*/
|
||||||
|
|
||||||
@ -211,9 +239,6 @@ extern "C" {
|
|||||||
#if defined(GLFW_INCLUDE_GLEXT)
|
#if defined(GLFW_INCLUDE_GLEXT)
|
||||||
#include <GL/glext.h>
|
#include <GL/glext.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(GLFW_INCLUDE_GLU)
|
|
||||||
#include <GL/glu.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*__APPLE__*/
|
#endif /*__APPLE__*/
|
||||||
|
|
||||||
@ -768,6 +793,33 @@ extern "C" {
|
|||||||
* [custom cursor](@ref cursor_custom).
|
* [custom cursor](@ref cursor_custom).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
|
#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
|
||||||
|
/*! @brief The requested feature is not provided by the platform.
|
||||||
|
*
|
||||||
|
* The requested feature is not provided by the platform, so GLFW is unable to
|
||||||
|
* implement it. The documentation for each function notes if it could emit
|
||||||
|
* this error.
|
||||||
|
*
|
||||||
|
* @analysis Platform or platform version limitation. The error can be ignored
|
||||||
|
* unless the feature is critical to the application.
|
||||||
|
*
|
||||||
|
* @par
|
||||||
|
* A function call that emits this error has no effect other than the error and
|
||||||
|
* updating any existing out parameters.
|
||||||
|
*/
|
||||||
|
#define GLFW_FEATURE_UNAVAILABLE 0x0001000C
|
||||||
|
/*! @brief The requested feature is not implemented for the platform.
|
||||||
|
*
|
||||||
|
* The requested feature has not yet been implemented in GLFW for this platform.
|
||||||
|
*
|
||||||
|
* @analysis An incomplete implementation of GLFW for this platform, hopefully
|
||||||
|
* fixed in a future release. The error can be ignored unless the feature is
|
||||||
|
* critical to the application.
|
||||||
|
*
|
||||||
|
* @par
|
||||||
|
* A function call that emits this error has no effect other than the error and
|
||||||
|
* updating any existing out parameters.
|
||||||
|
*/
|
||||||
|
#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! @addtogroup window
|
/*! @addtogroup window
|
||||||
@ -843,6 +895,13 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define GLFW_FOCUS_ON_SHOW 0x0002000C
|
#define GLFW_FOCUS_ON_SHOW 0x0002000C
|
||||||
|
|
||||||
|
/*! @brief Mouse input transparency window hint and attribute
|
||||||
|
*
|
||||||
|
* Mouse input transparency [window hint](@ref GLFW_MOUSE_PASSTHROUGH_hint) or
|
||||||
|
* [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib).
|
||||||
|
*/
|
||||||
|
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
|
||||||
|
|
||||||
/*! @brief Framebuffer bit depth hint.
|
/*! @brief Framebuffer bit depth hint.
|
||||||
*
|
*
|
||||||
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
|
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
|
||||||
@ -960,12 +1019,17 @@ extern "C" {
|
|||||||
* and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib).
|
* and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
|
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
|
||||||
/*! @brief OpenGL debug context hint and attribute.
|
/*! @brief Debug mode context hint and attribute.
|
||||||
*
|
*
|
||||||
* OpenGL debug context [hint](@ref GLFW_OPENGL_DEBUG_CONTEXT_hint) and
|
* Debug mode context [hint](@ref GLFW_CONTEXT_DEBUG_hint) and
|
||||||
* [attribute](@ref GLFW_OPENGL_DEBUG_CONTEXT_attrib).
|
* [attribute](@ref GLFW_CONTEXT_DEBUG_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
|
#define GLFW_CONTEXT_DEBUG 0x00022007
|
||||||
|
/*! @brief Legacy name for compatibility.
|
||||||
|
*
|
||||||
|
* This is an alias for compatibility with earlier versions.
|
||||||
|
*/
|
||||||
|
#define GLFW_OPENGL_DEBUG_CONTEXT GLFW_CONTEXT_DEBUG
|
||||||
/*! @brief OpenGL profile hint and attribute.
|
/*! @brief OpenGL profile hint and attribute.
|
||||||
*
|
*
|
||||||
* OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and
|
* OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and
|
||||||
@ -1047,6 +1111,14 @@ extern "C" {
|
|||||||
#define GLFW_EGL_CONTEXT_API 0x00036002
|
#define GLFW_EGL_CONTEXT_API 0x00036002
|
||||||
#define GLFW_OSMESA_CONTEXT_API 0x00036003
|
#define GLFW_OSMESA_CONTEXT_API 0x00036003
|
||||||
|
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
|
||||||
|
|
||||||
/*! @defgroup shapes Standard cursor shapes
|
/*! @defgroup shapes Standard cursor shapes
|
||||||
* @brief Standard system cursor shapes.
|
* @brief Standard system cursor shapes.
|
||||||
*
|
*
|
||||||
@ -1163,6 +1235,11 @@ extern "C" {
|
|||||||
* Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS).
|
* Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS).
|
||||||
*/
|
*/
|
||||||
#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
|
#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
|
||||||
|
/*! @brief ANGLE rendering backend init hint.
|
||||||
|
*
|
||||||
|
* ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint).
|
||||||
|
*/
|
||||||
|
#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002
|
||||||
/*! @brief macOS specific init hint.
|
/*! @brief macOS specific init hint.
|
||||||
*
|
*
|
||||||
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
|
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
|
||||||
@ -1831,6 +1908,14 @@ typedef struct GLFWgamepadstate
|
|||||||
* bundle, if present. This can be disabled with the @ref
|
* bundle, if present. This can be disabled with the @ref
|
||||||
* GLFW_COCOA_CHDIR_RESOURCES init hint.
|
* GLFW_COCOA_CHDIR_RESOURCES init hint.
|
||||||
*
|
*
|
||||||
|
* @remark @macos This function will create the main menu and dock icon for the
|
||||||
|
* application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to
|
||||||
|
* contain a menu bar. Otherwise a minimal menu bar is created manually with
|
||||||
|
* common commands like Hide, Quit and About. The About entry opens a minimal
|
||||||
|
* about dialog with information from the application's bundle. The menu bar
|
||||||
|
* and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init
|
||||||
|
* hint.
|
||||||
|
*
|
||||||
* @remark @x11 This function will set the `LC_CTYPE` category of the
|
* @remark @x11 This function will set the `LC_CTYPE` category of the
|
||||||
* application locale according to the current environment if that category is
|
* application locale according to the current environment if that category is
|
||||||
* still "C". This is because the "C" locale breaks Unicode text input.
|
* still "C". This is because the "C" locale breaks Unicode text input.
|
||||||
@ -1858,6 +1943,8 @@ GLFWAPI int glfwInit(void);
|
|||||||
* call this function, as it is called by @ref glfwInit before it returns
|
* call this function, as it is called by @ref glfwInit before it returns
|
||||||
* failure.
|
* failure.
|
||||||
*
|
*
|
||||||
|
* This function has no effect if GLFW is not initialized.
|
||||||
|
*
|
||||||
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
|
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
|
||||||
*
|
*
|
||||||
* @remark This function may be called before @ref glfwInit.
|
* @remark This function may be called before @ref glfwInit.
|
||||||
@ -2674,13 +2761,6 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
|||||||
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
|
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
|
||||||
* in the Mac Developer Library.
|
* in the Mac Developer Library.
|
||||||
*
|
*
|
||||||
* @remark @macos The first time a window is created the menu bar is created.
|
|
||||||
* If GLFW finds a `MainMenu.nib` it is loaded and assumed to contain a menu
|
|
||||||
* bar. Otherwise a minimal menu bar is created manually with common commands
|
|
||||||
* like Hide, Quit and About. The About entry opens a minimal about dialog
|
|
||||||
* with information from the application's bundle. Menu bar creation can be
|
|
||||||
* disabled entirely with the @ref GLFW_COCOA_MENUBAR init hint.
|
|
||||||
*
|
|
||||||
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
|
* @remark @macos On OS X 10.10 and later the window frame will not be rendered
|
||||||
* at full resolution on Retina displays unless the
|
* at full resolution on Retina displays unless the
|
||||||
* [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
|
* [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
|
||||||
@ -2853,21 +2933,21 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
|
|||||||
* @param[in] images The images to create the icon from. This is ignored if
|
* @param[in] images The images to create the icon from. This is ignored if
|
||||||
* count is zero.
|
* count is zero.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||||
*
|
*
|
||||||
* @pointer_lifetime The specified image data is copied before this function
|
* @pointer_lifetime The specified image data is copied before this function
|
||||||
* returns.
|
* returns.
|
||||||
*
|
*
|
||||||
* @remark @macos The GLFW window has no icon, as it is not a document
|
* @remark @macos Regular windows do not have icons on macOS. This function
|
||||||
* window, so this function does nothing. The dock icon will be the same as
|
* will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as
|
||||||
* the application bundle's icon. For more information on bundles, see the
|
* the application bundle's icon. For more information on bundles, see the
|
||||||
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
|
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
|
||||||
* in the Mac Developer Library.
|
* in the Mac Developer Library.
|
||||||
*
|
*
|
||||||
* @remark @wayland There is no existing protocol to change an icon, the
|
* @remark @wayland There is no existing protocol to change an icon, the
|
||||||
* window will thus inherit the one defined in the application's desktop file.
|
* window will thus inherit the one defined in the application's desktop file.
|
||||||
* This function always emits @ref GLFW_PLATFORM_ERROR.
|
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
@ -2893,12 +2973,12 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
|
|||||||
* @param[out] ypos Where to store the y-coordinate of the upper-left corner of
|
* @param[out] ypos Where to store the y-coordinate of the upper-left corner of
|
||||||
* the content area, or `NULL`.
|
* the content area, or `NULL`.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||||
*
|
*
|
||||||
* @remark @wayland There is no way for an application to retrieve the global
|
* @remark @wayland There is no way for an application to retrieve the global
|
||||||
* position of its windows, this function will always emit @ref
|
* position of its windows. This function will emit @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_FEATURE_UNAVAILABLE.
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
@ -2927,12 +3007,12 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
|||||||
* @param[in] xpos The x-coordinate of the upper-left corner of the content area.
|
* @param[in] xpos The x-coordinate of the upper-left corner of the content area.
|
||||||
* @param[in] ypos The y-coordinate of the upper-left corner of the content area.
|
* @param[in] ypos The y-coordinate of the upper-left corner of the content area.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||||
*
|
*
|
||||||
* @remark @wayland There is no way for an application to set the global
|
* @remark @wayland There is no way for an application to set the global
|
||||||
* position of its windows, this function will always emit @ref
|
* position of its windows. This function will emit @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_FEATURE_UNAVAILABLE.
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
@ -3244,8 +3324,11 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
|
|||||||
* @param[in] window The window to set the opacity for.
|
* @param[in] window The window to set the opacity for.
|
||||||
* @param[in] opacity The desired opacity of the specified window.
|
* @param[in] opacity The desired opacity of the specified window.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||||
|
*
|
||||||
|
* @remark @wayland There is no way to set an opacity factor for a window.
|
||||||
|
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
@ -3412,11 +3495,11 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
|
|||||||
*
|
*
|
||||||
* @param[in] window The window to give input focus.
|
* @param[in] window The window to give input focus.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||||
*
|
*
|
||||||
* @remark @wayland It is not possible for an application to bring its windows
|
* @remark @wayland It is not possible for an application to set the input
|
||||||
* to front, this function will always emit @ref GLFW_PLATFORM_ERROR.
|
* focus. This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
@ -3580,6 +3663,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
|
|||||||
* [GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
|
* [GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
|
||||||
* [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
|
* [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
|
||||||
* [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib).
|
* [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib).
|
||||||
|
* [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_attrib)
|
||||||
*
|
*
|
||||||
* Some of these attributes are ignored for full screen windows. The new
|
* Some of these attributes are ignored for full screen windows. The new
|
||||||
* value will take effect if the window is later made windowed.
|
* value will take effect if the window is later made windowed.
|
||||||
@ -4168,7 +4252,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
* If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE`
|
* If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE`
|
||||||
* to enable raw (unscaled and unaccelerated) mouse motion when the cursor is
|
* to enable raw (unscaled and unaccelerated) mouse motion when the cursor is
|
||||||
* disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported,
|
* disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported,
|
||||||
* attempting to set this will emit @ref GLFW_PLATFORM_ERROR. Call @ref
|
* attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref
|
||||||
* glfwRawMouseMotionSupported to check for support.
|
* glfwRawMouseMotionSupported to check for support.
|
||||||
*
|
*
|
||||||
* @param[in] window The window whose input mode to set.
|
* @param[in] window The window whose input mode to set.
|
||||||
@ -4178,7 +4262,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
* @param[in] value The new value of the specified input mode.
|
* @param[in] value The new value of the specified input mode.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
* GLFW_INVALID_ENUM, @ref GLFW_PLATFORM_ERROR and @ref
|
||||||
|
* GLFW_FEATURE_UNAVAILABLE (see above).
|
||||||
*
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
|
@ -100,8 +100,8 @@ target_include_directories(glfw PRIVATE
|
|||||||
${glfw_INCLUDE_DIRS})
|
${glfw_INCLUDE_DIRS})
|
||||||
target_link_libraries(glfw PRIVATE Threads::Threads ${glfw_LIBRARIES})
|
target_link_libraries(glfw PRIVATE Threads::Threads ${glfw_LIBRARIES})
|
||||||
|
|
||||||
|
# Workaround for CMake not knowing about .m files before version 3.16
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# For some reason CMake didn't know about .m until version 3.16
|
|
||||||
set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
|
set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
|
||||||
cocoa_window.m nsgl_context.m PROPERTIES
|
cocoa_window.m nsgl_context.m PROPERTIES
|
||||||
LANGUAGE C)
|
LANGUAGE C)
|
||||||
@ -136,6 +136,35 @@ if (MINGW)
|
|||||||
target_compile_definitions(glfw PRIVATE UNICODE WINVER=0x0501)
|
target_compile_definitions(glfw PRIVATE UNICODE WINVER=0x0501)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Workaround for legacy MinGW not providing XInput and DirectInput
|
||||||
|
if (MINGW)
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||||
|
check_include_file(xinput.h XINPUT_H_FOUND)
|
||||||
|
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
|
||||||
|
target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Workaround for VS deprecating parts of the standard library
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Workaround for VS 2008 not shipping with stdint.h
|
||||||
|
if (MSVC90)
|
||||||
|
target_include_directories(glfw PUBLIC "${GLFW_SOURCE_DIR}/deps/vs2008")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for the DirectX 9 SDK as it is not included with VS 2008
|
||||||
|
if (MSVC90)
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||||
|
if (NOT DINPUT_H_FOUND)
|
||||||
|
message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
@ -159,16 +188,41 @@ if (BUILD_SHARED_LIBS)
|
|||||||
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
|
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (MINGW)
|
||||||
|
# Enable link-time exploit mitigation features enabled by default on MSVC
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
|
||||||
|
# Compatibility with data execution prevention (DEP)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
|
||||||
|
check_c_compiler_flag("" _GLFW_HAS_DEP)
|
||||||
|
if (_GLFW_HAS_DEP)
|
||||||
|
target_link_libraries(glfw PRIVATE "-Wl,--nxcompat")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compatibility with address space layout randomization (ASLR)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
|
||||||
|
check_c_compiler_flag("" _GLFW_HAS_ASLR)
|
||||||
|
if (_GLFW_HAS_ASLR)
|
||||||
|
target_link_libraries(glfw PRIVATE "-Wl,--dynamicbase")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compatibility with 64-bit address space layout randomization (ASLR)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
|
||||||
|
check_c_compiler_flag("" _GLFW_HAS_64ASLR)
|
||||||
|
if (_GLFW_HAS_64ASLR)
|
||||||
|
target_link_libraries(glfw PRIVATE "-Wl,--high-entropy-va")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Clear flags again to avoid breaking later tests
|
||||||
|
set(CMAKE_REQUIRED_FLAGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
# Hide symbols not explicitly tagged for export from the shared library
|
# Hide symbols not explicitly tagged for export from the shared library
|
||||||
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
|
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (GLFW_INSTALL)
|
if (GLFW_INSTALL)
|
||||||
install(TARGETS glfw
|
install(TARGETS glfw
|
||||||
EXPORT glfwTargets
|
EXPORT glfwTargets
|
||||||
|
@ -447,7 +447,6 @@ static GLFWbool initializeTIS(void)
|
|||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
_glfw.ns.finishedLaunching = GLFW_TRUE;
|
|
||||||
_glfwPlatformPostEmptyEvent();
|
_glfwPlatformPostEmptyEvent();
|
||||||
[NSApp stop:nil];
|
[NSApp stop:nil];
|
||||||
}
|
}
|
||||||
@ -503,9 +502,6 @@ int _glfwPlatformInit(void)
|
|||||||
toTarget:_glfw.ns.helper
|
toTarget:_glfw.ns.helper
|
||||||
withObject:nil];
|
withObject:nil];
|
||||||
|
|
||||||
if (NSApp)
|
|
||||||
_glfw.ns.finishedLaunching = GLFW_TRUE;
|
|
||||||
|
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
|
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
|
||||||
@ -555,9 +551,12 @@ int _glfwPlatformInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfwInitTimerNS();
|
_glfwInitTimerNS();
|
||||||
_glfwInitJoysticksNS();
|
|
||||||
|
|
||||||
_glfwPollMonitorsNS();
|
_glfwPollMonitorsNS();
|
||||||
|
|
||||||
|
if (![[NSRunningApplication currentApplication] isFinishedLaunching])
|
||||||
|
[NSApp run];
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
@ -605,7 +604,6 @@ void _glfwPlatformTerminate(void)
|
|||||||
free(_glfw.ns.clipboardString);
|
free(_glfw.ns.clipboardString);
|
||||||
|
|
||||||
_glfwTerminateNSGL();
|
_glfwTerminateNSGL();
|
||||||
_glfwTerminateJoysticksNS();
|
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,3 @@ typedef struct _GLFWjoystickNS
|
|||||||
CFMutableArrayRef hats;
|
CFMutableArrayRef hats;
|
||||||
} _GLFWjoystickNS;
|
} _GLFWjoystickNS;
|
||||||
|
|
||||||
|
|
||||||
void _glfwInitJoysticksNS(void);
|
|
||||||
void _glfwTerminateJoysticksNS(void);
|
|
||||||
|
|
||||||
|
@ -304,12 +304,10 @@ static void removeCallback(void* context,
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Initialize joystick interface
|
GLFWbool _glfwPlatformInitJoysticks(void)
|
||||||
//
|
|
||||||
void _glfwInitJoysticksNS(void)
|
|
||||||
{
|
{
|
||||||
CFMutableArrayRef matching;
|
CFMutableArrayRef matching;
|
||||||
const long usages[] =
|
const long usages[] =
|
||||||
@ -328,7 +326,7 @@ void _glfwInitJoysticksNS(void)
|
|||||||
if (!matching)
|
if (!matching)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
|
||||||
return;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||||
@ -383,26 +381,24 @@ void _glfwInitJoysticksNS(void)
|
|||||||
// Execute the run loop once in order to register any initially-attached
|
// Execute the run loop once in order to register any initially-attached
|
||||||
// joysticks
|
// joysticks
|
||||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
|
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close all opened joystick handles
|
void _glfwPlatformTerminateJoysticks(void)
|
||||||
//
|
|
||||||
void _glfwTerminateJoysticksNS(void)
|
|
||||||
{
|
{
|
||||||
int jid;
|
int jid;
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
closeJoystick(_glfw.joysticks + jid);
|
||||||
|
|
||||||
CFRelease(_glfw.ns.hidManager);
|
if (_glfw.ns.hidManager)
|
||||||
_glfw.ns.hidManager = NULL;
|
{
|
||||||
|
CFRelease(_glfw.ns.hidManager);
|
||||||
|
_glfw.ns.hidManager = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
{
|
{
|
||||||
if (mode & _GLFW_POLL_AXES)
|
if (mode & _GLFW_POLL_AXES)
|
||||||
|
@ -277,14 +277,20 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
|||||||
CFSTR("IOFBCurrentPixelCount"),
|
CFSTR("IOFBCurrentPixelCount"),
|
||||||
kCFAllocatorDefault,
|
kCFAllocatorDefault,
|
||||||
kNilOptions);
|
kNilOptions);
|
||||||
if (!clockRef || !countRef)
|
|
||||||
break;
|
|
||||||
|
|
||||||
uint32_t clock = 0, count = 0;
|
uint32_t clock = 0, count = 0;
|
||||||
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
|
|
||||||
CFNumberGetValue(countRef, kCFNumberIntType, &count);
|
if (clockRef)
|
||||||
CFRelease(clockRef);
|
{
|
||||||
CFRelease(countRef);
|
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
|
||||||
|
CFRelease(clockRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countRef)
|
||||||
|
{
|
||||||
|
CFNumberGetValue(countRef, kCFNumberIntType, &count);
|
||||||
|
CFRelease(countRef);
|
||||||
|
}
|
||||||
|
|
||||||
if (clock > 0 && count > 0)
|
if (clock > 0 && count > 0)
|
||||||
refreshRate = clock / (double) count;
|
refreshRate = clock / (double) count;
|
||||||
|
@ -85,16 +85,11 @@ typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMeta
|
|||||||
#include "posix_thread.h"
|
#include "posix_thread.h"
|
||||||
#include "cocoa_joystick.h"
|
#include "cocoa_joystick.h"
|
||||||
#include "nsgl_context.h"
|
#include "nsgl_context.h"
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.view)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
|
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
|
||||||
@ -121,6 +116,7 @@ typedef struct _GLFWwindowNS
|
|||||||
id layer;
|
id layer;
|
||||||
|
|
||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
|
GLFWbool occluded;
|
||||||
GLFWbool retina;
|
GLFWbool retina;
|
||||||
|
|
||||||
// Cached window properties to filter out duplicate events
|
// Cached window properties to filter out duplicate events
|
||||||
@ -141,7 +137,6 @@ typedef struct _GLFWlibraryNS
|
|||||||
{
|
{
|
||||||
CGEventSourceRef eventSource;
|
CGEventSourceRef eventSource;
|
||||||
id delegate;
|
id delegate;
|
||||||
GLFWbool finishedLaunching;
|
|
||||||
GLFWbool cursorHidden;
|
GLFWbool cursorHidden;
|
||||||
TISInputSourceRef inputSource;
|
TISInputSourceRef inputSource;
|
||||||
IOHIDManagerRef hidManager;
|
IOHIDManagerRef hidManager;
|
||||||
|
@ -322,6 +322,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)windowDidChangeOcclusionState:(NSNotification* )notification
|
||||||
|
{
|
||||||
|
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
|
||||||
|
window->ns.occluded = GLFW_FALSE;
|
||||||
|
else
|
||||||
|
window->ns.occluded = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@ -723,14 +731,24 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
else
|
else
|
||||||
characters = (NSString*) string;
|
characters = (NSString*) string;
|
||||||
|
|
||||||
const NSUInteger length = [characters length];
|
NSRange range = NSMakeRange(0, [characters length]);
|
||||||
for (NSUInteger i = 0; i < length; i++)
|
while (range.length)
|
||||||
{
|
{
|
||||||
const unichar codepoint = [characters characterAtIndex:i];
|
uint32_t codepoint = 0;
|
||||||
if ((codepoint & 0xff00) == 0xf700)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_glfwInputChar(window, codepoint, mods, plain);
|
if ([characters getBytes:&codepoint
|
||||||
|
maxLength:sizeof(codepoint)
|
||||||
|
usedLength:NULL
|
||||||
|
encoding:NSUTF32StringEncoding
|
||||||
|
options:0
|
||||||
|
range:range
|
||||||
|
remainingRange:&range])
|
||||||
|
{
|
||||||
|
if (codepoint >= 0xf700 && codepoint <= 0xf7ff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_glfwInputChar(window, codepoint, mods, plain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,9 +902,6 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (!_glfw.ns.finishedLaunching)
|
|
||||||
[NSApp run];
|
|
||||||
|
|
||||||
if (!createNativeWindow(window, wndconfig, fbconfig))
|
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
@ -901,6 +916,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
||||||
{
|
{
|
||||||
|
// EGL implementation on macOS use CALayer* EGLNativeWindowType so we
|
||||||
|
// need to get the layer for EGL window surface creation.
|
||||||
|
[window->ns.view setWantsLayer:YES];
|
||||||
|
window->ns.layer = [window->ns.view layer];
|
||||||
|
|
||||||
if (!_glfwInitEGL())
|
if (!_glfwInitEGL())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
@ -972,7 +992,8 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
|||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||||
int count, const GLFWimage* images)
|
int count, const GLFWimage* images)
|
||||||
{
|
{
|
||||||
// Regular windows do not have icons
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
|
"Cocoa: Regular windows do not have icons on macOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||||
@ -1350,6 +1371,13 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
[window->ns.object setIgnoresMouseEvents:enabled];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
@ -1366,6 +1394,8 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
|||||||
|
|
||||||
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
|
"Cocoa: Raw mouse motion not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
|
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
|
||||||
@ -1377,9 +1407,6 @@ void _glfwPlatformPollEvents(void)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (!_glfw.ns.finishedLaunching)
|
|
||||||
[NSApp run];
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
||||||
@ -1399,9 +1426,6 @@ void _glfwPlatformWaitEvents(void)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (!_glfw.ns.finishedLaunching)
|
|
||||||
[NSApp run];
|
|
||||||
|
|
||||||
// I wanted to pass NO to dequeue:, and rely on PollEvents to
|
// I wanted to pass NO to dequeue:, and rely on PollEvents to
|
||||||
// dequeue and send. For reasons not at all clear to me, passing
|
// dequeue and send. For reasons not at all clear to me, passing
|
||||||
// NO to dequeue: causes this method never to return.
|
// NO to dequeue: causes this method never to return.
|
||||||
@ -1420,9 +1444,6 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (!_glfw.ns.finishedLaunching)
|
|
||||||
[NSApp run];
|
|
||||||
|
|
||||||
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
|
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
|
||||||
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
||||||
untilDate:date
|
untilDate:date
|
||||||
@ -1440,9 +1461,6 @@ void _glfwPlatformPostEmptyEvent(void)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (!_glfw.ns.finishedLaunching)
|
|
||||||
[NSApp run];
|
|
||||||
|
|
||||||
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
|
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
|
||||||
location:NSMakePoint(0, 0)
|
location:NSMakePoint(0, 0)
|
||||||
modifierFlags:0
|
modifierFlags:0
|
||||||
@ -1720,6 +1738,47 @@ const char* _glfwPlatformGetClipboardString(void)
|
|||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle)
|
||||||
|
{
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_opengl)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_metal)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_METAL)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
{
|
||||||
|
*attribs = calloc(3, sizeof(EGLint));
|
||||||
|
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
|
||||||
|
(*attribs)[1] = type;
|
||||||
|
(*attribs)[2] = EGL_NONE;
|
||||||
|
return EGL_PLATFORM_ANGLE_ANGLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
|
||||||
|
{
|
||||||
|
return EGL_DEFAULT_DISPLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return window->ns.layer;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
|
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
|
||||||
|
@ -303,6 +303,8 @@ static void destroyContextEGL(_GLFWwindow* window)
|
|||||||
GLFWbool _glfwInitEGL(void)
|
GLFWbool _glfwInitEGL(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
EGLint* attribs = NULL;
|
||||||
|
const char* extensions;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_EGL_LIBRARY)
|
#if defined(_GLFW_EGL_LIBRARY)
|
||||||
@ -395,7 +397,51 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
|
extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||||
|
if (extensions && eglGetError() == EGL_SUCCESS)
|
||||||
|
_glfw.egl.EXT_client_extensions = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (_glfw.egl.EXT_client_extensions)
|
||||||
|
{
|
||||||
|
_glfw.egl.EXT_platform_base =
|
||||||
|
_glfwStringInExtensionString("EGL_EXT_platform_base", extensions);
|
||||||
|
_glfw.egl.EXT_platform_x11 =
|
||||||
|
_glfwStringInExtensionString("EGL_EXT_platform_x11", extensions);
|
||||||
|
_glfw.egl.EXT_platform_wayland =
|
||||||
|
_glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions);
|
||||||
|
_glfw.egl.ANGLE_platform_angle =
|
||||||
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions);
|
||||||
|
_glfw.egl.ANGLE_platform_angle_opengl =
|
||||||
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions);
|
||||||
|
_glfw.egl.ANGLE_platform_angle_d3d =
|
||||||
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions);
|
||||||
|
_glfw.egl.ANGLE_platform_angle_vulkan =
|
||||||
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
|
||||||
|
_glfw.egl.ANGLE_platform_angle_metal =
|
||||||
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.EXT_platform_base)
|
||||||
|
{
|
||||||
|
_glfw.egl.GetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
|
||||||
|
eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||||
|
_glfw.egl.CreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)
|
||||||
|
eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.egl.platform = _glfwPlatformGetEGLPlatform(&attribs);
|
||||||
|
if (_glfw.egl.platform)
|
||||||
|
{
|
||||||
|
_glfw.egl.display =
|
||||||
|
eglGetPlatformDisplayEXT(_glfw.egl.platform,
|
||||||
|
_glfwPlatformGetEGLNativeDisplay(),
|
||||||
|
attribs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay());
|
||||||
|
|
||||||
|
free(attribs);
|
||||||
|
|
||||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
@ -463,6 +509,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
EGLint attribs[40];
|
EGLint attribs[40];
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLContext share = NULL;
|
EGLContext share = NULL;
|
||||||
|
EGLNativeWindowType native;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
if (!_glfw.egl.display)
|
if (!_glfw.egl.display)
|
||||||
@ -588,23 +635,30 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set up attributes for surface creation
|
// Set up attributes for surface creation
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
if (fbconfig->sRGB)
|
||||||
{
|
{
|
||||||
int index = 0;
|
if (_glfw.egl.KHR_gl_colorspace)
|
||||||
|
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||||
if (fbconfig->sRGB)
|
}
|
||||||
{
|
|
||||||
if (_glfw.egl.KHR_gl_colorspace)
|
setAttrib(EGL_NONE, EGL_NONE);
|
||||||
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
|
||||||
}
|
native = _glfwPlatformGetEGLNativeWindow(window);
|
||||||
|
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
|
||||||
setAttrib(EGL_NONE, EGL_NONE);
|
// despite reporting EGL_EXT_platform_base
|
||||||
|
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
|
||||||
|
{
|
||||||
|
window->context.egl.surface =
|
||||||
|
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->context.egl.surface =
|
||||||
|
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
window->context.egl.surface =
|
|
||||||
eglCreateWindowSurface(_glfw.egl.display,
|
|
||||||
config,
|
|
||||||
_GLFW_EGL_NATIVE_WINDOW,
|
|
||||||
attribs);
|
|
||||||
if (window->context.egl.surface == EGL_NO_SURFACE)
|
if (window->context.egl.surface == EGL_NO_SURFACE)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
@ -25,26 +25,10 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#if defined(_GLFW_USE_EGLPLATFORM_H)
|
#if defined(_GLFW_WIN32)
|
||||||
#include <EGL/eglplatform.h>
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
#define EGLAPIENTRY __stdcall
|
#define EGLAPIENTRY __stdcall
|
||||||
typedef HDC EGLNativeDisplayType;
|
|
||||||
typedef HWND EGLNativeWindowType;
|
|
||||||
#elif defined(_GLFW_COCOA)
|
|
||||||
#define EGLAPIENTRY
|
|
||||||
typedef void* EGLNativeDisplayType;
|
|
||||||
typedef id EGLNativeWindowType;
|
|
||||||
#elif defined(_GLFW_X11)
|
|
||||||
#define EGLAPIENTRY
|
|
||||||
typedef Display* EGLNativeDisplayType;
|
|
||||||
typedef Window EGLNativeWindowType;
|
|
||||||
#elif defined(_GLFW_WAYLAND)
|
|
||||||
#define EGLAPIENTRY
|
|
||||||
typedef struct wl_display* EGLNativeDisplayType;
|
|
||||||
typedef struct wl_egl_window* EGLNativeWindowType;
|
|
||||||
#else
|
#else
|
||||||
#error "No supported EGL platform selected"
|
#define EGLAPIENTRY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EGL_SUCCESS 0x3000
|
#define EGL_SUCCESS 0x3000
|
||||||
@ -106,6 +90,17 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
|||||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
|
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
|
||||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
|
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
|
||||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
|
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
|
||||||
|
#define EGL_PLATFORM_X11_EXT 0x31d5
|
||||||
|
#define EGL_PLATFORM_WAYLAND_EXT 0x31d8
|
||||||
|
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
|
||||||
|
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
|
||||||
|
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
|
||||||
|
|
||||||
typedef int EGLint;
|
typedef int EGLint;
|
||||||
typedef unsigned int EGLBoolean;
|
typedef unsigned int EGLBoolean;
|
||||||
@ -115,6 +110,9 @@ typedef void* EGLContext;
|
|||||||
typedef void* EGLDisplay;
|
typedef void* EGLDisplay;
|
||||||
typedef void* EGLSurface;
|
typedef void* EGLSurface;
|
||||||
|
|
||||||
|
typedef void* EGLNativeDisplayType;
|
||||||
|
typedef void* EGLNativeWindowType;
|
||||||
|
|
||||||
// EGL function pointer typedefs
|
// EGL function pointer typedefs
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
|
||||||
@ -149,9 +147,10 @@ typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
|
|||||||
#define eglQueryString _glfw.egl.QueryString
|
#define eglQueryString _glfw.egl.QueryString
|
||||||
#define eglGetProcAddress _glfw.egl.GetProcAddress
|
#define eglGetProcAddress _glfw.egl.GetProcAddress
|
||||||
|
|
||||||
#define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl
|
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
|
||||||
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
|
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*);
|
||||||
|
#define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT
|
||||||
|
#define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT
|
||||||
|
|
||||||
// EGL-specific per-context data
|
// EGL-specific per-context data
|
||||||
//
|
//
|
||||||
@ -169,6 +168,7 @@ typedef struct _GLFWcontextEGL
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWlibraryEGL
|
typedef struct _GLFWlibraryEGL
|
||||||
{
|
{
|
||||||
|
EGLenum platform;
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLint major, minor;
|
EGLint major, minor;
|
||||||
GLFWbool prefix;
|
GLFWbool prefix;
|
||||||
@ -178,6 +178,15 @@ typedef struct _GLFWlibraryEGL
|
|||||||
GLFWbool KHR_gl_colorspace;
|
GLFWbool KHR_gl_colorspace;
|
||||||
GLFWbool KHR_get_all_proc_addresses;
|
GLFWbool KHR_get_all_proc_addresses;
|
||||||
GLFWbool KHR_context_flush_control;
|
GLFWbool KHR_context_flush_control;
|
||||||
|
GLFWbool EXT_client_extensions;
|
||||||
|
GLFWbool EXT_platform_base;
|
||||||
|
GLFWbool EXT_platform_x11;
|
||||||
|
GLFWbool EXT_platform_wayland;
|
||||||
|
GLFWbool ANGLE_platform_angle;
|
||||||
|
GLFWbool ANGLE_platform_angle_opengl;
|
||||||
|
GLFWbool ANGLE_platform_angle_d3d;
|
||||||
|
GLFWbool ANGLE_platform_angle_vulkan;
|
||||||
|
GLFWbool ANGLE_platform_angle_metal;
|
||||||
|
|
||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
@ -198,6 +207,9 @@ typedef struct _GLFWlibraryEGL
|
|||||||
PFN_eglQueryString QueryString;
|
PFN_eglQueryString QueryString;
|
||||||
PFN_eglGetProcAddress GetProcAddress;
|
PFN_eglGetProcAddress GetProcAddress;
|
||||||
|
|
||||||
|
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
|
||||||
|
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT;
|
||||||
|
|
||||||
} _GLFWlibraryEGL;
|
} _GLFWlibraryEGL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ static GLFWerrorfun _glfwErrorCallback;
|
|||||||
static _GLFWinitconfig _glfwInitHints =
|
static _GLFWinitconfig _glfwInitHints =
|
||||||
{
|
{
|
||||||
GLFW_TRUE, // hat buttons
|
GLFW_TRUE, // hat buttons
|
||||||
|
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
|
||||||
{
|
{
|
||||||
GLFW_TRUE, // macOS menu bar
|
GLFW_TRUE, // macOS menu bar
|
||||||
GLFW_TRUE // macOS bundle chdir
|
GLFW_TRUE // macOS bundle chdir
|
||||||
@ -90,6 +91,7 @@ static void terminate(void)
|
|||||||
_glfw.mappingCount = 0;
|
_glfw.mappingCount = 0;
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
_glfwTerminateVulkan();
|
||||||
|
_glfwPlatformTerminateJoysticks();
|
||||||
_glfwPlatformTerminate();
|
_glfwPlatformTerminate();
|
||||||
|
|
||||||
_glfw.initialized = GLFW_FALSE;
|
_glfw.initialized = GLFW_FALSE;
|
||||||
@ -191,6 +193,10 @@ void _glfwInputError(int code, const char* format, ...)
|
|||||||
strcpy(description, "The specified window has no context");
|
strcpy(description, "The specified window has no context");
|
||||||
else if (code == GLFW_CURSOR_UNAVAILABLE)
|
else if (code == GLFW_CURSOR_UNAVAILABLE)
|
||||||
strcpy(description, "The specified cursor shape is unavailable");
|
strcpy(description, "The specified cursor shape is unavailable");
|
||||||
|
else if (code == GLFW_FEATURE_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested feature cannot be implemented for this platform");
|
||||||
|
else if (code == GLFW_FEATURE_UNIMPLEMENTED)
|
||||||
|
strcpy(description, "The requested feature has not yet been implemented for this platform");
|
||||||
else
|
else
|
||||||
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||||
}
|
}
|
||||||
@ -283,6 +289,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
|||||||
case GLFW_JOYSTICK_HAT_BUTTONS:
|
case GLFW_JOYSTICK_HAT_BUTTONS:
|
||||||
_glfwInitHints.hatButtons = value;
|
_glfwInitHints.hatButtons = value;
|
||||||
return;
|
return;
|
||||||
|
case GLFW_ANGLE_PLATFORM_TYPE:
|
||||||
|
_glfwInitHints.angleType = value;
|
||||||
|
return;
|
||||||
case GLFW_COCOA_CHDIR_RESOURCES:
|
case GLFW_COCOA_CHDIR_RESOURCES:
|
||||||
_glfwInitHints.ns.chdir = value;
|
_glfwInitHints.ns.chdir = value;
|
||||||
return;
|
return;
|
||||||
|
47
src/input.c
47
src/input.c
@ -43,6 +43,22 @@
|
|||||||
#define _GLFW_JOYSTICK_BUTTON 2
|
#define _GLFW_JOYSTICK_BUTTON 2
|
||||||
#define _GLFW_JOYSTICK_HATBIT 3
|
#define _GLFW_JOYSTICK_HATBIT 3
|
||||||
|
|
||||||
|
// Initializes the platform joystick API if it has not been already
|
||||||
|
//
|
||||||
|
static GLFWbool initJoysticks(void)
|
||||||
|
{
|
||||||
|
if (!_glfw.joysticksInitialized)
|
||||||
|
{
|
||||||
|
if (!_glfwPlatformInitJoysticks())
|
||||||
|
{
|
||||||
|
_glfwPlatformTerminateJoysticks();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glfw.joysticksInitialized = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Finds a mapping based on joystick GUID
|
// Finds a mapping based on joystick GUID
|
||||||
//
|
//
|
||||||
static _GLFWmapping* findMapping(const char* guid)
|
static _GLFWmapping* findMapping(const char* guid)
|
||||||
@ -929,6 +945,9 @@ GLFWAPI int glfwJoystickPresent(int jid)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@ -954,6 +973,9 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -983,6 +1005,9 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1016,6 +1041,9 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1042,6 +1070,9 @@ GLFWAPI const char* glfwGetJoystickName(int jid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1067,6 +1098,9 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1112,6 +1146,10 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid)
|
|||||||
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
|
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
|
||||||
return cbfun;
|
return cbfun;
|
||||||
}
|
}
|
||||||
@ -1191,6 +1229,9 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@ -1216,6 +1257,9 @@ GLFWAPI const char* glfwGetGamepadName(int jid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1248,6 +1292,9 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!initJoysticks())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (!js->present)
|
if (!js->present)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
@ -194,6 +194,9 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
|||||||
#error "No supported window creation API selected"
|
#error "No supported window creation API selected"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "egl_context.h"
|
||||||
|
#include "osmesa_context.h"
|
||||||
|
|
||||||
// Constructs a version number string from the public header macros
|
// Constructs a version number string from the public header macros
|
||||||
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
||||||
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
|
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
|
||||||
@ -240,6 +243,7 @@ struct _GLFWerror
|
|||||||
struct _GLFWinitconfig
|
struct _GLFWinitconfig
|
||||||
{
|
{
|
||||||
GLFWbool hatButtons;
|
GLFWbool hatButtons;
|
||||||
|
int angleType;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool menubar;
|
GLFWbool menubar;
|
||||||
GLFWbool chdir;
|
GLFWbool chdir;
|
||||||
@ -266,6 +270,7 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
GLFWbool centerCursor;
|
GLFWbool centerCursor;
|
||||||
GLFWbool focusOnShow;
|
GLFWbool focusOnShow;
|
||||||
|
GLFWbool mousePassthrough;
|
||||||
GLFWbool scaleToMonitor;
|
GLFWbool scaleToMonitor;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool retina;
|
GLFWbool retina;
|
||||||
@ -359,9 +364,9 @@ struct _GLFWcontext
|
|||||||
// This is defined in the context API's context.h
|
// This is defined in the context API's context.h
|
||||||
_GLFW_PLATFORM_CONTEXT_STATE;
|
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||||
// This is defined in egl_context.h
|
// This is defined in egl_context.h
|
||||||
_GLFW_EGL_CONTEXT_STATE;
|
_GLFWcontextEGL egl;
|
||||||
// This is defined in osmesa_context.h
|
// This is defined in osmesa_context.h
|
||||||
_GLFW_OSMESA_CONTEXT_STATE;
|
_GLFWcontextOSMesa osmesa;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Window and context structure
|
// Window and context structure
|
||||||
@ -376,6 +381,7 @@ struct _GLFWwindow
|
|||||||
GLFWbool autoIconify;
|
GLFWbool autoIconify;
|
||||||
GLFWbool floating;
|
GLFWbool floating;
|
||||||
GLFWbool focusOnShow;
|
GLFWbool focusOnShow;
|
||||||
|
GLFWbool mousePassthrough;
|
||||||
GLFWbool shouldClose;
|
GLFWbool shouldClose;
|
||||||
void* userPointer;
|
void* userPointer;
|
||||||
GLFWvidmode videoMode;
|
GLFWvidmode videoMode;
|
||||||
@ -533,6 +539,7 @@ struct _GLFWlibrary
|
|||||||
_GLFWmonitor** monitors;
|
_GLFWmonitor** monitors;
|
||||||
int monitorCount;
|
int monitorCount;
|
||||||
|
|
||||||
|
GLFWbool joysticksInitialized;
|
||||||
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
|
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
|
||||||
_GLFWmapping* mappings;
|
_GLFWmapping* mappings;
|
||||||
int mappingCount;
|
int mappingCount;
|
||||||
@ -581,9 +588,9 @@ struct _GLFWlibrary
|
|||||||
// This is defined in the platform's joystick.h
|
// This is defined in the platform's joystick.h
|
||||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||||
// This is defined in egl_context.h
|
// This is defined in egl_context.h
|
||||||
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
_GLFWlibraryEGL egl;
|
||||||
// This is defined in osmesa_context.h
|
// This is defined in osmesa_context.h
|
||||||
_GLFW_OSMESA_LIBRARY_CONTEXT_STATE;
|
_GLFWlibraryOSMesa osmesa;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Global state shared between compilation units of GLFW
|
// Global state shared between compilation units of GLFW
|
||||||
@ -626,6 +633,8 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|||||||
void _glfwPlatformSetClipboardString(const char* string);
|
void _glfwPlatformSetClipboardString(const char* string);
|
||||||
const char* _glfwPlatformGetClipboardString(void);
|
const char* _glfwPlatformGetClipboardString(void);
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformInitJoysticks(void);
|
||||||
|
void _glfwPlatformTerminateJoysticks(void);
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
||||||
|
|
||||||
@ -674,6 +683,7 @@ float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
|
|||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled);
|
||||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
||||||
|
|
||||||
void _glfwPlatformPollEvents(void);
|
void _glfwPlatformPollEvents(void);
|
||||||
@ -681,6 +691,10 @@ void _glfwPlatformWaitEvents(void);
|
|||||||
void _glfwPlatformWaitEventsTimeout(double timeout);
|
void _glfwPlatformWaitEventsTimeout(double timeout);
|
||||||
void _glfwPlatformPostEmptyEvent(void);
|
void _glfwPlatformPostEmptyEvent(void);
|
||||||
|
|
||||||
|
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs);
|
||||||
|
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void);
|
||||||
|
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
|
||||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
|
@ -264,9 +264,50 @@ static int compareJoysticks(const void* fp, const void* sp)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Initialize joystick interface
|
void _glfwDetectJoystickConnectionLinux(void)
|
||||||
//
|
{
|
||||||
GLFWbool _glfwInitJoysticksLinux(void)
|
if (_glfw.linjs.inotify <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ssize_t offset = 0;
|
||||||
|
char buffer[16384];
|
||||||
|
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
while (size > offset)
|
||||||
|
{
|
||||||
|
regmatch_t match;
|
||||||
|
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
||||||
|
|
||||||
|
offset += sizeof(struct inotify_event) + e->len;
|
||||||
|
|
||||||
|
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
||||||
|
|
||||||
|
if (e->mask & (IN_CREATE | IN_ATTRIB))
|
||||||
|
openJoystickDevice(path);
|
||||||
|
else if (e->mask & IN_DELETE)
|
||||||
|
{
|
||||||
|
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||||
|
{
|
||||||
|
closeJoystick(_glfw.joysticks + jid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformInitJoysticks(void)
|
||||||
{
|
{
|
||||||
const char* dirname = "/dev/input";
|
const char* dirname = "/dev/input";
|
||||||
|
|
||||||
@ -320,9 +361,7 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close all opened joystick handles
|
void _glfwPlatformTerminateJoysticks(void)
|
||||||
//
|
|
||||||
void _glfwTerminateJoysticksLinux(void)
|
|
||||||
{
|
{
|
||||||
int jid;
|
int jid;
|
||||||
|
|
||||||
@ -333,60 +372,16 @@ void _glfwTerminateJoysticksLinux(void)
|
|||||||
closeJoystick(js);
|
closeJoystick(js);
|
||||||
}
|
}
|
||||||
|
|
||||||
regfree(&_glfw.linjs.regex);
|
|
||||||
|
|
||||||
if (_glfw.linjs.inotify > 0)
|
if (_glfw.linjs.inotify > 0)
|
||||||
{
|
{
|
||||||
if (_glfw.linjs.watch > 0)
|
if (_glfw.linjs.watch > 0)
|
||||||
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
|
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
|
||||||
|
|
||||||
close(_glfw.linjs.inotify);
|
close(_glfw.linjs.inotify);
|
||||||
|
regfree(&_glfw.linjs.regex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwDetectJoystickConnectionLinux(void)
|
|
||||||
{
|
|
||||||
if (_glfw.linjs.inotify <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ssize_t offset = 0;
|
|
||||||
char buffer[16384];
|
|
||||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
while (size > offset)
|
|
||||||
{
|
|
||||||
regmatch_t match;
|
|
||||||
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
|
||||||
|
|
||||||
offset += sizeof(struct inotify_event) + e->len;
|
|
||||||
|
|
||||||
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char path[PATH_MAX];
|
|
||||||
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
|
||||||
|
|
||||||
if (e->mask & (IN_CREATE | IN_ATTRIB))
|
|
||||||
openJoystickDevice(path);
|
|
||||||
else if (e->mask & IN_DELETE)
|
|
||||||
{
|
|
||||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
|
||||||
{
|
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
{
|
{
|
||||||
// Read all queued events (non-blocking)
|
// Read all queued events (non-blocking)
|
||||||
|
@ -55,8 +55,5 @@ typedef struct _GLFWlibraryLinux
|
|||||||
GLFWbool dropped;
|
GLFWbool dropped;
|
||||||
} _GLFWlibraryLinux;
|
} _GLFWlibraryLinux;
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwInitJoysticksLinux(void);
|
|
||||||
void _glfwTerminateJoysticksLinux(void);
|
|
||||||
void _glfwDetectJoystickConnectionLinux(void);
|
void _glfwDetectJoystickConnectionLinux(void);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
|||||||
|
|
||||||
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
||||||
// windows with a non-visible occlusion state
|
// windows with a non-visible occlusion state
|
||||||
if (!([window->ns.object occlusionState] & NSWindowOcclusionStateVisible))
|
if (window->ns.occluded)
|
||||||
{
|
{
|
||||||
int interval = 0;
|
int interval = 0;
|
||||||
[window->context.nsgl.object getValues:&interval
|
[window->context.nsgl.object getValues:&interval
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -37,11 +39,14 @@
|
|||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
_glfwPollMonitorsNull();
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
void _glfwPlatformTerminate(void)
|
||||||
{
|
{
|
||||||
|
free(_glfw.null.clipboardString);
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,15 @@
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformInitJoysticks(void)
|
||||||
|
{
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformTerminateJoysticks(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
@ -29,6 +29,37 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// The the sole (fake) video mode of our (sole) fake monitor
|
||||||
|
//
|
||||||
|
static GLFWvidmode getVideoMode(void)
|
||||||
|
{
|
||||||
|
GLFWvidmode mode;
|
||||||
|
mode.width = 1920;
|
||||||
|
mode.height = 1080;
|
||||||
|
mode.redBits = 8;
|
||||||
|
mode.greenBits = 8;
|
||||||
|
mode.blueBits = 8;
|
||||||
|
mode.refreshRate = 60;
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwPollMonitorsNull(void)
|
||||||
|
{
|
||||||
|
const float dpi = 141.f;
|
||||||
|
const GLFWvidmode mode = getVideoMode();
|
||||||
|
_GLFWmonitor* monitor = _glfwAllocMonitor("Null SuperNoop 0",
|
||||||
|
(int) (mode.width * 25.4f / dpi),
|
||||||
|
(int) (mode.height * 25.4f / dpi));
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -36,6 +67,7 @@
|
|||||||
|
|
||||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||||
{
|
{
|
||||||
|
_glfwFreeGammaArrays(&monitor->null.ramp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
@ -55,23 +87,69 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
|||||||
int* xpos, int* ypos,
|
int* xpos, int* ypos,
|
||||||
int* width, int* height)
|
int* width, int* height)
|
||||||
{
|
{
|
||||||
|
const GLFWvidmode mode = getVideoMode();
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = 0;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = 10;
|
||||||
|
if (width)
|
||||||
|
*width = mode.width;
|
||||||
|
if (height)
|
||||||
|
*height = mode.height - 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||||
{
|
{
|
||||||
return NULL;
|
GLFWvidmode* mode = calloc(1, sizeof(GLFWvidmode));
|
||||||
|
*mode = getVideoMode();
|
||||||
|
*found = 1;
|
||||||
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
{
|
{
|
||||||
|
*mode = getVideoMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
if (!monitor->null.ramp.size)
|
||||||
|
{
|
||||||
|
_glfwAllocGammaArrays(&monitor->null.ramp, 256);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < monitor->null.ramp.size; i++)
|
||||||
|
{
|
||||||
|
const float gamma = 2.2f;
|
||||||
|
float value;
|
||||||
|
value = i / (float) (monitor->null.ramp.size - 1);
|
||||||
|
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||||
|
value = _glfw_fminf(value, 65535.f);
|
||||||
|
|
||||||
|
monitor->null.ramp.red[i] = (unsigned short) value;
|
||||||
|
monitor->null.ramp.green[i] = (unsigned short) value;
|
||||||
|
monitor->null.ramp.blue[i] = (unsigned short) value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwAllocGammaArrays(ramp, monitor->null.ramp.size);
|
||||||
|
memcpy(ramp->red, monitor->null.ramp.red, sizeof(short) * ramp->size);
|
||||||
|
memcpy(ramp->green, monitor->null.ramp.green, sizeof(short) * ramp->size);
|
||||||
|
memcpy(ramp->blue, monitor->null.ramp.blue, sizeof(short) * ramp->size);
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
|
if (monitor->null.ramp.size != ramp->size)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Null: Gamma ramp size must match current ramp size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(monitor->null.ramp.red, ramp->red, sizeof(short) * ramp->size);
|
||||||
|
memcpy(monitor->null.ramp.green, ramp->green, sizeof(short) * ramp->size);
|
||||||
|
memcpy(monitor->null.ramp.blue, ramp->blue, sizeof(short) * ramp->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,17 +27,14 @@
|
|||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNull null
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNull null
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
|
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE struct { int dummyMonitor; }
|
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE struct { int dummyCursor; }
|
#define _GLFW_PLATFORM_CURSOR_STATE struct { int dummyCursor; }
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE struct { int dummyLibraryWindow; }
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
|
||||||
#define _GLFW_EGL_CONTEXT_STATE struct { int dummyEGLContext; }
|
|
||||||
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE struct { int dummyEGLLibraryContext; }
|
|
||||||
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "posix_thread.h"
|
#include "posix_thread.h"
|
||||||
#include "null_joystick.h"
|
#include "null_joystick.h"
|
||||||
@ -56,7 +53,37 @@
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWwindowNull
|
typedef struct _GLFWwindowNull
|
||||||
{
|
{
|
||||||
int width;
|
int xpos;
|
||||||
int height;
|
int ypos;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
char* title;
|
||||||
|
GLFWbool visible;
|
||||||
|
GLFWbool iconified;
|
||||||
|
GLFWbool maximized;
|
||||||
|
GLFWbool resizable;
|
||||||
|
GLFWbool decorated;
|
||||||
|
GLFWbool floating;
|
||||||
|
GLFWbool transparent;
|
||||||
|
float opacity;
|
||||||
} _GLFWwindowNull;
|
} _GLFWwindowNull;
|
||||||
|
|
||||||
|
// Null-specific per-monitor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmonitorNull
|
||||||
|
{
|
||||||
|
GLFWgammaramp ramp;
|
||||||
|
} _GLFWmonitorNull;
|
||||||
|
|
||||||
|
// Null-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryNull
|
||||||
|
{
|
||||||
|
int xcursor;
|
||||||
|
int ycursor;
|
||||||
|
char* clipboardString;
|
||||||
|
_GLFWwindow* focusedWindow;
|
||||||
|
} _GLFWlibraryNull;
|
||||||
|
|
||||||
|
void _glfwPollMonitorsNull(void);
|
||||||
|
|
||||||
|
@ -29,12 +29,71 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
|
||||||
|
{
|
||||||
|
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
const float ratio = (float) window->numer / (float) window->denom;
|
||||||
|
*height = (int) (*width / ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->minwidth != GLFW_DONT_CARE && *width < window->minwidth)
|
||||||
|
*width = window->minwidth;
|
||||||
|
else if (window->maxwidth != GLFW_DONT_CARE && *width > window->maxwidth)
|
||||||
|
*width = window->maxwidth;
|
||||||
|
|
||||||
|
if (window->minheight != GLFW_DONT_CARE && *height < window->minheight)
|
||||||
|
*height = window->minheight;
|
||||||
|
else if (window->maxheight != GLFW_DONT_CARE && *height > window->maxheight)
|
||||||
|
*height = window->maxheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fitToMonitor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
GLFWvidmode mode;
|
||||||
|
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||||
|
_glfwPlatformGetMonitorPos(window->monitor,
|
||||||
|
&window->null.xpos,
|
||||||
|
&window->null.ypos);
|
||||||
|
window->null.width = mode.width;
|
||||||
|
window->null.height = mode.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acquireMonitor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
_glfwInputMonitorWindow(window->monitor, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void releaseMonitor(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->monitor->window != window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int createNativeWindow(_GLFWwindow* window,
|
static int createNativeWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig)
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
window->null.width = wndconfig->width;
|
if (window->monitor)
|
||||||
window->null.height = wndconfig->height;
|
fitToMonitor(window);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->null.xpos = 17;
|
||||||
|
window->null.ypos = 17;
|
||||||
|
window->null.width = wndconfig->width;
|
||||||
|
window->null.height = wndconfig->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->null.visible = wndconfig->visible;
|
||||||
|
window->null.decorated = wndconfig->decorated;
|
||||||
|
window->null.maximized = wndconfig->maximized;
|
||||||
|
window->null.floating = wndconfig->floating;
|
||||||
|
window->null.transparent = fbconfig->transparent;
|
||||||
|
window->null.opacity = 1.f;
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
@ -49,7 +108,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
if (!createNativeWindow(window, wndconfig))
|
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
@ -69,11 +128,24 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->monitor)
|
||||||
|
{
|
||||||
|
_glfwPlatformShowWindow(window);
|
||||||
|
_glfwPlatformFocusWindow(window);
|
||||||
|
acquireMonitor(window);
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (window->monitor)
|
||||||
|
releaseMonitor(window);
|
||||||
|
|
||||||
|
if (_glfw.null.focusedWindow == window)
|
||||||
|
_glfw.null.focusedWindow = NULL;
|
||||||
|
|
||||||
if (window->context.destroy)
|
if (window->context.destroy)
|
||||||
window->context.destroy(window);
|
window->context.destroy(window);
|
||||||
}
|
}
|
||||||
@ -93,14 +165,54 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
int width, int height,
|
int width, int height,
|
||||||
int refreshRate)
|
int refreshRate)
|
||||||
{
|
{
|
||||||
|
if (window->monitor == monitor)
|
||||||
|
{
|
||||||
|
if (!monitor)
|
||||||
|
{
|
||||||
|
_glfwPlatformSetWindowPos(window, xpos, ypos);
|
||||||
|
_glfwPlatformSetWindowSize(window, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->monitor)
|
||||||
|
releaseMonitor(window);
|
||||||
|
|
||||||
|
_glfwInputWindowMonitor(window, monitor);
|
||||||
|
|
||||||
|
if (window->monitor)
|
||||||
|
{
|
||||||
|
window->null.visible = GLFW_TRUE;
|
||||||
|
acquireMonitor(window);
|
||||||
|
fitToMonitor(window);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwPlatformSetWindowPos(window, xpos, ypos);
|
||||||
|
_glfwPlatformSetWindowSize(window, width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
|
if (xpos)
|
||||||
|
*xpos = window->null.xpos;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = window->null.ypos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
||||||
{
|
{
|
||||||
|
if (window->monitor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (window->null.xpos != xpos || window->null.ypos != ypos)
|
||||||
|
{
|
||||||
|
window->null.xpos = xpos;
|
||||||
|
window->null.ypos = ypos;
|
||||||
|
_glfwInputWindowPos(window, xpos, ypos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||||
@ -113,18 +225,34 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
window->null.width = width;
|
if (window->monitor)
|
||||||
window->null.height = height;
|
return;
|
||||||
|
|
||||||
|
if (window->null.width != width || window->null.height != height)
|
||||||
|
{
|
||||||
|
window->null.width = width;
|
||||||
|
window->null.height = height;
|
||||||
|
_glfwInputWindowSize(window, width, height);
|
||||||
|
_glfwInputFramebufferSize(window, width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||||
int minwidth, int minheight,
|
int minwidth, int minheight,
|
||||||
int maxwidth, int maxheight)
|
int maxwidth, int maxheight)
|
||||||
{
|
{
|
||||||
|
int width = window->null.width;
|
||||||
|
int height = window->null.height;
|
||||||
|
applySizeLimits(window, &width, &height);
|
||||||
|
_glfwPlatformSetWindowSize(window, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
|
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
|
||||||
{
|
{
|
||||||
|
int width = window->null.width;
|
||||||
|
int height = window->null.height;
|
||||||
|
applySizeLimits(window, &width, &height);
|
||||||
|
_glfwPlatformSetWindowSize(window, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
||||||
@ -139,6 +267,13 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|||||||
int* left, int* top,
|
int* left, int* top,
|
||||||
int* right, int* bottom)
|
int* right, int* bottom)
|
||||||
{
|
{
|
||||||
|
if (window->null.decorated && !window->monitor)
|
||||||
|
{
|
||||||
|
*left = 1;
|
||||||
|
*top = 10;
|
||||||
|
*right = 1;
|
||||||
|
*bottom = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||||
@ -152,50 +287,93 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
|||||||
|
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (_glfw.null.focusedWindow == window)
|
||||||
|
{
|
||||||
|
_glfw.null.focusedWindow = NULL;
|
||||||
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window->null.iconified)
|
||||||
|
{
|
||||||
|
window->null.iconified = GLFW_TRUE;
|
||||||
|
_glfwInputWindowIconify(window, GLFW_TRUE);
|
||||||
|
|
||||||
|
if (window->monitor)
|
||||||
|
releaseMonitor(window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (window->null.iconified)
|
||||||
|
{
|
||||||
|
window->null.iconified = GLFW_FALSE;
|
||||||
|
_glfwInputWindowIconify(window, GLFW_FALSE);
|
||||||
|
|
||||||
|
if (window->monitor)
|
||||||
|
acquireMonitor(window);
|
||||||
|
}
|
||||||
|
else if (window->null.maximized)
|
||||||
|
{
|
||||||
|
window->null.maximized = GLFW_FALSE;
|
||||||
|
_glfwInputWindowMaximize(window, GLFW_FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (!window->null.maximized)
|
||||||
|
{
|
||||||
|
window->null.maximized = GLFW_TRUE;
|
||||||
|
_glfwInputWindowMaximize(window, GLFW_TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return window->null.maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return _glfw.null.xcursor >= window->null.xpos &&
|
||||||
|
_glfw.null.ycursor >= window->null.ypos &&
|
||||||
|
_glfw.null.xcursor <= window->null.xpos + window->null.width - 1 &&
|
||||||
|
_glfw.null.ycursor <= window->null.ypos + window->null.height - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return window->null.transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
|
window->null.resizable = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
|
window->null.decorated = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
window->null.floating = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return 1.f;
|
return window->null.opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||||
{
|
{
|
||||||
|
window->null.opacity = opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
||||||
@ -204,43 +382,63 @@ void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
|||||||
|
|
||||||
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
|
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
window->null.visible = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (_glfw.null.focusedWindow == window)
|
||||||
|
{
|
||||||
|
_glfw.null.focusedWindow = NULL;
|
||||||
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
window->null.visible = GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (_glfw.null.focusedWindow == window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!window->null.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_GLFWwindow* previous = _glfw.null.focusedWindow;
|
||||||
|
_glfw.null.focusedWindow = window;
|
||||||
|
|
||||||
|
if (previous)
|
||||||
|
{
|
||||||
|
_glfwInputWindowFocus(previous, GLFW_FALSE);
|
||||||
|
if (previous->monitor && previous->autoIconify)
|
||||||
|
_glfwPlatformIconifyWindow(previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return _glfw.null.focusedWindow == window;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return window->null.iconified;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
return window->null.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformPollEvents(void)
|
void _glfwPlatformPollEvents(void)
|
||||||
@ -261,10 +459,16 @@ void _glfwPlatformPostEmptyEvent(void)
|
|||||||
|
|
||||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||||
{
|
{
|
||||||
|
if (xpos)
|
||||||
|
*xpos = _glfw.null.xcursor - window->null.xpos;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = _glfw.null.ycursor - window->null.ypos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||||
{
|
{
|
||||||
|
_glfw.null.xcursor = window->null.xpos + (int) x;
|
||||||
|
_glfw.null.ycursor = window->null.ypos + (int) y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||||
@ -293,21 +497,140 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
|
|
||||||
void _glfwPlatformSetClipboardString(const char* string)
|
void _glfwPlatformSetClipboardString(const char* string)
|
||||||
{
|
{
|
||||||
|
char* copy = _glfw_strdup(string);
|
||||||
|
free(_glfw.null.clipboardString);
|
||||||
|
_glfw.null.clipboardString = copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(void)
|
const char* _glfwPlatformGetClipboardString(void)
|
||||||
{
|
{
|
||||||
return NULL;
|
return _glfw.null.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
{
|
{
|
||||||
return "";
|
switch (scancode)
|
||||||
|
{
|
||||||
|
case GLFW_KEY_APOSTROPHE:
|
||||||
|
return "'";
|
||||||
|
case GLFW_KEY_COMMA:
|
||||||
|
return ",";
|
||||||
|
case GLFW_KEY_MINUS:
|
||||||
|
case GLFW_KEY_KP_SUBTRACT:
|
||||||
|
return "-";
|
||||||
|
case GLFW_KEY_PERIOD:
|
||||||
|
case GLFW_KEY_KP_DECIMAL:
|
||||||
|
return ".";
|
||||||
|
case GLFW_KEY_SLASH:
|
||||||
|
case GLFW_KEY_KP_DIVIDE:
|
||||||
|
return "/";
|
||||||
|
case GLFW_KEY_SEMICOLON:
|
||||||
|
return ";";
|
||||||
|
case GLFW_KEY_EQUAL:
|
||||||
|
case GLFW_KEY_KP_EQUAL:
|
||||||
|
return "=";
|
||||||
|
case GLFW_KEY_LEFT_BRACKET:
|
||||||
|
return "[";
|
||||||
|
case GLFW_KEY_RIGHT_BRACKET:
|
||||||
|
return "]";
|
||||||
|
case GLFW_KEY_KP_MULTIPLY:
|
||||||
|
return "*";
|
||||||
|
case GLFW_KEY_KP_ADD:
|
||||||
|
return "+";
|
||||||
|
case GLFW_KEY_BACKSLASH:
|
||||||
|
case GLFW_KEY_WORLD_1:
|
||||||
|
case GLFW_KEY_WORLD_2:
|
||||||
|
return "\\";
|
||||||
|
case GLFW_KEY_0:
|
||||||
|
case GLFW_KEY_KP_0:
|
||||||
|
return "0";
|
||||||
|
case GLFW_KEY_1:
|
||||||
|
case GLFW_KEY_KP_1:
|
||||||
|
return "1";
|
||||||
|
case GLFW_KEY_2:
|
||||||
|
case GLFW_KEY_KP_2:
|
||||||
|
return "2";
|
||||||
|
case GLFW_KEY_3:
|
||||||
|
case GLFW_KEY_KP_3:
|
||||||
|
return "3";
|
||||||
|
case GLFW_KEY_4:
|
||||||
|
case GLFW_KEY_KP_4:
|
||||||
|
return "4";
|
||||||
|
case GLFW_KEY_5:
|
||||||
|
case GLFW_KEY_KP_5:
|
||||||
|
return "5";
|
||||||
|
case GLFW_KEY_6:
|
||||||
|
case GLFW_KEY_KP_6:
|
||||||
|
return "6";
|
||||||
|
case GLFW_KEY_7:
|
||||||
|
case GLFW_KEY_KP_7:
|
||||||
|
return "7";
|
||||||
|
case GLFW_KEY_8:
|
||||||
|
case GLFW_KEY_KP_8:
|
||||||
|
return "8";
|
||||||
|
case GLFW_KEY_9:
|
||||||
|
case GLFW_KEY_KP_9:
|
||||||
|
return "9";
|
||||||
|
case GLFW_KEY_A:
|
||||||
|
return "a";
|
||||||
|
case GLFW_KEY_B:
|
||||||
|
return "b";
|
||||||
|
case GLFW_KEY_C:
|
||||||
|
return "c";
|
||||||
|
case GLFW_KEY_D:
|
||||||
|
return "d";
|
||||||
|
case GLFW_KEY_E:
|
||||||
|
return "e";
|
||||||
|
case GLFW_KEY_F:
|
||||||
|
return "f";
|
||||||
|
case GLFW_KEY_G:
|
||||||
|
return "g";
|
||||||
|
case GLFW_KEY_H:
|
||||||
|
return "h";
|
||||||
|
case GLFW_KEY_I:
|
||||||
|
return "i";
|
||||||
|
case GLFW_KEY_J:
|
||||||
|
return "j";
|
||||||
|
case GLFW_KEY_K:
|
||||||
|
return "k";
|
||||||
|
case GLFW_KEY_L:
|
||||||
|
return "l";
|
||||||
|
case GLFW_KEY_M:
|
||||||
|
return "m";
|
||||||
|
case GLFW_KEY_N:
|
||||||
|
return "n";
|
||||||
|
case GLFW_KEY_O:
|
||||||
|
return "o";
|
||||||
|
case GLFW_KEY_P:
|
||||||
|
return "p";
|
||||||
|
case GLFW_KEY_Q:
|
||||||
|
return "q";
|
||||||
|
case GLFW_KEY_R:
|
||||||
|
return "r";
|
||||||
|
case GLFW_KEY_S:
|
||||||
|
return "s";
|
||||||
|
case GLFW_KEY_T:
|
||||||
|
return "t";
|
||||||
|
case GLFW_KEY_U:
|
||||||
|
return "u";
|
||||||
|
case GLFW_KEY_V:
|
||||||
|
return "v";
|
||||||
|
case GLFW_KEY_W:
|
||||||
|
return "w";
|
||||||
|
case GLFW_KEY_X:
|
||||||
|
return "x";
|
||||||
|
case GLFW_KEY_Y:
|
||||||
|
return "y";
|
||||||
|
case GLFW_KEY_Z:
|
||||||
|
return "z";
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformGetKeyScancode(int key)
|
int _glfwPlatformGetKeyScancode(int key)
|
||||||
{
|
{
|
||||||
return -1;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
@ -327,6 +650,6 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
VkSurfaceKHR* surface)
|
VkSurfaceKHR* surface)
|
||||||
{
|
{
|
||||||
// This seems like the most appropriate error to return here
|
// This seems like the most appropriate error to return here
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +54,6 @@ typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
|
|||||||
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
|
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
|
||||||
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
|
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
|
||||||
|
|
||||||
#define _GLFW_OSMESA_CONTEXT_STATE _GLFWcontextOSMesa osmesa
|
|
||||||
#define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
|
|
||||||
|
|
||||||
|
|
||||||
// OSMesa-specific per-context data
|
// OSMesa-specific per-context data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWcontextOSMesa
|
typedef struct _GLFWcontextOSMesa
|
||||||
|
@ -143,6 +143,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||||
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
|
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||||
@ -580,7 +582,6 @@ int _glfwPlatformInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfwInitTimerWin32();
|
_glfwInitTimerWin32();
|
||||||
_glfwInitJoysticksWin32();
|
|
||||||
|
|
||||||
_glfwPollMonitorsWin32();
|
_glfwPollMonitorsWin32();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -607,8 +608,6 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfwTerminateWGL();
|
_glfwTerminateWGL();
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
|
|
||||||
_glfwTerminateJoysticksWin32();
|
|
||||||
|
|
||||||
freeLibraries();
|
freeLibraries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
|||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
js = _glfw.joysticks + jid;
|
||||||
if (js->present)
|
if (js->present)
|
||||||
{
|
{
|
||||||
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||||
@ -491,39 +491,6 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Initialize joystick interface
|
|
||||||
//
|
|
||||||
void _glfwInitJoysticksWin32(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.dinput8.instance)
|
|
||||||
{
|
|
||||||
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
|
||||||
DIRECTINPUT_VERSION,
|
|
||||||
&IID_IDirectInput8W,
|
|
||||||
(void**) &_glfw.win32.dinput8.api,
|
|
||||||
NULL)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to create interface");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwDetectJoystickConnectionWin32();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close all opened joystick handles
|
|
||||||
//
|
|
||||||
void _glfwTerminateJoysticksWin32(void)
|
|
||||||
{
|
|
||||||
int jid;
|
|
||||||
|
|
||||||
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.api)
|
|
||||||
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks for new joysticks after DBT_DEVICEARRIVAL
|
// Checks for new joysticks after DBT_DEVICEARRIVAL
|
||||||
//
|
//
|
||||||
void _glfwDetectJoystickConnectionWin32(void)
|
void _glfwDetectJoystickConnectionWin32(void)
|
||||||
@ -603,6 +570,37 @@ void _glfwDetectJoystickDisconnectionWin32(void)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformInitJoysticks(void)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.dinput8.instance)
|
||||||
|
{
|
||||||
|
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
||||||
|
DIRECTINPUT_VERSION,
|
||||||
|
&IID_IDirectInput8W,
|
||||||
|
(void**) &_glfw.win32.dinput8.api,
|
||||||
|
NULL)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to create interface");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwDetectJoystickConnectionWin32();
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformTerminateJoysticks(void)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
closeJoystick(_glfw.joysticks + jid);
|
||||||
|
|
||||||
|
if (_glfw.win32.dinput8.api)
|
||||||
|
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
||||||
|
}
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
{
|
{
|
||||||
if (js->win32.device)
|
if (js->win32.device)
|
||||||
@ -672,11 +670,11 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Screams of horror are appropriate at this point
|
// Screams of horror are appropriate at this point
|
||||||
int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
int stateIndex = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
||||||
if (state < 0 || state > 8)
|
if (stateIndex < 0 || stateIndex > 8)
|
||||||
state = 8;
|
stateIndex = 8;
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, pi, states[state]);
|
_glfwInputJoystickHat(js, pi, states[stateIndex]);
|
||||||
pi++;
|
pi++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,6 @@ typedef struct _GLFWjoystickWin32
|
|||||||
GUID guid;
|
GUID guid;
|
||||||
} _GLFWjoystickWin32;
|
} _GLFWjoystickWin32;
|
||||||
|
|
||||||
|
|
||||||
void _glfwInitJoysticksWin32(void);
|
|
||||||
void _glfwTerminateJoysticksWin32(void);
|
|
||||||
void _glfwDetectJoystickConnectionWin32(void);
|
void _glfwDetectJoystickConnectionWin32(void);
|
||||||
void _glfwDetectJoystickDisconnectionWin32(void);
|
void _glfwDetectJoystickDisconnectionWin32(void);
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@
|
|||||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
#ifndef WM_DWMCOMPOSITIONCHANGED
|
||||||
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WM_DWMCOLORIZATIONCOLORCHANGED
|
||||||
|
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
|
||||||
|
#endif
|
||||||
#ifndef WM_COPYGLOBALDATA
|
#ifndef WM_COPYGLOBALDATA
|
||||||
#define WM_COPYGLOBALDATA 0x0049
|
#define WM_COPYGLOBALDATA 0x0049
|
||||||
#endif
|
#endif
|
||||||
@ -160,9 +163,6 @@ typedef enum
|
|||||||
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
||||||
|
|
||||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
||||||
#define IsWindowsXPOrGreater() \
|
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
|
|
||||||
LOBYTE(_WIN32_WINNT_WINXP), 0)
|
|
||||||
#define IsWindowsVistaOrGreater() \
|
#define IsWindowsVistaOrGreater() \
|
||||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||||
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||||
@ -247,9 +247,11 @@ typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UIN
|
|||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
|
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
// shcore.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
@ -277,8 +279,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
|||||||
|
|
||||||
#include "win32_joystick.h"
|
#include "win32_joystick.h"
|
||||||
#include "wgl_context.h"
|
#include "wgl_context.h"
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#if !defined(_GLFW_WNDCLASSNAME)
|
#if !defined(_GLFW_WNDCLASSNAME)
|
||||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||||
@ -288,9 +288,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
|||||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
|
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
|
||||||
@ -319,6 +316,8 @@ typedef struct _GLFWwindowWin32
|
|||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
// The last recevied high surrogate when decoding pairs of UTF-16 messages
|
||||||
|
WCHAR highSurrogate;
|
||||||
|
|
||||||
} _GLFWwindowWin32;
|
} _GLFWwindowWin32;
|
||||||
|
|
||||||
@ -374,6 +373,7 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush Flush;
|
||||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
|
PFN_DwmGetColorizationColor GetColorizationColor;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -377,12 +377,17 @@ static void updateWindowStyles(const _GLFWwindow* window)
|
|||||||
//
|
//
|
||||||
static void updateFramebufferTransparency(const _GLFWwindow* window)
|
static void updateFramebufferTransparency(const _GLFWwindow* window)
|
||||||
{
|
{
|
||||||
BOOL enabled;
|
BOOL composition, opaque;
|
||||||
|
DWORD color;
|
||||||
|
|
||||||
if (!IsWindowsVistaOrGreater())
|
if (!IsWindowsVistaOrGreater())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IsWindows8OrGreater() ||
|
||||||
|
(SUCCEEDED(DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
||||||
{
|
{
|
||||||
HRGN region = CreateRectRgn(0, 0, -1, -1);
|
HRGN region = CreateRectRgn(0, 0, -1, -1);
|
||||||
DWM_BLURBEHIND bb = {0};
|
DWM_BLURBEHIND bb = {0};
|
||||||
@ -390,37 +395,18 @@ static void updateFramebufferTransparency(const _GLFWwindow* window)
|
|||||||
bb.hRgnBlur = region;
|
bb.hRgnBlur = region;
|
||||||
bb.fEnable = TRUE;
|
bb.fEnable = TRUE;
|
||||||
|
|
||||||
if (SUCCEEDED(DwmEnableBlurBehindWindow(window->win32.handle, &bb)))
|
DwmEnableBlurBehindWindow(window->win32.handle, &bb);
|
||||||
{
|
|
||||||
// Decorated windows don't repaint the transparent background
|
|
||||||
// leaving a trail behind animations
|
|
||||||
// HACK: Making the window layered with a transparency color key
|
|
||||||
// seems to fix this. Normally, when specifying
|
|
||||||
// a transparency color key to be used when composing the
|
|
||||||
// layered window, all pixels painted by the window in this
|
|
||||||
// color will be transparent. That doesn't seem to be the
|
|
||||||
// case anymore, at least when used with blur behind window
|
|
||||||
// plus negative region.
|
|
||||||
LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
|
||||||
exStyle |= WS_EX_LAYERED;
|
|
||||||
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
|
||||||
|
|
||||||
// Using a color key not equal to black to fix the trailing
|
|
||||||
// issue. When set to black, something is making the hit test
|
|
||||||
// not resize with the window frame.
|
|
||||||
SetLayeredWindowAttributes(window->win32.handle,
|
|
||||||
RGB(255, 0, 255), 255, LWA_COLORKEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteObject(region);
|
DeleteObject(region);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
// HACK: Disable framebuffer transparency on Windows 7 when the
|
||||||
exStyle &= ~WS_EX_LAYERED;
|
// colorization color is opaque, because otherwise the window
|
||||||
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
// contents is blended additively with the previous frame instead
|
||||||
RedrawWindow(window->win32.handle, NULL, NULL,
|
// of replacing it
|
||||||
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
|
DWM_BLURBEHIND bb = {0};
|
||||||
|
bb.dwFlags = DWM_BB_ENABLE;
|
||||||
|
DwmEnableBlurBehindWindow(window->win32.handle, &bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,11 +454,8 @@ static void acquireMonitor(_GLFWwindow* window)
|
|||||||
|
|
||||||
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
// HACK: When mouse trails are enabled the cursor becomes invisible when
|
||||||
// the OpenGL ICD switches to page flipping
|
// the OpenGL ICD switches to page flipping
|
||||||
if (IsWindowsXPOrGreater())
|
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
||||||
{
|
SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
|
||||||
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &_glfw.win32.mouseTrailSize, 0);
|
|
||||||
SystemParametersInfo(SPI_SETMOUSETRAILS, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window->monitor->window)
|
if (!window->monitor->window)
|
||||||
@ -495,8 +478,7 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
SetThreadExecutionState(ES_CONTINUOUS);
|
SetThreadExecutionState(ES_CONTINUOUS);
|
||||||
|
|
||||||
// HACK: Restore mouse trail length saved in acquireMonitor
|
// HACK: Restore mouse trail length saved in acquireMonitor
|
||||||
if (IsWindowsXPOrGreater())
|
SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
||||||
SystemParametersInfo(SPI_SETMOUSETRAILS, _glfw.win32.mouseTrailSize, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||||
@ -530,6 +512,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
case WM_DEVICECHANGE:
|
case WM_DEVICECHANGE:
|
||||||
{
|
{
|
||||||
|
if (!_glfw.joysticksInitialized)
|
||||||
|
break;
|
||||||
|
|
||||||
if (wParam == DBT_DEVICEARRIVAL)
|
if (wParam == DBT_DEVICEARRIVAL)
|
||||||
{
|
{
|
||||||
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
||||||
@ -650,11 +635,38 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
case WM_SYSCHAR:
|
case WM_SYSCHAR:
|
||||||
|
{
|
||||||
|
if (wParam >= 0xd800 && wParam <= 0xdbff)
|
||||||
|
window->win32.highSurrogate = (WCHAR) wParam;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int codepoint = 0;
|
||||||
|
|
||||||
|
if (wParam >= 0xdc00 && wParam <= 0xdfff)
|
||||||
|
{
|
||||||
|
if (window->win32.highSurrogate)
|
||||||
|
{
|
||||||
|
codepoint += (window->win32.highSurrogate - 0xd800) << 10;
|
||||||
|
codepoint += (WCHAR) wParam - 0xdc00;
|
||||||
|
codepoint += 0x10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
codepoint = (WCHAR) wParam;
|
||||||
|
|
||||||
|
window->win32.highSurrogate = 0;
|
||||||
|
_glfwInputChar(window, codepoint, getKeyMods(), uMsg != WM_SYSCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uMsg == WM_SYSCHAR && window->win32.keymenu)
|
||||||
|
break;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_UNICHAR:
|
case WM_UNICHAR:
|
||||||
{
|
{
|
||||||
const GLFWbool plain = (uMsg != WM_SYSCHAR);
|
if (wParam == UNICODE_NOCHAR)
|
||||||
|
|
||||||
if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
|
|
||||||
{
|
{
|
||||||
// WM_UNICHAR is not sent by Windows, but is sent by some
|
// WM_UNICHAR is not sent by Windows, but is sent by some
|
||||||
// third-party input method engine
|
// third-party input method engine
|
||||||
@ -662,11 +674,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);
|
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE);
|
||||||
|
|
||||||
if (uMsg == WM_SYSCHAR && window->win32.keymenu)
|
|
||||||
break;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1082,6 +1090,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WM_DWMCOMPOSITIONCHANGED:
|
case WM_DWMCOMPOSITIONCHANGED:
|
||||||
|
case WM_DWMCOLORIZATIONCOLORCHANGED:
|
||||||
{
|
{
|
||||||
if (window->win32.transparent)
|
if (window->win32.transparent)
|
||||||
updateFramebufferTransparency(window);
|
updateFramebufferTransparency(window);
|
||||||
@ -1807,7 +1816,8 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
|||||||
|
|
||||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
BOOL enabled;
|
BOOL composition, opaque;
|
||||||
|
DWORD color;
|
||||||
|
|
||||||
if (!window->win32.transparent)
|
if (!window->win32.transparent)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@ -1815,7 +1825,20 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
|||||||
if (!IsWindowsVistaOrGreater())
|
if (!IsWindowsVistaOrGreater())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled;
|
if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!IsWindows8OrGreater())
|
||||||
|
{
|
||||||
|
// HACK: Disable framebuffer transparency on Windows 7 when the
|
||||||
|
// colorization color is opaque, because otherwise the window
|
||||||
|
// contents is blended additively with the previous frame instead
|
||||||
|
// of replacing it
|
||||||
|
if (FAILED(DwmGetColorizationColor(&color, &opaque)) || opaque)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
@ -1835,6 +1858,36 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
COLORREF key = 0;
|
||||||
|
BYTE alpha = 0;
|
||||||
|
DWORD flags = 0;
|
||||||
|
DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||||
|
|
||||||
|
if (exStyle & WS_EX_LAYERED)
|
||||||
|
GetLayeredWindowAttributes(window->win32.handle, &key, &alpha, &flags);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
exStyle |= (WS_EX_TRANSPARENT | WS_EX_LAYERED);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exStyle &= ~WS_EX_TRANSPARENT;
|
||||||
|
// NOTE: Window opacity also needs the layered window style so do not
|
||||||
|
// remove it if the window is alpha blended
|
||||||
|
if (exStyle & WS_EX_LAYERED)
|
||||||
|
{
|
||||||
|
if (!(flags & LWA_ALPHA))
|
||||||
|
exStyle &= ~WS_EX_LAYERED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
SetLayeredWindowAttributes(window->win32.handle, key, alpha, flags);
|
||||||
|
}
|
||||||
|
|
||||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
BYTE alpha;
|
BYTE alpha;
|
||||||
@ -1852,19 +1905,22 @@ float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||||
{
|
{
|
||||||
if (opacity < 1.f)
|
LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||||
|
if (opacity < 1.f || (exStyle & WS_EX_TRANSPARENT))
|
||||||
{
|
{
|
||||||
const BYTE alpha = (BYTE) (255 * opacity);
|
const BYTE alpha = (BYTE) (255 * opacity);
|
||||||
DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
exStyle |= WS_EX_LAYERED;
|
||||||
style |= WS_EX_LAYERED;
|
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
||||||
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style);
|
|
||||||
SetLayeredWindowAttributes(window->win32.handle, 0, alpha, LWA_ALPHA);
|
SetLayeredWindowAttributes(window->win32.handle, 0, alpha, LWA_ALPHA);
|
||||||
}
|
}
|
||||||
|
else if (exStyle & WS_EX_TRANSPARENT)
|
||||||
|
{
|
||||||
|
SetLayeredWindowAttributes(window->win32.handle, 0, 0, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
exStyle &= ~WS_EX_LAYERED;
|
||||||
style &= ~WS_EX_LAYERED;
|
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
||||||
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2190,6 +2246,57 @@ const char* _glfwPlatformGetClipboardString(void)
|
|||||||
return _glfw.win32.clipboardString;
|
return _glfw.win32.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle)
|
||||||
|
{
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_opengl)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
|
||||||
|
else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGLES)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_d3d)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D9)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
|
||||||
|
else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D11)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_vulkan)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
{
|
||||||
|
*attribs = calloc(3, sizeof(EGLint));
|
||||||
|
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
|
||||||
|
(*attribs)[1] = type;
|
||||||
|
(*attribs)[2] = EGL_NONE;
|
||||||
|
return EGL_PLATFORM_ANGLE_ANGLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
|
||||||
|
{
|
||||||
|
return GetDC(_glfw.win32.helperWindowHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return window->win32.handle;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
|
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
|
||||||
|
35
src/window.c
35
src/window.c
@ -197,13 +197,14 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
|||||||
window->videoMode.blueBits = fbconfig.blueBits;
|
window->videoMode.blueBits = fbconfig.blueBits;
|
||||||
window->videoMode.refreshRate = _glfw.hints.refreshRate;
|
window->videoMode.refreshRate = _glfw.hints.refreshRate;
|
||||||
|
|
||||||
window->monitor = (_GLFWmonitor*) monitor;
|
window->monitor = (_GLFWmonitor*) monitor;
|
||||||
window->resizable = wndconfig.resizable;
|
window->resizable = wndconfig.resizable;
|
||||||
window->decorated = wndconfig.decorated;
|
window->decorated = wndconfig.decorated;
|
||||||
window->autoIconify = wndconfig.autoIconify;
|
window->autoIconify = wndconfig.autoIconify;
|
||||||
window->floating = wndconfig.floating;
|
window->floating = wndconfig.floating;
|
||||||
window->focusOnShow = wndconfig.focusOnShow;
|
window->focusOnShow = wndconfig.focusOnShow;
|
||||||
window->cursorMode = GLFW_CURSOR_NORMAL;
|
window->mousePassthrough = wndconfig.mousePassthrough;
|
||||||
|
window->cursorMode = GLFW_CURSOR_NORMAL;
|
||||||
|
|
||||||
window->minwidth = GLFW_DONT_CARE;
|
window->minwidth = GLFW_DONT_CARE;
|
||||||
window->minheight = GLFW_DONT_CARE;
|
window->minheight = GLFW_DONT_CARE;
|
||||||
@ -228,6 +229,9 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wndconfig.mousePassthrough)
|
||||||
|
_glfwPlatformSetWindowMousePassthrough(window, GLFW_TRUE);
|
||||||
|
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
{
|
{
|
||||||
if (wndconfig.centerCursor)
|
if (wndconfig.centerCursor)
|
||||||
@ -378,6 +382,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_FOCUS_ON_SHOW:
|
case GLFW_FOCUS_ON_SHOW:
|
||||||
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
case GLFW_MOUSE_PASSTHROUGH:
|
||||||
|
_glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
return;
|
||||||
case GLFW_CLIENT_API:
|
case GLFW_CLIENT_API:
|
||||||
_glfw.hints.context.client = value;
|
_glfw.hints.context.client = value;
|
||||||
return;
|
return;
|
||||||
@ -396,7 +403,7 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||||
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
case GLFW_CONTEXT_DEBUG:
|
||||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
case GLFW_CONTEXT_NO_ERROR:
|
case GLFW_CONTEXT_NO_ERROR:
|
||||||
@ -822,6 +829,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
|||||||
return _glfwPlatformWindowHovered(window);
|
return _glfwPlatformWindowHovered(window);
|
||||||
case GLFW_FOCUS_ON_SHOW:
|
case GLFW_FOCUS_ON_SHOW:
|
||||||
return window->focusOnShow;
|
return window->focusOnShow;
|
||||||
|
case GLFW_MOUSE_PASSTHROUGH:
|
||||||
|
return window->mousePassthrough;
|
||||||
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
||||||
return _glfwPlatformFramebufferTransparent(window);
|
return _glfwPlatformFramebufferTransparent(window);
|
||||||
case GLFW_RESIZABLE:
|
case GLFW_RESIZABLE:
|
||||||
@ -846,7 +855,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
|||||||
return window->context.robustness;
|
return window->context.robustness;
|
||||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||||
return window->context.forward;
|
return window->context.forward;
|
||||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
case GLFW_CONTEXT_DEBUG:
|
||||||
return window->context.debug;
|
return window->context.debug;
|
||||||
case GLFW_OPENGL_PROFILE:
|
case GLFW_OPENGL_PROFILE:
|
||||||
return window->context.profile;
|
return window->context.profile;
|
||||||
@ -900,6 +909,14 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
|||||||
}
|
}
|
||||||
else if (attrib == GLFW_FOCUS_ON_SHOW)
|
else if (attrib == GLFW_FOCUS_ON_SHOW)
|
||||||
window->focusOnShow = value;
|
window->focusOnShow = value;
|
||||||
|
else if (attrib == GLFW_MOUSE_PASSTHROUGH)
|
||||||
|
{
|
||||||
|
if (window->mousePassthrough == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window->mousePassthrough = value;
|
||||||
|
_glfwPlatformSetWindowMousePassthrough(window, value);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
||||||
}
|
}
|
||||||
|
@ -341,9 +341,9 @@ static void pointerHandleAxis(void* data,
|
|||||||
axis == WL_POINTER_AXIS_VERTICAL_SCROLL);
|
axis == WL_POINTER_AXIS_VERTICAL_SCROLL);
|
||||||
|
|
||||||
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||||
x = wl_fixed_to_double(value) * scrollFactor;
|
x = -wl_fixed_to_double(value) * scrollFactor;
|
||||||
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||||
y = wl_fixed_to_double(value) * scrollFactor;
|
y = -wl_fixed_to_double(value) * scrollFactor;
|
||||||
|
|
||||||
_glfwInputScroll(window, x, y);
|
_glfwInputScroll(window, x, y);
|
||||||
}
|
}
|
||||||
@ -1146,11 +1146,6 @@ int _glfwPlatformInit(void)
|
|||||||
// Sync so we got all initial output events
|
// Sync so we got all initial output events
|
||||||
wl_display_roundtrip(_glfw.wl.display);
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
_glfw.wl.timerfd = -1;
|
_glfw.wl.timerfd = -1;
|
||||||
@ -1213,9 +1208,6 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
void _glfwPlatformTerminate(void)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
|
||||||
_glfwTerminateJoysticksLinux();
|
|
||||||
#endif
|
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
if (_glfw.wl.egl.handle)
|
if (_glfw.wl.egl.handle)
|
||||||
{
|
{
|
||||||
|
@ -199,7 +199,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
|
|
||||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: Gamma ramp access is not available");
|
"Wayland: Gamma ramp access is not available");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
|
||||||
const GLFWgammaramp* ramp)
|
const GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: Gamma ramp access is not available");
|
"Wayland: Gamma ramp access is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||||||
#include "null_joystick.h"
|
#include "null_joystick.h"
|
||||||
#endif
|
#endif
|
||||||
#include "xkb_unicode.h"
|
#include "xkb_unicode.h"
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#include "wayland-xdg-shell-client-protocol.h"
|
#include "wayland-xdg-shell-client-protocol.h"
|
||||||
#include "wayland-xdg-decoration-client-protocol.h"
|
#include "wayland-xdg-decoration-client-protocol.h"
|
||||||
@ -67,9 +65,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl
|
||||||
|
@ -142,8 +142,8 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Creating a buffer file for %d B failed: %m",
|
"Wayland: Creating a buffer file for %d B failed: %s",
|
||||||
length);
|
length, strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
|||||||
if (data == MAP_FAILED)
|
if (data == MAP_FAILED)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: mmap failed: %m");
|
"Wayland: mmap failed: %s", strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -749,10 +749,17 @@ static void handleEvents(int timeout)
|
|||||||
if (read_ret != 8)
|
if (read_ret != 8)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < repeats; ++i)
|
if (_glfw.wl.keyboardFocus)
|
||||||
_glfwInputKey(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastKey,
|
{
|
||||||
_glfw.wl.keyboardLastScancode, GLFW_REPEAT,
|
for (i = 0; i < repeats; ++i)
|
||||||
_glfw.wl.xkb.modifiers);
|
{
|
||||||
|
_glfwInputKey(_glfw.wl.keyboardFocus,
|
||||||
|
_glfw.wl.keyboardLastKey,
|
||||||
|
_glfw.wl.keyboardLastScancode,
|
||||||
|
GLFW_REPEAT,
|
||||||
|
_glfw.wl.xkb.modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[2].revents & POLLIN)
|
if (fds[2].revents & POLLIN)
|
||||||
@ -883,8 +890,8 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
|||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||||
int count, const GLFWimage* images)
|
int count, const GLFWimage* images)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: Setting window icon not supported");
|
"Wayland: The platform does not support setting the window icon");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||||
@ -892,16 +899,16 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
|||||||
// A Wayland client is not aware of its position, so just warn and leave it
|
// A Wayland client is not aware of its position, so just warn and leave it
|
||||||
// as (0, 0)
|
// as (0, 0)
|
||||||
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: Window position retrieval not supported");
|
"Wayland: The platform does not provide the window position");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
||||||
{
|
{
|
||||||
// A Wayland client can not set its position, so just warn
|
// A Wayland client can not set its position, so just warn
|
||||||
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: Window position setting not supported");
|
"Wayland: The platform does not support setting the window position");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||||
@ -940,14 +947,18 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
// TODO: find out how to trigger a resize.
|
// TODO: find out how to trigger a resize.
|
||||||
// The actual limits are checked in the xdg_toplevel::configure handler.
|
// The actual limits are checked in the xdg_toplevel::configure handler.
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
|
"Wayland: Window aspect ratio not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window,
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window,
|
||||||
int* width, int* height)
|
int* width, int* height)
|
||||||
{
|
{
|
||||||
_glfwPlatformGetWindowSize(window, width, height);
|
_glfwPlatformGetWindowSize(window, width, height);
|
||||||
*width *= window->wl.scale;
|
if (width)
|
||||||
*height *= window->wl.scale;
|
*width *= window->wl.scale;
|
||||||
|
if (height)
|
||||||
|
*height *= window->wl.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
@ -1030,14 +1041,14 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
"Wayland: Window attention request not implemented yet");
|
"Wayland: Window attention request not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
"Wayland: Focusing a window requires user interaction");
|
"Wayland: The platform does not support setting the input focus");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||||
@ -1096,7 +1107,7 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
|||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
"Wayland: Window attribute setting not implemented yet");
|
"Wayland: Window attribute setting not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,10 +1125,23 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
"Wayland: Window attribute setting not implemented yet");
|
"Wayland: Window attribute setting not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
struct wl_region* region = wl_compositor_create_region(_glfw.wl.compositor);
|
||||||
|
wl_surface_set_input_region(window->wl.surface, region);
|
||||||
|
wl_region_destroy(region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wl_surface_set_input_region(window->wl.surface, 0);
|
||||||
|
wl_surface_commit(window->wl.surface);
|
||||||
|
}
|
||||||
|
|
||||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return 1.f;
|
return 1.f;
|
||||||
@ -1125,6 +1149,8 @@ float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||||
{
|
{
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||||
|
"Wayland: The platform does not support setting the window opacity");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
||||||
@ -1186,6 +1212,8 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
|
"Wayland: Key names not yet implemented");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1671,6 +1699,24 @@ const char* _glfwPlatformGetClipboardString(void)
|
|||||||
return _glfw.wl.clipboardString;
|
return _glfw.wl.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland)
|
||||||
|
return EGL_PLATFORM_WAYLAND_EXT;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
|
||||||
|
{
|
||||||
|
return _glfw.wl.display;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return window->wl.native;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
|
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
|
||||||
|
446
src/x11_init.c
446
src/x11_init.c
@ -37,24 +37,15 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
// Translate an X11 key code to a GLFW key code.
|
// Translate the X11 KeySyms for a key to a GLFW key code
|
||||||
|
// NOTE: This is only used as a fallback, in case the XKB method fails
|
||||||
|
// It is layout-dependent and will fail partially on most non-US layouts
|
||||||
//
|
//
|
||||||
static int translateKeyCode(int scancode)
|
static int translateKeySyms(const KeySym* keysyms, int width)
|
||||||
{
|
{
|
||||||
int keySym;
|
if (width > 1)
|
||||||
|
|
||||||
// Valid key code range is [8,255], according to the Xlib manual
|
|
||||||
if (scancode < 8 || scancode > 255)
|
|
||||||
return GLFW_KEY_UNKNOWN;
|
|
||||||
|
|
||||||
if (_glfw.x11.xkb.available)
|
|
||||||
{
|
{
|
||||||
// Try secondary keysym, for numeric keypad keys
|
switch (keysyms[1])
|
||||||
// Note: This way we always force "NumLock = ON", which is intentional
|
|
||||||
// since the returned key code should correspond to a physical
|
|
||||||
// location.
|
|
||||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 1);
|
|
||||||
switch (keySym)
|
|
||||||
{
|
{
|
||||||
case XK_KP_0: return GLFW_KEY_KP_0;
|
case XK_KP_0: return GLFW_KEY_KP_0;
|
||||||
case XK_KP_1: return GLFW_KEY_KP_1;
|
case XK_KP_1: return GLFW_KEY_KP_1;
|
||||||
@ -72,22 +63,9 @@ static int translateKeyCode(int scancode)
|
|||||||
case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
|
case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try primary keysym for function keys (non-printable keys)
|
|
||||||
// These should not depend on the current keyboard layout
|
|
||||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int dummy;
|
|
||||||
KeySym* keySyms;
|
|
||||||
|
|
||||||
keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy);
|
|
||||||
keySym = keySyms[0];
|
|
||||||
XFree(keySyms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (keySym)
|
switch (keysyms[0])
|
||||||
{
|
{
|
||||||
case XK_Escape: return GLFW_KEY_ESCAPE;
|
case XK_Escape: return GLFW_KEY_ESCAPE;
|
||||||
case XK_Tab: return GLFW_KEY_TAB;
|
case XK_Tab: return GLFW_KEY_TAB;
|
||||||
@ -231,7 +209,7 @@ static int translateKeyCode(int scancode)
|
|||||||
//
|
//
|
||||||
static void createKeyTables(void)
|
static void createKeyTables(void)
|
||||||
{
|
{
|
||||||
int scancode, key;
|
int scancode, scancodeMin, scancodeMax;
|
||||||
|
|
||||||
memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
|
memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
|
||||||
memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
|
memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
|
||||||
@ -241,89 +219,217 @@ static void createKeyTables(void)
|
|||||||
// Use XKB to determine physical key locations independently of the
|
// Use XKB to determine physical key locations independently of the
|
||||||
// current keyboard layout
|
// current keyboard layout
|
||||||
|
|
||||||
char name[XkbKeyNameLength + 1];
|
|
||||||
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
||||||
XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc);
|
XkbGetNames(_glfw.x11.display, XkbKeyNamesMask | XkbKeyAliasesMask, desc);
|
||||||
|
|
||||||
|
scancodeMin = desc->min_key_code;
|
||||||
|
scancodeMax = desc->max_key_code;
|
||||||
|
|
||||||
|
const struct
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
char* name;
|
||||||
|
} keymap[] =
|
||||||
|
{
|
||||||
|
{ GLFW_KEY_GRAVE_ACCENT, "TLDE" },
|
||||||
|
{ GLFW_KEY_1, "AE01" },
|
||||||
|
{ GLFW_KEY_2, "AE02" },
|
||||||
|
{ GLFW_KEY_3, "AE03" },
|
||||||
|
{ GLFW_KEY_4, "AE04" },
|
||||||
|
{ GLFW_KEY_5, "AE05" },
|
||||||
|
{ GLFW_KEY_6, "AE06" },
|
||||||
|
{ GLFW_KEY_7, "AE07" },
|
||||||
|
{ GLFW_KEY_8, "AE08" },
|
||||||
|
{ GLFW_KEY_9, "AE09" },
|
||||||
|
{ GLFW_KEY_0, "AE10" },
|
||||||
|
{ GLFW_KEY_MINUS, "AE11" },
|
||||||
|
{ GLFW_KEY_EQUAL, "AE12" },
|
||||||
|
{ GLFW_KEY_Q, "AD01" },
|
||||||
|
{ GLFW_KEY_W, "AD02" },
|
||||||
|
{ GLFW_KEY_E, "AD03" },
|
||||||
|
{ GLFW_KEY_R, "AD04" },
|
||||||
|
{ GLFW_KEY_T, "AD05" },
|
||||||
|
{ GLFW_KEY_Y, "AD06" },
|
||||||
|
{ GLFW_KEY_U, "AD07" },
|
||||||
|
{ GLFW_KEY_I, "AD08" },
|
||||||
|
{ GLFW_KEY_O, "AD09" },
|
||||||
|
{ GLFW_KEY_P, "AD10" },
|
||||||
|
{ GLFW_KEY_LEFT_BRACKET, "AD11" },
|
||||||
|
{ GLFW_KEY_RIGHT_BRACKET, "AD12" },
|
||||||
|
{ GLFW_KEY_A, "AC01" },
|
||||||
|
{ GLFW_KEY_S, "AC02" },
|
||||||
|
{ GLFW_KEY_D, "AC03" },
|
||||||
|
{ GLFW_KEY_F, "AC04" },
|
||||||
|
{ GLFW_KEY_G, "AC05" },
|
||||||
|
{ GLFW_KEY_H, "AC06" },
|
||||||
|
{ GLFW_KEY_J, "AC07" },
|
||||||
|
{ GLFW_KEY_K, "AC08" },
|
||||||
|
{ GLFW_KEY_L, "AC09" },
|
||||||
|
{ GLFW_KEY_SEMICOLON, "AC10" },
|
||||||
|
{ GLFW_KEY_APOSTROPHE, "AC11" },
|
||||||
|
{ GLFW_KEY_Z, "AB01" },
|
||||||
|
{ GLFW_KEY_X, "AB02" },
|
||||||
|
{ GLFW_KEY_C, "AB03" },
|
||||||
|
{ GLFW_KEY_V, "AB04" },
|
||||||
|
{ GLFW_KEY_B, "AB05" },
|
||||||
|
{ GLFW_KEY_N, "AB06" },
|
||||||
|
{ GLFW_KEY_M, "AB07" },
|
||||||
|
{ GLFW_KEY_COMMA, "AB08" },
|
||||||
|
{ GLFW_KEY_PERIOD, "AB09" },
|
||||||
|
{ GLFW_KEY_SLASH, "AB10" },
|
||||||
|
{ GLFW_KEY_BACKSLASH, "BKSL" },
|
||||||
|
{ GLFW_KEY_WORLD_1, "LSGT" },
|
||||||
|
{ GLFW_KEY_SPACE, "SPCE" },
|
||||||
|
{ GLFW_KEY_ESCAPE, "ESC" },
|
||||||
|
{ GLFW_KEY_ENTER, "RTRN" },
|
||||||
|
{ GLFW_KEY_TAB, "TAB" },
|
||||||
|
{ GLFW_KEY_BACKSPACE, "BKSP" },
|
||||||
|
{ GLFW_KEY_INSERT, "INS" },
|
||||||
|
{ GLFW_KEY_DELETE, "DELE" },
|
||||||
|
{ GLFW_KEY_RIGHT, "RGHT" },
|
||||||
|
{ GLFW_KEY_LEFT, "LEFT" },
|
||||||
|
{ GLFW_KEY_DOWN, "DOWN" },
|
||||||
|
{ GLFW_KEY_UP, "UP" },
|
||||||
|
{ GLFW_KEY_PAGE_UP, "PGUP" },
|
||||||
|
{ GLFW_KEY_PAGE_DOWN, "PGDN" },
|
||||||
|
{ GLFW_KEY_HOME, "HOME" },
|
||||||
|
{ GLFW_KEY_END, "END" },
|
||||||
|
{ GLFW_KEY_CAPS_LOCK, "CAPS" },
|
||||||
|
{ GLFW_KEY_SCROLL_LOCK, "SCLK" },
|
||||||
|
{ GLFW_KEY_NUM_LOCK, "NMLK" },
|
||||||
|
{ GLFW_KEY_PRINT_SCREEN, "PRSC" },
|
||||||
|
{ GLFW_KEY_PAUSE, "PAUS" },
|
||||||
|
{ GLFW_KEY_F1, "FK01" },
|
||||||
|
{ GLFW_KEY_F2, "FK02" },
|
||||||
|
{ GLFW_KEY_F3, "FK03" },
|
||||||
|
{ GLFW_KEY_F4, "FK04" },
|
||||||
|
{ GLFW_KEY_F5, "FK05" },
|
||||||
|
{ GLFW_KEY_F6, "FK06" },
|
||||||
|
{ GLFW_KEY_F7, "FK07" },
|
||||||
|
{ GLFW_KEY_F8, "FK08" },
|
||||||
|
{ GLFW_KEY_F9, "FK09" },
|
||||||
|
{ GLFW_KEY_F10, "FK10" },
|
||||||
|
{ GLFW_KEY_F11, "FK11" },
|
||||||
|
{ GLFW_KEY_F12, "FK12" },
|
||||||
|
{ GLFW_KEY_F13, "FK13" },
|
||||||
|
{ GLFW_KEY_F14, "FK14" },
|
||||||
|
{ GLFW_KEY_F15, "FK15" },
|
||||||
|
{ GLFW_KEY_F16, "FK16" },
|
||||||
|
{ GLFW_KEY_F17, "FK17" },
|
||||||
|
{ GLFW_KEY_F18, "FK18" },
|
||||||
|
{ GLFW_KEY_F19, "FK19" },
|
||||||
|
{ GLFW_KEY_F20, "FK20" },
|
||||||
|
{ GLFW_KEY_F21, "FK21" },
|
||||||
|
{ GLFW_KEY_F22, "FK22" },
|
||||||
|
{ GLFW_KEY_F23, "FK23" },
|
||||||
|
{ GLFW_KEY_F24, "FK24" },
|
||||||
|
{ GLFW_KEY_F25, "FK25" },
|
||||||
|
{ GLFW_KEY_KP_0, "KP0" },
|
||||||
|
{ GLFW_KEY_KP_1, "KP1" },
|
||||||
|
{ GLFW_KEY_KP_2, "KP2" },
|
||||||
|
{ GLFW_KEY_KP_3, "KP3" },
|
||||||
|
{ GLFW_KEY_KP_4, "KP4" },
|
||||||
|
{ GLFW_KEY_KP_5, "KP5" },
|
||||||
|
{ GLFW_KEY_KP_6, "KP6" },
|
||||||
|
{ GLFW_KEY_KP_7, "KP7" },
|
||||||
|
{ GLFW_KEY_KP_8, "KP8" },
|
||||||
|
{ GLFW_KEY_KP_9, "KP9" },
|
||||||
|
{ GLFW_KEY_KP_DECIMAL, "KPDL" },
|
||||||
|
{ GLFW_KEY_KP_DIVIDE, "KPDV" },
|
||||||
|
{ GLFW_KEY_KP_MULTIPLY, "KPMU" },
|
||||||
|
{ GLFW_KEY_KP_SUBTRACT, "KPSU" },
|
||||||
|
{ GLFW_KEY_KP_ADD, "KPAD" },
|
||||||
|
{ GLFW_KEY_KP_ENTER, "KPEN" },
|
||||||
|
{ GLFW_KEY_KP_EQUAL, "KPEQ" },
|
||||||
|
{ GLFW_KEY_LEFT_SHIFT, "LFSH" },
|
||||||
|
{ GLFW_KEY_LEFT_CONTROL, "LCTL" },
|
||||||
|
{ GLFW_KEY_LEFT_ALT, "LALT" },
|
||||||
|
{ GLFW_KEY_LEFT_SUPER, "LWIN" },
|
||||||
|
{ GLFW_KEY_RIGHT_SHIFT, "RTSH" },
|
||||||
|
{ GLFW_KEY_RIGHT_CONTROL, "RCTL" },
|
||||||
|
{ GLFW_KEY_RIGHT_ALT, "RALT" },
|
||||||
|
{ GLFW_KEY_RIGHT_ALT, "LVL3" },
|
||||||
|
{ GLFW_KEY_RIGHT_ALT, "MDSW" },
|
||||||
|
{ GLFW_KEY_RIGHT_SUPER, "RWIN" },
|
||||||
|
{ GLFW_KEY_MENU, "MENU" }
|
||||||
|
};
|
||||||
|
|
||||||
// Find the X11 key code -> GLFW key code mapping
|
// Find the X11 key code -> GLFW key code mapping
|
||||||
for (scancode = desc->min_key_code; scancode <= desc->max_key_code; scancode++)
|
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||||
{
|
{
|
||||||
memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
|
int key = GLFW_KEY_UNKNOWN;
|
||||||
name[XkbKeyNameLength] = '\0';
|
|
||||||
|
|
||||||
// Map the key name to a GLFW key code. Note: We only map printable
|
// Map the key name to a GLFW key code. Note: We use the US
|
||||||
// keys here, and we use the US keyboard layout. The rest of the
|
// keyboard layout. Because function keys aren't mapped correctly
|
||||||
// keys (function keys) are mapped using traditional KeySym
|
// when using traditional KeySym translations, they are mapped
|
||||||
// translations.
|
// here instead.
|
||||||
if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT;
|
for (int i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
|
||||||
else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1;
|
{
|
||||||
else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2;
|
if (strncmp(desc->names->keys[scancode].name,
|
||||||
else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3;
|
keymap[i].name,
|
||||||
else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4;
|
XkbKeyNameLength) == 0)
|
||||||
else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5;
|
{
|
||||||
else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6;
|
key = keymap[i].key;
|
||||||
else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7;
|
break;
|
||||||
else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8;
|
}
|
||||||
else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9;
|
}
|
||||||
else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0;
|
|
||||||
else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS;
|
|
||||||
else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL;
|
|
||||||
else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q;
|
|
||||||
else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W;
|
|
||||||
else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E;
|
|
||||||
else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R;
|
|
||||||
else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T;
|
|
||||||
else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y;
|
|
||||||
else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U;
|
|
||||||
else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I;
|
|
||||||
else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O;
|
|
||||||
else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P;
|
|
||||||
else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET;
|
|
||||||
else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET;
|
|
||||||
else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A;
|
|
||||||
else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S;
|
|
||||||
else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D;
|
|
||||||
else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F;
|
|
||||||
else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G;
|
|
||||||
else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H;
|
|
||||||
else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J;
|
|
||||||
else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K;
|
|
||||||
else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L;
|
|
||||||
else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON;
|
|
||||||
else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE;
|
|
||||||
else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z;
|
|
||||||
else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X;
|
|
||||||
else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C;
|
|
||||||
else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V;
|
|
||||||
else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B;
|
|
||||||
else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N;
|
|
||||||
else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M;
|
|
||||||
else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA;
|
|
||||||
else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD;
|
|
||||||
else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH;
|
|
||||||
else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH;
|
|
||||||
else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1;
|
|
||||||
else key = GLFW_KEY_UNKNOWN;
|
|
||||||
|
|
||||||
if ((scancode >= 0) && (scancode < 256))
|
// Fall back to key aliases in case the key name did not match
|
||||||
_glfw.x11.keycodes[scancode] = key;
|
for (int i = 0; i < desc->names->num_key_aliases; i++)
|
||||||
|
{
|
||||||
|
if (key != GLFW_KEY_UNKNOWN)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (strncmp(desc->names->key_aliases[i].real,
|
||||||
|
desc->names->keys[scancode].name,
|
||||||
|
XkbKeyNameLength) != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
|
||||||
|
{
|
||||||
|
if (strncmp(desc->names->key_aliases[i].alias,
|
||||||
|
keymap[j].name,
|
||||||
|
XkbKeyNameLength) == 0)
|
||||||
|
{
|
||||||
|
key = keymap[j].key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.x11.keycodes[scancode] = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
XkbFreeNames(desc, XkbKeyNamesMask, True);
|
XkbFreeNames(desc, XkbKeyNamesMask, True);
|
||||||
XkbFreeKeyboard(desc, 0, True);
|
XkbFreeKeyboard(desc, 0, True);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
XDisplayKeycodes(_glfw.x11.display, &scancodeMin, &scancodeMax);
|
||||||
|
|
||||||
for (scancode = 0; scancode < 256; scancode++)
|
int width;
|
||||||
|
KeySym* keysyms = XGetKeyboardMapping(_glfw.x11.display,
|
||||||
|
scancodeMin,
|
||||||
|
scancodeMax - scancodeMin + 1,
|
||||||
|
&width);
|
||||||
|
|
||||||
|
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||||
{
|
{
|
||||||
// Translate the un-translated key codes using traditional X11 KeySym
|
// Translate the un-translated key codes using traditional X11 KeySym
|
||||||
// lookups
|
// lookups
|
||||||
if (_glfw.x11.keycodes[scancode] < 0)
|
if (_glfw.x11.keycodes[scancode] < 0)
|
||||||
_glfw.x11.keycodes[scancode] = translateKeyCode(scancode);
|
{
|
||||||
|
const size_t base = (scancode - scancodeMin) * width;
|
||||||
|
_glfw.x11.keycodes[scancode] = translateKeySyms(&keysyms[base], width);
|
||||||
|
}
|
||||||
|
|
||||||
// Store the reverse translation for faster key name lookup
|
// Store the reverse translation for faster key name lookup
|
||||||
if (_glfw.x11.keycodes[scancode] > 0)
|
if (_glfw.x11.keycodes[scancode] > 0)
|
||||||
_glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode;
|
_glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XFree(keysyms);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the IM has a usable style
|
// Check whether the IM has a usable style
|
||||||
@ -349,15 +455,49 @@ static GLFWbool hasUsableInputMethodStyle(void)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the specified atom is supported
|
static void inputMethodDestroyCallback(XIM im, XPointer clientData, XPointer callData)
|
||||||
|
{
|
||||||
|
_glfw.x11.im = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inputMethodInstantiateCallback(Display* display,
|
||||||
|
XPointer clientData,
|
||||||
|
XPointer callData)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.im)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL);
|
||||||
|
if (_glfw.x11.im)
|
||||||
|
{
|
||||||
|
if (!hasUsableInputMethodStyle())
|
||||||
|
{
|
||||||
|
XCloseIM(_glfw.x11.im);
|
||||||
|
_glfw.x11.im = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.im)
|
||||||
|
{
|
||||||
|
XIMCallback callback;
|
||||||
|
callback.callback = (XIMProc) inputMethodDestroyCallback;
|
||||||
|
callback.client_data = NULL;
|
||||||
|
XSetIMValues(_glfw.x11.im, XNDestroyCallback, &callback, NULL);
|
||||||
|
|
||||||
|
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||||
|
_glfwCreateInputContextX11(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the atom ID only if it is listed in the specified array
|
||||||
//
|
//
|
||||||
static Atom getSupportedAtom(Atom* supportedAtoms,
|
static Atom getAtomIfSupported(Atom* supportedAtoms,
|
||||||
unsigned long atomCount,
|
unsigned long atomCount,
|
||||||
const char* atomName)
|
const char* atomName)
|
||||||
{
|
{
|
||||||
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < atomCount; i++)
|
for (unsigned long i = 0; i < atomCount; i++)
|
||||||
{
|
{
|
||||||
if (supportedAtoms[i] == atom)
|
if (supportedAtoms[i] == atom)
|
||||||
return atom;
|
return atom;
|
||||||
@ -425,33 +565,33 @@ static void detectEWMH(void)
|
|||||||
// See which of the atoms we support that are supported by the WM
|
// See which of the atoms we support that are supported by the WM
|
||||||
|
|
||||||
_glfw.x11.NET_WM_STATE =
|
_glfw.x11.NET_WM_STATE =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||||
_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
|
_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||||
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||||
_glfw.x11.NET_WM_WINDOW_TYPE =
|
_glfw.x11.NET_WM_WINDOW_TYPE =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
|
||||||
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
|
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||||
_glfw.x11.NET_WORKAREA =
|
_glfw.x11.NET_WORKAREA =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||||
_glfw.x11.NET_CURRENT_DESKTOP =
|
_glfw.x11.NET_CURRENT_DESKTOP =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
||||||
_glfw.x11.NET_ACTIVE_WINDOW =
|
_glfw.x11.NET_ACTIVE_WINDOW =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
||||||
_glfw.x11.NET_FRAME_EXTENTS =
|
_glfw.x11.NET_FRAME_EXTENTS =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
|
||||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
getAtomIfSupported(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||||
|
|
||||||
if (supportedAtoms)
|
if (supportedAtoms)
|
||||||
XFree(supportedAtoms);
|
XFree(supportedAtoms);
|
||||||
@ -665,13 +805,12 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.x11.xkb.group = 0;
|
|
||||||
XkbStateRec state;
|
XkbStateRec state;
|
||||||
if (XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state) == Success)
|
if (XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state) == Success)
|
||||||
{
|
|
||||||
XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);
|
|
||||||
_glfw.x11.xkb.group = (unsigned int)state.group;
|
_glfw.x11.xkb.group = (unsigned int)state.group;
|
||||||
}
|
|
||||||
|
XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify,
|
||||||
|
XkbGroupStateMask, XkbGroupStateMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
@ -712,6 +851,35 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.xshape.handle = _glfw_dlopen("libXext-6.so");
|
||||||
|
#else
|
||||||
|
_glfw.x11.xshape.handle = _glfw_dlopen("libXext.so.6");
|
||||||
|
#endif
|
||||||
|
if (_glfw.x11.xshape.handle)
|
||||||
|
{
|
||||||
|
_glfw.x11.xshape.QueryExtension = (PFN_XShapeQueryExtension)
|
||||||
|
_glfw_dlsym(_glfw.x11.xshape.handle, "XShapeQueryExtension");
|
||||||
|
_glfw.x11.xshape.ShapeCombineRegion = (PFN_XShapeCombineRegion)
|
||||||
|
_glfw_dlsym(_glfw.x11.xshape.handle, "XShapeCombineRegion");
|
||||||
|
_glfw.x11.xshape.QueryVersion = (PFN_XShapeQueryVersion)
|
||||||
|
_glfw_dlsym(_glfw.x11.xshape.handle, "XShapeQueryVersion");
|
||||||
|
_glfw.x11.xshape.ShapeCombineMask = (PFN_XShapeCombineMask)
|
||||||
|
_glfw_dlsym(_glfw.x11.xshape.handle, "XShapeCombineMask");
|
||||||
|
|
||||||
|
if (XShapeQueryExtension(_glfw.x11.display,
|
||||||
|
&_glfw.x11.xshape.errorBase,
|
||||||
|
&_glfw.x11.xshape.eventBase))
|
||||||
|
{
|
||||||
|
if (XShapeQueryVersion(_glfw.x11.display,
|
||||||
|
&_glfw.x11.xshape.major,
|
||||||
|
&_glfw.x11.xshape.minor))
|
||||||
|
{
|
||||||
|
_glfw.x11.xshape.available = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the key code LUT
|
// Update the key code LUT
|
||||||
// FIXME: We should listen to XkbMapNotify events to track changes to
|
// FIXME: We should listen to XkbMapNotify events to track changes to
|
||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
@ -856,6 +1024,9 @@ static Window createHelperWindow(void)
|
|||||||
//
|
//
|
||||||
static int errorHandler(Display *display, XErrorEvent* event)
|
static int errorHandler(Display *display, XErrorEvent* event)
|
||||||
{
|
{
|
||||||
|
if (_glfw.x11.display != display)
|
||||||
|
return 0;
|
||||||
|
|
||||||
_glfw.x11.errorCode = event->error_code;
|
_glfw.x11.errorCode = event->error_code;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -980,6 +1151,8 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateFontCursor");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateFontCursor");
|
||||||
_glfw.x11.xlib.CreateIC = (PFN_XCreateIC)
|
_glfw.x11.xlib.CreateIC = (PFN_XCreateIC)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateIC");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateIC");
|
||||||
|
_glfw.x11.xlib.CreateRegion = (PFN_XCreateRegion)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateRegion");
|
||||||
_glfw.x11.xlib.CreateWindow = (PFN_XCreateWindow)
|
_glfw.x11.xlib.CreateWindow = (PFN_XCreateWindow)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateWindow");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateWindow");
|
||||||
_glfw.x11.xlib.DefineCursor = (PFN_XDefineCursor)
|
_glfw.x11.xlib.DefineCursor = (PFN_XDefineCursor)
|
||||||
@ -990,8 +1163,12 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XDeleteProperty");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDeleteProperty");
|
||||||
_glfw.x11.xlib.DestroyIC = (PFN_XDestroyIC)
|
_glfw.x11.xlib.DestroyIC = (PFN_XDestroyIC)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyIC");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyIC");
|
||||||
|
_glfw.x11.xlib.DestroyRegion = (PFN_XDestroyRegion)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyRegion");
|
||||||
_glfw.x11.xlib.DestroyWindow = (PFN_XDestroyWindow)
|
_glfw.x11.xlib.DestroyWindow = (PFN_XDestroyWindow)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyWindow");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyWindow");
|
||||||
|
_glfw.x11.xlib.DisplayKeycodes = (PFN_XDisplayKeycodes)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDisplayKeycodes");
|
||||||
_glfw.x11.xlib.EventsQueued = (PFN_XEventsQueued)
|
_glfw.x11.xlib.EventsQueued = (PFN_XEventsQueued)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XEventsQueued");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XEventsQueued");
|
||||||
_glfw.x11.xlib.FilterEvent = (PFN_XFilterEvent)
|
_glfw.x11.xlib.FilterEvent = (PFN_XFilterEvent)
|
||||||
@ -1066,6 +1243,8 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XQueryPointer");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XQueryPointer");
|
||||||
_glfw.x11.xlib.RaiseWindow = (PFN_XRaiseWindow)
|
_glfw.x11.xlib.RaiseWindow = (PFN_XRaiseWindow)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XRaiseWindow");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XRaiseWindow");
|
||||||
|
_glfw.x11.xlib.RegisterIMInstantiateCallback = (PFN_XRegisterIMInstantiateCallback)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XRegisterIMInstantiateCallback");
|
||||||
_glfw.x11.xlib.ResizeWindow = (PFN_XResizeWindow)
|
_glfw.x11.xlib.ResizeWindow = (PFN_XResizeWindow)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XResizeWindow");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XResizeWindow");
|
||||||
_glfw.x11.xlib.ResourceManagerString = (PFN_XResourceManagerString)
|
_glfw.x11.xlib.ResourceManagerString = (PFN_XResourceManagerString)
|
||||||
@ -1082,6 +1261,8 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetErrorHandler");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetErrorHandler");
|
||||||
_glfw.x11.xlib.SetICFocus = (PFN_XSetICFocus)
|
_glfw.x11.xlib.SetICFocus = (PFN_XSetICFocus)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetICFocus");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetICFocus");
|
||||||
|
_glfw.x11.xlib.SetIMValues = (PFN_XSetIMValues)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetIMValues");
|
||||||
_glfw.x11.xlib.SetInputFocus = (PFN_XSetInputFocus)
|
_glfw.x11.xlib.SetInputFocus = (PFN_XSetInputFocus)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetInputFocus");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetInputFocus");
|
||||||
_glfw.x11.xlib.SetLocaleModifiers = (PFN_XSetLocaleModifiers)
|
_glfw.x11.xlib.SetLocaleModifiers = (PFN_XSetLocaleModifiers)
|
||||||
@ -1142,11 +1323,16 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmInitialize");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmInitialize");
|
||||||
_glfw.x11.xrm.UniqueQuark = (PFN_XrmUniqueQuark)
|
_glfw.x11.xrm.UniqueQuark = (PFN_XrmUniqueQuark)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmUniqueQuark");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmUniqueQuark");
|
||||||
|
_glfw.x11.xlib.UnregisterIMInstantiateCallback = (PFN_XUnregisterIMInstantiateCallback)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XUnregisterIMInstantiateCallback");
|
||||||
_glfw.x11.xlib.utf8LookupString = (PFN_Xutf8LookupString)
|
_glfw.x11.xlib.utf8LookupString = (PFN_Xutf8LookupString)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "Xutf8LookupString");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "Xutf8LookupString");
|
||||||
_glfw.x11.xlib.utf8SetWMProperties = (PFN_Xutf8SetWMProperties)
|
_glfw.x11.xlib.utf8SetWMProperties = (PFN_Xutf8SetWMProperties)
|
||||||
_glfw_dlsym(_glfw.x11.xlib.handle, "Xutf8SetWMProperties");
|
_glfw_dlsym(_glfw.x11.xlib.handle, "Xutf8SetWMProperties");
|
||||||
|
|
||||||
|
if (_glfw.x11.xlib.utf8LookupString && _glfw.x11.xlib.utf8SetWMProperties)
|
||||||
|
_glfw.x11.xlib.utf8 = GLFW_TRUE;
|
||||||
|
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
XrmInitialize();
|
XrmInitialize();
|
||||||
|
|
||||||
@ -1180,26 +1366,17 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw.x11.helperWindowHandle = createHelperWindow();
|
_glfw.x11.helperWindowHandle = createHelperWindow();
|
||||||
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
||||||
|
|
||||||
if (XSupportsLocale())
|
if (XSupportsLocale() && _glfw.x11.xlib.utf8)
|
||||||
{
|
{
|
||||||
XSetLocaleModifiers("");
|
XSetLocaleModifiers("");
|
||||||
|
|
||||||
_glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL);
|
// If an IM is already present our callback will be called right away
|
||||||
if (_glfw.x11.im)
|
XRegisterIMInstantiateCallback(_glfw.x11.display,
|
||||||
{
|
NULL, NULL, NULL,
|
||||||
if (!hasUsableInputMethodStyle())
|
inputMethodInstantiateCallback,
|
||||||
{
|
NULL);
|
||||||
XCloseIM(_glfw.x11.im);
|
|
||||||
_glfw.x11.im = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
_glfwPollMonitorsX11();
|
_glfwPollMonitorsX11();
|
||||||
@ -1229,6 +1406,11 @@ void _glfwPlatformTerminate(void)
|
|||||||
free(_glfw.x11.primarySelectionString);
|
free(_glfw.x11.primarySelectionString);
|
||||||
free(_glfw.x11.clipboardString);
|
free(_glfw.x11.clipboardString);
|
||||||
|
|
||||||
|
XUnregisterIMInstantiateCallback(_glfw.x11.display,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
inputMethodInstantiateCallback,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (_glfw.x11.im)
|
if (_glfw.x11.im)
|
||||||
{
|
{
|
||||||
XCloseIM(_glfw.x11.im);
|
XCloseIM(_glfw.x11.im);
|
||||||
@ -1288,10 +1470,6 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateGLX();
|
_glfwTerminateGLX();
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
_glfwTerminateJoysticksLinux();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_glfw.x11.xlib.handle)
|
if (_glfw.x11.xlib.handle)
|
||||||
{
|
{
|
||||||
_glfw_dlclose(_glfw.x11.xlib.handle);
|
_glfw_dlclose(_glfw.x11.xlib.handle);
|
||||||
|
@ -164,7 +164,7 @@ void _glfwPollMonitorsX11(void)
|
|||||||
if (widthMM <= 0 || heightMM <= 0)
|
if (widthMM <= 0 || heightMM <= 0)
|
||||||
{
|
{
|
||||||
// HACK: If RandR does not provide a physical size, assume the
|
// HACK: If RandR does not provide a physical size, assume the
|
||||||
// X11 default 96 DPI and calcuate from the CRTC viewport
|
// X11 default 96 DPI and calculate from the CRTC viewport
|
||||||
// NOTE: These members are affected by rotation, unlike the mode
|
// NOTE: These members are affected by rotation, unlike the mode
|
||||||
// info and output info members
|
// info and output info members
|
||||||
widthMM = (int) (ci->width * 25.4f / 96.f);
|
widthMM = (int) (ci->width * 25.4f / 96.f);
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
// The XInput extension provides raw mouse motion input
|
// The XInput extension provides raw mouse motion input
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
|
|
||||||
|
// The Shape extension provides custom window shapes
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
|
||||||
typedef XClassHint* (* PFN_XAllocClassHint)(void);
|
typedef XClassHint* (* PFN_XAllocClassHint)(void);
|
||||||
typedef XSizeHints* (* PFN_XAllocSizeHints)(void);
|
typedef XSizeHints* (* PFN_XAllocSizeHints)(void);
|
||||||
typedef XWMHints* (* PFN_XAllocWMHints)(void);
|
typedef XWMHints* (* PFN_XAllocWMHints)(void);
|
||||||
@ -61,12 +64,15 @@ typedef int (* PFN_XConvertSelection)(Display*,Atom,Atom,Atom,Window,Time);
|
|||||||
typedef Colormap (* PFN_XCreateColormap)(Display*,Window,Visual*,int);
|
typedef Colormap (* PFN_XCreateColormap)(Display*,Window,Visual*,int);
|
||||||
typedef Cursor (* PFN_XCreateFontCursor)(Display*,unsigned int);
|
typedef Cursor (* PFN_XCreateFontCursor)(Display*,unsigned int);
|
||||||
typedef XIC (* PFN_XCreateIC)(XIM,...);
|
typedef XIC (* PFN_XCreateIC)(XIM,...);
|
||||||
|
typedef Region (* PFN_XCreateRegion)(void);
|
||||||
typedef Window (* PFN_XCreateWindow)(Display*,Window,int,int,unsigned int,unsigned int,unsigned int,int,unsigned int,Visual*,unsigned long,XSetWindowAttributes*);
|
typedef Window (* PFN_XCreateWindow)(Display*,Window,int,int,unsigned int,unsigned int,unsigned int,int,unsigned int,Visual*,unsigned long,XSetWindowAttributes*);
|
||||||
typedef int (* PFN_XDefineCursor)(Display*,Window,Cursor);
|
typedef int (* PFN_XDefineCursor)(Display*,Window,Cursor);
|
||||||
typedef int (* PFN_XDeleteContext)(Display*,XID,XContext);
|
typedef int (* PFN_XDeleteContext)(Display*,XID,XContext);
|
||||||
typedef int (* PFN_XDeleteProperty)(Display*,Window,Atom);
|
typedef int (* PFN_XDeleteProperty)(Display*,Window,Atom);
|
||||||
typedef void (* PFN_XDestroyIC)(XIC);
|
typedef void (* PFN_XDestroyIC)(XIC);
|
||||||
|
typedef int (* PFN_XDestroyRegion)(Region);
|
||||||
typedef int (* PFN_XDestroyWindow)(Display*,Window);
|
typedef int (* PFN_XDestroyWindow)(Display*,Window);
|
||||||
|
typedef int (* PFN_XDisplayKeycodes)(Display*,int*,int*);
|
||||||
typedef int (* PFN_XEventsQueued)(Display*,int);
|
typedef int (* PFN_XEventsQueued)(Display*,int);
|
||||||
typedef Bool (* PFN_XFilterEvent)(XEvent*,Window);
|
typedef Bool (* PFN_XFilterEvent)(XEvent*,Window);
|
||||||
typedef int (* PFN_XFindContext)(Display*,XID,XContext,XPointer*);
|
typedef int (* PFN_XFindContext)(Display*,XID,XContext,XPointer*);
|
||||||
@ -104,6 +110,7 @@ typedef int (* PFN_XPending)(Display*);
|
|||||||
typedef Bool (* PFN_XQueryExtension)(Display*,const char*,int*,int*,int*);
|
typedef Bool (* PFN_XQueryExtension)(Display*,const char*,int*,int*,int*);
|
||||||
typedef Bool (* PFN_XQueryPointer)(Display*,Window,Window*,Window*,int*,int*,int*,int*,unsigned int*);
|
typedef Bool (* PFN_XQueryPointer)(Display*,Window,Window*,Window*,int*,int*,int*,int*,unsigned int*);
|
||||||
typedef int (* PFN_XRaiseWindow)(Display*,Window);
|
typedef int (* PFN_XRaiseWindow)(Display*,Window);
|
||||||
|
typedef Bool (* PFN_XRegisterIMInstantiateCallback)(Display*,void*,char*,char*,XIDProc,XPointer);
|
||||||
typedef int (* PFN_XResizeWindow)(Display*,Window,unsigned int,unsigned int);
|
typedef int (* PFN_XResizeWindow)(Display*,Window,unsigned int,unsigned int);
|
||||||
typedef char* (* PFN_XResourceManagerString)(Display*);
|
typedef char* (* PFN_XResourceManagerString)(Display*);
|
||||||
typedef int (* PFN_XSaveContext)(Display*,XID,XContext,const char*);
|
typedef int (* PFN_XSaveContext)(Display*,XID,XContext,const char*);
|
||||||
@ -112,6 +119,7 @@ typedef Status (* PFN_XSendEvent)(Display*,Window,Bool,long,XEvent*);
|
|||||||
typedef int (* PFN_XSetClassHint)(Display*,Window,XClassHint*);
|
typedef int (* PFN_XSetClassHint)(Display*,Window,XClassHint*);
|
||||||
typedef XErrorHandler (* PFN_XSetErrorHandler)(XErrorHandler);
|
typedef XErrorHandler (* PFN_XSetErrorHandler)(XErrorHandler);
|
||||||
typedef void (* PFN_XSetICFocus)(XIC);
|
typedef void (* PFN_XSetICFocus)(XIC);
|
||||||
|
typedef char* (* PFN_XSetIMValues)(XIM,...);
|
||||||
typedef int (* PFN_XSetInputFocus)(Display*,Window,int,Time);
|
typedef int (* PFN_XSetInputFocus)(Display*,Window,int,Time);
|
||||||
typedef char* (* PFN_XSetLocaleModifiers)(const char*);
|
typedef char* (* PFN_XSetLocaleModifiers)(const char*);
|
||||||
typedef int (* PFN_XSetScreenSaver)(Display*,int,int,int,int);
|
typedef int (* PFN_XSetScreenSaver)(Display*,int,int,int,int);
|
||||||
@ -142,6 +150,7 @@ typedef Bool (* PFN_XrmGetResource)(XrmDatabase,const char*,const char*,char**,X
|
|||||||
typedef XrmDatabase (* PFN_XrmGetStringDatabase)(const char*);
|
typedef XrmDatabase (* PFN_XrmGetStringDatabase)(const char*);
|
||||||
typedef void (* PFN_XrmInitialize)(void);
|
typedef void (* PFN_XrmInitialize)(void);
|
||||||
typedef XrmQuark (* PFN_XrmUniqueQuark)(void);
|
typedef XrmQuark (* PFN_XrmUniqueQuark)(void);
|
||||||
|
typedef Bool (* PFN_XUnregisterIMInstantiateCallback)(Display*,void*,char*,char*,XIDProc,XPointer);
|
||||||
typedef int (* PFN_Xutf8LookupString)(XIC,XKeyPressedEvent*,char*,int,KeySym*,Status*);
|
typedef int (* PFN_Xutf8LookupString)(XIC,XKeyPressedEvent*,char*,int,KeySym*,Status*);
|
||||||
typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char*,char**,int,XSizeHints*,XWMHints*,XClassHint*);
|
typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char*,char**,int,XSizeHints*,XWMHints*,XClassHint*);
|
||||||
#define XAllocClassHint _glfw.x11.xlib.AllocClassHint
|
#define XAllocClassHint _glfw.x11.xlib.AllocClassHint
|
||||||
@ -157,12 +166,15 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
|
|||||||
#define XCreateColormap _glfw.x11.xlib.CreateColormap
|
#define XCreateColormap _glfw.x11.xlib.CreateColormap
|
||||||
#define XCreateFontCursor _glfw.x11.xlib.CreateFontCursor
|
#define XCreateFontCursor _glfw.x11.xlib.CreateFontCursor
|
||||||
#define XCreateIC _glfw.x11.xlib.CreateIC
|
#define XCreateIC _glfw.x11.xlib.CreateIC
|
||||||
|
#define XCreateRegion _glfw.x11.xlib.CreateRegion
|
||||||
#define XCreateWindow _glfw.x11.xlib.CreateWindow
|
#define XCreateWindow _glfw.x11.xlib.CreateWindow
|
||||||
#define XDefineCursor _glfw.x11.xlib.DefineCursor
|
#define XDefineCursor _glfw.x11.xlib.DefineCursor
|
||||||
#define XDeleteContext _glfw.x11.xlib.DeleteContext
|
#define XDeleteContext _glfw.x11.xlib.DeleteContext
|
||||||
#define XDeleteProperty _glfw.x11.xlib.DeleteProperty
|
#define XDeleteProperty _glfw.x11.xlib.DeleteProperty
|
||||||
#define XDestroyIC _glfw.x11.xlib.DestroyIC
|
#define XDestroyIC _glfw.x11.xlib.DestroyIC
|
||||||
|
#define XDestroyRegion _glfw.x11.xlib.DestroyRegion
|
||||||
#define XDestroyWindow _glfw.x11.xlib.DestroyWindow
|
#define XDestroyWindow _glfw.x11.xlib.DestroyWindow
|
||||||
|
#define XDisplayKeycodes _glfw.x11.xlib.DisplayKeycodes
|
||||||
#define XEventsQueued _glfw.x11.xlib.EventsQueued
|
#define XEventsQueued _glfw.x11.xlib.EventsQueued
|
||||||
#define XFilterEvent _glfw.x11.xlib.FilterEvent
|
#define XFilterEvent _glfw.x11.xlib.FilterEvent
|
||||||
#define XFindContext _glfw.x11.xlib.FindContext
|
#define XFindContext _glfw.x11.xlib.FindContext
|
||||||
@ -200,6 +212,7 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
|
|||||||
#define XQueryExtension _glfw.x11.xlib.QueryExtension
|
#define XQueryExtension _glfw.x11.xlib.QueryExtension
|
||||||
#define XQueryPointer _glfw.x11.xlib.QueryPointer
|
#define XQueryPointer _glfw.x11.xlib.QueryPointer
|
||||||
#define XRaiseWindow _glfw.x11.xlib.RaiseWindow
|
#define XRaiseWindow _glfw.x11.xlib.RaiseWindow
|
||||||
|
#define XRegisterIMInstantiateCallback _glfw.x11.xlib.RegisterIMInstantiateCallback
|
||||||
#define XResizeWindow _glfw.x11.xlib.ResizeWindow
|
#define XResizeWindow _glfw.x11.xlib.ResizeWindow
|
||||||
#define XResourceManagerString _glfw.x11.xlib.ResourceManagerString
|
#define XResourceManagerString _glfw.x11.xlib.ResourceManagerString
|
||||||
#define XSaveContext _glfw.x11.xlib.SaveContext
|
#define XSaveContext _glfw.x11.xlib.SaveContext
|
||||||
@ -208,6 +221,7 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
|
|||||||
#define XSetClassHint _glfw.x11.xlib.SetClassHint
|
#define XSetClassHint _glfw.x11.xlib.SetClassHint
|
||||||
#define XSetErrorHandler _glfw.x11.xlib.SetErrorHandler
|
#define XSetErrorHandler _glfw.x11.xlib.SetErrorHandler
|
||||||
#define XSetICFocus _glfw.x11.xlib.SetICFocus
|
#define XSetICFocus _glfw.x11.xlib.SetICFocus
|
||||||
|
#define XSetIMValues _glfw.x11.xlib.SetIMValues
|
||||||
#define XSetInputFocus _glfw.x11.xlib.SetInputFocus
|
#define XSetInputFocus _glfw.x11.xlib.SetInputFocus
|
||||||
#define XSetLocaleModifiers _glfw.x11.xlib.SetLocaleModifiers
|
#define XSetLocaleModifiers _glfw.x11.xlib.SetLocaleModifiers
|
||||||
#define XSetScreenSaver _glfw.x11.xlib.SetScreenSaver
|
#define XSetScreenSaver _glfw.x11.xlib.SetScreenSaver
|
||||||
@ -238,6 +252,7 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
|
|||||||
#define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase
|
#define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase
|
||||||
#define XrmInitialize _glfw.x11.xrm.Initialize
|
#define XrmInitialize _glfw.x11.xrm.Initialize
|
||||||
#define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark
|
#define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark
|
||||||
|
#define XUnregisterIMInstantiateCallback _glfw.x11.xlib.UnregisterIMInstantiateCallback
|
||||||
#define Xutf8LookupString _glfw.x11.xlib.utf8LookupString
|
#define Xutf8LookupString _glfw.x11.xlib.utf8LookupString
|
||||||
#define Xutf8SetWMProperties _glfw.x11.xlib.utf8SetWMProperties
|
#define Xutf8SetWMProperties _glfw.x11.xlib.utf8SetWMProperties
|
||||||
|
|
||||||
@ -323,6 +338,16 @@ typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const
|
|||||||
#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
|
#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
|
||||||
#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
|
#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
|
||||||
|
|
||||||
|
typedef Bool (* PFN_XShapeQueryExtension)(Display*,int*,int*);
|
||||||
|
typedef Status (* PFN_XShapeQueryVersion)(Display*dpy,int*,int*);
|
||||||
|
typedef void (* PFN_XShapeCombineRegion)(Display*,Window,int,int,int,Region,int);
|
||||||
|
typedef void (* PFN_XShapeCombineMask)(Display*,Window,int,int,int,Pixmap,int);
|
||||||
|
|
||||||
|
#define XShapeQueryExtension _glfw.x11.xshape.QueryExtension
|
||||||
|
#define XShapeQueryVersion _glfw.x11.xshape.QueryVersion
|
||||||
|
#define XShapeCombineRegion _glfw.x11.xshape.ShapeCombineRegion
|
||||||
|
#define XShapeCombineMask _glfw.x11.xshape.ShapeCombineMask
|
||||||
|
|
||||||
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||||
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
@ -353,8 +378,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
|||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "xkb_unicode.h"
|
#include "xkb_unicode.h"
|
||||||
#include "glx_context.h"
|
#include "glx_context.h"
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#include "linux_joystick.h"
|
#include "linux_joystick.h"
|
||||||
#else
|
#else
|
||||||
@ -365,9 +388,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
|||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
||||||
@ -399,8 +419,9 @@ typedef struct _GLFWwindowX11
|
|||||||
// The last position the cursor was warped to by GLFW
|
// The last position the cursor was warped to by GLFW
|
||||||
int warpCursorPosX, warpCursorPosY;
|
int warpCursorPosX, warpCursorPosY;
|
||||||
|
|
||||||
// The time of the last KeyPress event
|
// The time of the last KeyPress event per keycode, for discarding
|
||||||
Time lastKeyTime;
|
// duplicate key events generated for some keys by ibus
|
||||||
|
Time keyPressTimes[256];
|
||||||
|
|
||||||
} _GLFWwindowX11;
|
} _GLFWwindowX11;
|
||||||
|
|
||||||
@ -497,6 +518,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
void* handle;
|
void* handle;
|
||||||
|
GLFWbool utf8;
|
||||||
PFN_XAllocClassHint AllocClassHint;
|
PFN_XAllocClassHint AllocClassHint;
|
||||||
PFN_XAllocSizeHints AllocSizeHints;
|
PFN_XAllocSizeHints AllocSizeHints;
|
||||||
PFN_XAllocWMHints AllocWMHints;
|
PFN_XAllocWMHints AllocWMHints;
|
||||||
@ -510,12 +532,15 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XCreateColormap CreateColormap;
|
PFN_XCreateColormap CreateColormap;
|
||||||
PFN_XCreateFontCursor CreateFontCursor;
|
PFN_XCreateFontCursor CreateFontCursor;
|
||||||
PFN_XCreateIC CreateIC;
|
PFN_XCreateIC CreateIC;
|
||||||
|
PFN_XCreateRegion CreateRegion;
|
||||||
PFN_XCreateWindow CreateWindow;
|
PFN_XCreateWindow CreateWindow;
|
||||||
PFN_XDefineCursor DefineCursor;
|
PFN_XDefineCursor DefineCursor;
|
||||||
PFN_XDeleteContext DeleteContext;
|
PFN_XDeleteContext DeleteContext;
|
||||||
PFN_XDeleteProperty DeleteProperty;
|
PFN_XDeleteProperty DeleteProperty;
|
||||||
PFN_XDestroyIC DestroyIC;
|
PFN_XDestroyIC DestroyIC;
|
||||||
|
PFN_XDestroyRegion DestroyRegion;
|
||||||
PFN_XDestroyWindow DestroyWindow;
|
PFN_XDestroyWindow DestroyWindow;
|
||||||
|
PFN_XDisplayKeycodes DisplayKeycodes;
|
||||||
PFN_XEventsQueued EventsQueued;
|
PFN_XEventsQueued EventsQueued;
|
||||||
PFN_XFilterEvent FilterEvent;
|
PFN_XFilterEvent FilterEvent;
|
||||||
PFN_XFindContext FindContext;
|
PFN_XFindContext FindContext;
|
||||||
@ -553,6 +578,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XQueryExtension QueryExtension;
|
PFN_XQueryExtension QueryExtension;
|
||||||
PFN_XQueryPointer QueryPointer;
|
PFN_XQueryPointer QueryPointer;
|
||||||
PFN_XRaiseWindow RaiseWindow;
|
PFN_XRaiseWindow RaiseWindow;
|
||||||
|
PFN_XRegisterIMInstantiateCallback RegisterIMInstantiateCallback;
|
||||||
PFN_XResizeWindow ResizeWindow;
|
PFN_XResizeWindow ResizeWindow;
|
||||||
PFN_XResourceManagerString ResourceManagerString;
|
PFN_XResourceManagerString ResourceManagerString;
|
||||||
PFN_XSaveContext SaveContext;
|
PFN_XSaveContext SaveContext;
|
||||||
@ -561,6 +587,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XSetClassHint SetClassHint;
|
PFN_XSetClassHint SetClassHint;
|
||||||
PFN_XSetErrorHandler SetErrorHandler;
|
PFN_XSetErrorHandler SetErrorHandler;
|
||||||
PFN_XSetICFocus SetICFocus;
|
PFN_XSetICFocus SetICFocus;
|
||||||
|
PFN_XSetIMValues SetIMValues;
|
||||||
PFN_XSetInputFocus SetInputFocus;
|
PFN_XSetInputFocus SetInputFocus;
|
||||||
PFN_XSetLocaleModifiers SetLocaleModifiers;
|
PFN_XSetLocaleModifiers SetLocaleModifiers;
|
||||||
PFN_XSetScreenSaver SetScreenSaver;
|
PFN_XSetScreenSaver SetScreenSaver;
|
||||||
@ -577,6 +604,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XUnsetICFocus UnsetICFocus;
|
PFN_XUnsetICFocus UnsetICFocus;
|
||||||
PFN_XVisualIDFromVisual VisualIDFromVisual;
|
PFN_XVisualIDFromVisual VisualIDFromVisual;
|
||||||
PFN_XWarpPointer WarpPointer;
|
PFN_XWarpPointer WarpPointer;
|
||||||
|
PFN_XUnregisterIMInstantiateCallback UnregisterIMInstantiateCallback;
|
||||||
PFN_Xutf8LookupString utf8LookupString;
|
PFN_Xutf8LookupString utf8LookupString;
|
||||||
PFN_Xutf8SetWMProperties utf8SetWMProperties;
|
PFN_Xutf8SetWMProperties utf8SetWMProperties;
|
||||||
} xlib;
|
} xlib;
|
||||||
@ -711,6 +739,19 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XRenderFindVisualFormat FindVisualFormat;
|
PFN_XRenderFindVisualFormat FindVisualFormat;
|
||||||
} xrender;
|
} xrender;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
PFN_XShapeQueryExtension QueryExtension;
|
||||||
|
PFN_XShapeCombineRegion ShapeCombineRegion;
|
||||||
|
PFN_XShapeQueryVersion QueryVersion;
|
||||||
|
PFN_XShapeCombineMask ShapeCombineMask;
|
||||||
|
} xshape;
|
||||||
|
|
||||||
} _GLFWlibraryX11;
|
} _GLFWlibraryX11;
|
||||||
|
|
||||||
// X11-specific per-monitor data
|
// X11-specific per-monitor data
|
||||||
@ -753,4 +794,5 @@ void _glfwReleaseErrorHandlerX11(void);
|
|||||||
void _glfwInputErrorX11(int error, const char* message);
|
void _glfwInputErrorX11(int error, const char* message);
|
||||||
|
|
||||||
void _glfwPushSelectionToManagerX11(void);
|
void _glfwPushSelectionToManagerX11(void);
|
||||||
|
void _glfwCreateInputContextX11(_GLFWwindow* window);
|
||||||
|
|
||||||
|
235
src/x11_window.c
235
src/x11_window.c
@ -463,7 +463,6 @@ static size_t encodeUTF8(char* s, unsigned int ch)
|
|||||||
// Decode a Unicode code point from a UTF-8 stream
|
// Decode a Unicode code point from a UTF-8 stream
|
||||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||||
//
|
//
|
||||||
#if defined(X_HAVE_UTF8_STRING)
|
|
||||||
static unsigned int decodeUTF8(const char** s)
|
static unsigned int decodeUTF8(const char** s)
|
||||||
{
|
{
|
||||||
unsigned int ch = 0, count = 0;
|
unsigned int ch = 0, count = 0;
|
||||||
@ -483,7 +482,6 @@ static unsigned int decodeUTF8(const char** s)
|
|||||||
assert(count <= 6);
|
assert(count <= 6);
|
||||||
return ch - offsets[count - 1];
|
return ch - offsets[count - 1];
|
||||||
}
|
}
|
||||||
#endif /*X_HAVE_UTF8_STRING*/
|
|
||||||
|
|
||||||
// Convert the specified Latin-1 string to UTF-8
|
// Convert the specified Latin-1 string to UTF-8
|
||||||
//
|
//
|
||||||
@ -590,6 +588,14 @@ static void enableCursor(_GLFWwindow* window)
|
|||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear its handle when the input context has been destroyed
|
||||||
|
//
|
||||||
|
static void inputContextDestroyCallback(XIC ic, XPointer clientData, XPointer callData)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) clientData;
|
||||||
|
window->x11.ic = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the X11 window (and its colormap)
|
// Create the X11 window (and its colormap)
|
||||||
//
|
//
|
||||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||||
@ -768,27 +774,10 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
PropModeReplace, (unsigned char*) &version, 1);
|
PropModeReplace, (unsigned char*) &version, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
|
||||||
|
|
||||||
if (_glfw.x11.im)
|
if (_glfw.x11.im)
|
||||||
{
|
_glfwCreateInputContextX11(window);
|
||||||
window->x11.ic = XCreateIC(_glfw.x11.im,
|
|
||||||
XNInputStyle,
|
|
||||||
XIMPreeditNothing | XIMStatusNothing,
|
|
||||||
XNClientWindow,
|
|
||||||
window->x11.handle,
|
|
||||||
XNFocusWindow,
|
|
||||||
window->x11.handle,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->x11.ic)
|
|
||||||
{
|
|
||||||
unsigned long filter = 0;
|
|
||||||
if (XGetICValues(window->x11.ic, XNFilterEvents, &filter, NULL) == NULL)
|
|
||||||
XSelectInput(_glfw.x11.display, window->x11.handle, wa.event_mask | filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
||||||
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
|
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
|
||||||
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
|
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
|
||||||
|
|
||||||
@ -1173,8 +1162,7 @@ static void processEvent(XEvent *event)
|
|||||||
if (event->type == KeyPress || event->type == KeyRelease)
|
if (event->type == KeyPress || event->type == KeyRelease)
|
||||||
keycode = event->xkey.keycode;
|
keycode = event->xkey.keycode;
|
||||||
|
|
||||||
if (_glfw.x11.im)
|
filtered = XFilterEvent(event, None);
|
||||||
filtered = XFilterEvent(event, None);
|
|
||||||
|
|
||||||
if (_glfw.x11.randr.available)
|
if (_glfw.x11.randr.available)
|
||||||
{
|
{
|
||||||
@ -1195,6 +1183,8 @@ static void processEvent(XEvent *event)
|
|||||||
{
|
{
|
||||||
_glfw.x11.xkb.group = ((XkbEvent*) event)->state.group;
|
_glfw.x11.xkb.group = ((XkbEvent*) event)->state.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1273,23 +1263,26 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
if (window->x11.ic)
|
if (window->x11.ic)
|
||||||
{
|
{
|
||||||
// HACK: Ignore duplicate key press events generated by ibus
|
// HACK: Do not report the key press events duplicated by XIM
|
||||||
// These have the same timestamp as the original event
|
// Duplicate key releases are filtered out implicitly by
|
||||||
// Corresponding release events are filtered out
|
// the GLFW key repeat logic in _glfwInputKey
|
||||||
// implicitly by the GLFW key repeat logic
|
// A timestamp per key is used to handle simultaneous keys
|
||||||
if (window->x11.lastKeyTime < event->xkey.time)
|
// NOTE: Always allow the first event for each key through
|
||||||
|
// (the server never sends a timestamp of zero)
|
||||||
|
// NOTE: Timestamp difference is compared to handle wrap-around
|
||||||
|
Time diff = event->xkey.time - window->x11.keyPressTimes[keycode];
|
||||||
|
if (diff == event->xkey.time || (diff > 0 && diff < (1 << 31)))
|
||||||
{
|
{
|
||||||
if (keycode)
|
if (keycode)
|
||||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||||
|
|
||||||
window->x11.lastKeyTime = event->xkey.time;
|
window->x11.keyPressTimes[keycode] = event->xkey.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filtered)
|
if (!filtered)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
Status status;
|
Status status;
|
||||||
#if defined(X_HAVE_UTF8_STRING)
|
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
char* chars = buffer;
|
char* chars = buffer;
|
||||||
|
|
||||||
@ -1314,33 +1307,6 @@ static void processEvent(XEvent *event)
|
|||||||
while (c - chars < count)
|
while (c - chars < count)
|
||||||
_glfwInputChar(window, decodeUTF8(&c), mods, plain);
|
_glfwInputChar(window, decodeUTF8(&c), mods, plain);
|
||||||
}
|
}
|
||||||
#else /*X_HAVE_UTF8_STRING*/
|
|
||||||
wchar_t buffer[16];
|
|
||||||
wchar_t* chars = buffer;
|
|
||||||
|
|
||||||
count = XwcLookupString(window->x11.ic,
|
|
||||||
&event->xkey,
|
|
||||||
buffer,
|
|
||||||
sizeof(buffer) / sizeof(wchar_t),
|
|
||||||
NULL,
|
|
||||||
&status);
|
|
||||||
|
|
||||||
if (status == XBufferOverflow)
|
|
||||||
{
|
|
||||||
chars = calloc(count, sizeof(wchar_t));
|
|
||||||
count = XwcLookupString(window->x11.ic,
|
|
||||||
&event->xkey,
|
|
||||||
chars, count,
|
|
||||||
NULL, &status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == XLookupChars || status == XLookupBoth)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
_glfwInputChar(window, chars[i], mods, plain);
|
|
||||||
}
|
|
||||||
#endif /*X_HAVE_UTF8_STRING*/
|
|
||||||
|
|
||||||
if (chars != buffer)
|
if (chars != buffer)
|
||||||
free(chars);
|
free(chars);
|
||||||
@ -1557,6 +1523,8 @@ static void processEvent(XEvent *event)
|
|||||||
// the position into root (screen) coordinates
|
// the position into root (screen) coordinates
|
||||||
if (!event->xany.send_event && window->x11.parent != _glfw.x11.root)
|
if (!event->xany.send_event && window->x11.parent != _glfw.x11.root)
|
||||||
{
|
{
|
||||||
|
_glfwGrabErrorHandlerX11();
|
||||||
|
|
||||||
Window dummy;
|
Window dummy;
|
||||||
XTranslateCoordinates(_glfw.x11.display,
|
XTranslateCoordinates(_glfw.x11.display,
|
||||||
window->x11.parent,
|
window->x11.parent,
|
||||||
@ -1564,6 +1532,10 @@ static void processEvent(XEvent *event)
|
|||||||
xpos, ypos,
|
xpos, ypos,
|
||||||
&xpos, &ypos,
|
&xpos, &ypos,
|
||||||
&dummy);
|
&dummy);
|
||||||
|
|
||||||
|
_glfwReleaseErrorHandlerX11();
|
||||||
|
if (_glfw.x11.errorCode == BadWindow)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xpos != window->x11.xpos || ypos != window->x11.ypos)
|
if (xpos != window->x11.xpos || ypos != window->x11.ypos)
|
||||||
@ -1961,6 +1933,38 @@ void _glfwPushSelectionToManagerX11(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwCreateInputContextX11(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
XIMCallback callback;
|
||||||
|
callback.callback = (XIMProc) inputContextDestroyCallback;
|
||||||
|
callback.client_data = (XPointer) window;
|
||||||
|
|
||||||
|
window->x11.ic = XCreateIC(_glfw.x11.im,
|
||||||
|
XNInputStyle,
|
||||||
|
XIMPreeditNothing | XIMStatusNothing,
|
||||||
|
XNClientWindow,
|
||||||
|
window->x11.handle,
|
||||||
|
XNFocusWindow,
|
||||||
|
window->x11.handle,
|
||||||
|
XNDestroyCallback,
|
||||||
|
&callback,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (window->x11.ic)
|
||||||
|
{
|
||||||
|
XWindowAttributes attribs;
|
||||||
|
XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs);
|
||||||
|
|
||||||
|
unsigned long filter = 0;
|
||||||
|
if (XGetICValues(window->x11.ic, XNFilterEvents, &filter, NULL) == NULL)
|
||||||
|
{
|
||||||
|
XSelectInput(_glfw.x11.display,
|
||||||
|
window->x11.handle,
|
||||||
|
attribs.your_event_mask | filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -1971,7 +1975,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
Visual* visual;
|
Visual* visual = NULL;
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
@ -1997,8 +2001,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_NO_API ||
|
if (!visual)
|
||||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
{
|
||||||
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
||||||
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
|
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
|
||||||
@ -2073,21 +2076,14 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||||
{
|
{
|
||||||
#if defined(X_HAVE_UTF8_STRING)
|
if (_glfw.x11.xlib.utf8)
|
||||||
Xutf8SetWMProperties(_glfw.x11.display,
|
{
|
||||||
window->x11.handle,
|
Xutf8SetWMProperties(_glfw.x11.display,
|
||||||
title, title,
|
window->x11.handle,
|
||||||
NULL, 0,
|
title, title,
|
||||||
NULL, NULL, NULL);
|
NULL, 0,
|
||||||
#else
|
NULL, NULL, NULL);
|
||||||
// This may be a slightly better fallback than using XStoreName and
|
}
|
||||||
// XSetIconName, which always store their arguments using STRING
|
|
||||||
XmbSetWMProperties(_glfw.x11.display,
|
|
||||||
window->x11.handle,
|
|
||||||
title, title,
|
|
||||||
NULL, 0,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
_glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8,
|
_glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8,
|
||||||
@ -2580,13 +2576,19 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
|||||||
int rootX, rootY, childX, childY;
|
int rootX, rootY, childX, childY;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
|
|
||||||
if (!XQueryPointer(_glfw.x11.display, w,
|
_glfwGrabErrorHandlerX11();
|
||||||
&root, &w, &rootX, &rootY, &childX, &childY, &mask))
|
|
||||||
{
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w == window->x11.handle)
|
const Bool result = XQueryPointer(_glfw.x11.display, w,
|
||||||
|
&root, &w, &rootX, &rootY,
|
||||||
|
&childX, &childY, &mask);
|
||||||
|
|
||||||
|
_glfwReleaseErrorHandlerX11();
|
||||||
|
|
||||||
|
if (_glfw.x11.errorCode == BadWindow)
|
||||||
|
w = _glfw.x11.root;
|
||||||
|
else if (!result)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
else if (w == window->x11.handle)
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2700,6 +2702,25 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
XFlush(_glfw.x11.display);
|
XFlush(_glfw.x11.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
if (!_glfw.x11.xshape.available)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
Region region = XCreateRegion();
|
||||||
|
XShapeCombineRegion(_glfw.x11.display, window->x11.handle,
|
||||||
|
ShapeInput, 0, 0, region, ShapeSet);
|
||||||
|
XDestroyRegion(region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XShapeCombineMask(_glfw.x11.display, window->x11.handle,
|
||||||
|
ShapeInput, 0, 0, None, ShapeSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
float opacity = 1.f;
|
float opacity = 1.f;
|
||||||
@ -2755,7 +2776,8 @@ void _glfwPlatformPollEvents(void)
|
|||||||
_GLFWwindow* window;
|
_GLFWwindow* window;
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
_glfwDetectJoystickConnectionLinux();
|
if (_glfw.joysticksInitialized)
|
||||||
|
_glfwDetectJoystickConnectionLinux();
|
||||||
#endif
|
#endif
|
||||||
XPending(_glfw.x11.display);
|
XPending(_glfw.x11.display);
|
||||||
|
|
||||||
@ -3019,6 +3041,55 @@ const char* _glfwPlatformGetClipboardString(void)
|
|||||||
return getSelectionString(_glfw.x11.CLIPBOARD);
|
return getSelectionString(_glfw.x11.CLIPBOARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle)
|
||||||
|
{
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_opengl)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.ANGLE_platform_angle_vulkan)
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN)
|
||||||
|
type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
{
|
||||||
|
*attribs = calloc(5, sizeof(EGLint));
|
||||||
|
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
|
||||||
|
(*attribs)[1] = type;
|
||||||
|
(*attribs)[2] = EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE;
|
||||||
|
(*attribs)[3] = EGL_PLATFORM_X11_EXT;
|
||||||
|
(*attribs)[4] = EGL_NONE;
|
||||||
|
return EGL_PLATFORM_ANGLE_ANGLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_x11)
|
||||||
|
return EGL_PLATFORM_X11_EXT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
|
||||||
|
{
|
||||||
|
return _glfw.x11.display;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.platform)
|
||||||
|
return &window->x11.handle;
|
||||||
|
else
|
||||||
|
return (EGLNativeWindowType) window->x11.handle;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (!_glfw.vk.KHR_surface)
|
if (!_glfw.vk.KHR_surface)
|
||||||
|
@ -34,13 +34,12 @@ add_executable(gamma WIN32 MACOSX_BUNDLE gamma.c ${GLAD_GL})
|
|||||||
add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD_GL})
|
add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD_GL})
|
||||||
add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD_GL})
|
add_executable(inputlag WIN32 MACOSX_BUNDLE inputlag.c ${GETOPT} ${GLAD_GL})
|
||||||
add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD_GL})
|
add_executable(joysticks WIN32 MACOSX_BUNDLE joysticks.c ${GLAD_GL})
|
||||||
add_executable(opacity WIN32 MACOSX_BUNDLE opacity.c ${GLAD_GL})
|
|
||||||
add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GLAD_GL})
|
add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GLAD_GL})
|
||||||
add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD_GL})
|
add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD_GL})
|
||||||
add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD_GL})
|
add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD_GL})
|
||||||
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
|
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
|
||||||
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
|
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
|
||||||
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD_GL})
|
add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
|
||||||
|
|
||||||
target_link_libraries(empty Threads::Threads)
|
target_link_libraries(empty Threads::Threads)
|
||||||
target_link_libraries(threads Threads::Threads)
|
target_link_libraries(threads Threads::Threads)
|
||||||
@ -49,8 +48,8 @@ if (RT_LIBRARY)
|
|||||||
target_link_libraries(threads "${RT_LIBRARY}")
|
target_link_libraries(threads "${RT_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks opacity tearing
|
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads
|
||||||
threads timeout title triangle-vulkan windows)
|
timeout title triangle-vulkan window)
|
||||||
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
||||||
cursor)
|
cursor)
|
||||||
|
|
||||||
@ -69,12 +68,11 @@ if (APPLE)
|
|||||||
set_target_properties(gamma PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gamma")
|
set_target_properties(gamma PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gamma")
|
||||||
set_target_properties(inputlag PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Input Lag")
|
set_target_properties(inputlag PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Input Lag")
|
||||||
set_target_properties(joysticks PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Joysticks")
|
set_target_properties(joysticks PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Joysticks")
|
||||||
set_target_properties(opacity PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Opacity")
|
|
||||||
set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing")
|
set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing")
|
||||||
set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads")
|
set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads")
|
||||||
set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout")
|
set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout")
|
||||||
set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
|
set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
|
||||||
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
|
set_target_properties(window PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Window")
|
||||||
|
|
||||||
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||||
|
240
tests/glfwinfo.c
240
tests/glfwinfo.c
@ -55,6 +55,13 @@
|
|||||||
#define BEHAVIOR_NAME_NONE "none"
|
#define BEHAVIOR_NAME_NONE "none"
|
||||||
#define BEHAVIOR_NAME_FLUSH "flush"
|
#define BEHAVIOR_NAME_FLUSH "flush"
|
||||||
|
|
||||||
|
#define ANGLE_TYPE_OPENGL "gl"
|
||||||
|
#define ANGLE_TYPE_OPENGLES "es"
|
||||||
|
#define ANGLE_TYPE_D3D9 "d3d9"
|
||||||
|
#define ANGLE_TYPE_D3D11 "d3d11"
|
||||||
|
#define ANGLE_TYPE_VULKAN "vk"
|
||||||
|
#define ANGLE_TYPE_METAL "mtl"
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
printf("Usage: glfwinfo [OPTION]...\n");
|
printf("Usage: glfwinfo [OPTION]...\n");
|
||||||
@ -101,6 +108,13 @@ static void usage(void)
|
|||||||
printf(" --srgb request an sRGB capable framebuffer\n");
|
printf(" --srgb request an sRGB capable framebuffer\n");
|
||||||
printf(" --singlebuffer request single-buffering\n");
|
printf(" --singlebuffer request single-buffering\n");
|
||||||
printf(" --no-error request a context that does not emit errors\n");
|
printf(" --no-error request a context that does not emit errors\n");
|
||||||
|
printf(" --angle-type=TYPE the ANGLE platform type to use ("
|
||||||
|
ANGLE_TYPE_OPENGL ", "
|
||||||
|
ANGLE_TYPE_OPENGLES ", "
|
||||||
|
ANGLE_TYPE_D3D9 ", "
|
||||||
|
ANGLE_TYPE_D3D11 ", "
|
||||||
|
ANGLE_TYPE_VULKAN " or "
|
||||||
|
ANGLE_TYPE_METAL ")\n");
|
||||||
printf(" --graphics-switching request macOS graphics switching\n");
|
printf(" --graphics-switching request macOS graphics switching\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +292,7 @@ static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice devi
|
|||||||
free(lp);
|
free(lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int valid_version(void)
|
static bool valid_version(void)
|
||||||
{
|
{
|
||||||
int major, minor, revision;
|
int major, minor, revision;
|
||||||
glfwGetVersion(&major, &minor, &revision);
|
glfwGetVersion(&major, &minor, &revision);
|
||||||
@ -286,13 +300,13 @@ static int valid_version(void)
|
|||||||
if (major != GLFW_VERSION_MAJOR)
|
if (major != GLFW_VERSION_MAJOR)
|
||||||
{
|
{
|
||||||
printf("*** ERROR: GLFW major version mismatch! ***\n");
|
printf("*** ERROR: GLFW major version mismatch! ***\n");
|
||||||
return GLFW_FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minor != GLFW_VERSION_MINOR || revision != GLFW_VERSION_REVISION)
|
if (minor != GLFW_VERSION_MINOR || revision != GLFW_VERSION_REVISION)
|
||||||
printf("*** WARNING: GLFW version mismatch! ***\n");
|
printf("*** WARNING: GLFW version mismatch! ***\n");
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_version(void)
|
static void print_version(void)
|
||||||
@ -318,13 +332,42 @@ int main(int argc, char** argv)
|
|||||||
int ch;
|
int ch;
|
||||||
bool list_extensions = false, list_layers = false;
|
bool list_extensions = false, list_layers = false;
|
||||||
|
|
||||||
|
// These duplicate the defaults for each hint
|
||||||
|
int client_api = GLFW_OPENGL_API;
|
||||||
|
int context_major = 1;
|
||||||
|
int context_minor = 0;
|
||||||
|
int context_release = GLFW_ANY_RELEASE_BEHAVIOR;
|
||||||
|
int context_creation_api = GLFW_NATIVE_CONTEXT_API;
|
||||||
|
int context_robustness = GLFW_NO_ROBUSTNESS;
|
||||||
|
bool context_debug = false;
|
||||||
|
bool context_no_error = false;
|
||||||
|
bool opengl_forward = false;
|
||||||
|
int opengl_profile = GLFW_OPENGL_ANY_PROFILE;
|
||||||
|
int fb_red_bits = 8;
|
||||||
|
int fb_green_bits = 8;
|
||||||
|
int fb_blue_bits = 8;
|
||||||
|
int fb_alpha_bits = 8;
|
||||||
|
int fb_depth_bits = 24;
|
||||||
|
int fb_stencil_bits = 8;
|
||||||
|
int fb_accum_red_bits = 0;
|
||||||
|
int fb_accum_green_bits = 0;
|
||||||
|
int fb_accum_blue_bits = 0;
|
||||||
|
int fb_accum_alpha_bits = 0;
|
||||||
|
int fb_aux_buffers = 0;
|
||||||
|
int fb_samples = 0;
|
||||||
|
bool fb_stereo = false;
|
||||||
|
bool fb_srgb = false;
|
||||||
|
bool fb_doublebuffer = true;
|
||||||
|
int angle_type = GLFW_ANGLE_PLATFORM_TYPE_NONE;
|
||||||
|
bool cocoa_graphics_switching = false;
|
||||||
|
|
||||||
enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP,
|
enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP,
|
||||||
EXTENSIONS, LAYERS,
|
EXTENSIONS, LAYERS,
|
||||||
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
||||||
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
||||||
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
||||||
AUXBUFFERS, SAMPLES, STEREO, SRGB, SINGLEBUFFER, NOERROR_SRSLY,
|
AUXBUFFERS, SAMPLES, STEREO, SRGB, SINGLEBUFFER, NOERROR_SRSLY,
|
||||||
GRAPHICS_SWITCHING };
|
ANGLE_TYPE, GRAPHICS_SWITCHING };
|
||||||
const struct option options[] =
|
const struct option options[] =
|
||||||
{
|
{
|
||||||
{ "behavior", 1, NULL, BEHAVIOR },
|
{ "behavior", 1, NULL, BEHAVIOR },
|
||||||
@ -356,22 +399,11 @@ int main(int argc, char** argv)
|
|||||||
{ "srgb", 0, NULL, SRGB },
|
{ "srgb", 0, NULL, SRGB },
|
||||||
{ "singlebuffer", 0, NULL, SINGLEBUFFER },
|
{ "singlebuffer", 0, NULL, SINGLEBUFFER },
|
||||||
{ "no-error", 0, NULL, NOERROR_SRSLY },
|
{ "no-error", 0, NULL, NOERROR_SRSLY },
|
||||||
|
{ "angle-type", 1, NULL, ANGLE_TYPE },
|
||||||
{ "graphics-switching", 0, NULL, GRAPHICS_SWITCHING },
|
{ "graphics-switching", 0, NULL, GRAPHICS_SWITCHING },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize GLFW and create window
|
|
||||||
|
|
||||||
if (!valid_version())
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
|
||||||
|
|
||||||
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
|
|
||||||
|
|
||||||
if (!glfwInit())
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
while ((ch = getopt_long(argc, argv, "a:b:c:dfhlm:n:p:s:v", options, NULL)) != -1)
|
while ((ch = getopt_long(argc, argv, "a:b:c:dfhlm:n:p:s:v", options, NULL)) != -1)
|
||||||
{
|
{
|
||||||
switch (ch)
|
switch (ch)
|
||||||
@ -379,9 +411,9 @@ int main(int argc, char** argv)
|
|||||||
case 'a':
|
case 'a':
|
||||||
case CLIENT:
|
case CLIENT:
|
||||||
if (strcasecmp(optarg, API_NAME_OPENGL) == 0)
|
if (strcasecmp(optarg, API_NAME_OPENGL) == 0)
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
client_api = GLFW_OPENGL_API;
|
||||||
else if (strcasecmp(optarg, API_NAME_OPENGL_ES) == 0)
|
else if (strcasecmp(optarg, API_NAME_OPENGL_ES) == 0)
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
client_api = GLFW_OPENGL_ES_API;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
@ -391,15 +423,9 @@ int main(int argc, char** argv)
|
|||||||
case 'b':
|
case 'b':
|
||||||
case BEHAVIOR:
|
case BEHAVIOR:
|
||||||
if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0)
|
if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0)
|
||||||
{
|
context_release = GLFW_RELEASE_BEHAVIOR_NONE;
|
||||||
glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR,
|
|
||||||
GLFW_RELEASE_BEHAVIOR_NONE);
|
|
||||||
}
|
|
||||||
else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0)
|
else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0)
|
||||||
{
|
context_release = GLFW_RELEASE_BEHAVIOR_FLUSH;
|
||||||
glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR,
|
|
||||||
GLFW_RELEASE_BEHAVIOR_FLUSH);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
@ -409,11 +435,11 @@ int main(int argc, char** argv)
|
|||||||
case 'c':
|
case 'c':
|
||||||
case CONTEXT:
|
case CONTEXT:
|
||||||
if (strcasecmp(optarg, API_NAME_NATIVE) == 0)
|
if (strcasecmp(optarg, API_NAME_NATIVE) == 0)
|
||||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
|
context_creation_api = GLFW_NATIVE_CONTEXT_API;
|
||||||
else if (strcasecmp(optarg, API_NAME_EGL) == 0)
|
else if (strcasecmp(optarg, API_NAME_EGL) == 0)
|
||||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
|
context_creation_api = GLFW_EGL_CONTEXT_API;
|
||||||
else if (strcasecmp(optarg, API_NAME_OSMESA) == 0)
|
else if (strcasecmp(optarg, API_NAME_OSMESA) == 0)
|
||||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_OSMESA_CONTEXT_API);
|
context_creation_api = GLFW_OSMESA_CONTEXT_API;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
@ -422,11 +448,11 @@ int main(int argc, char** argv)
|
|||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case DEBUG_CONTEXT:
|
case DEBUG_CONTEXT:
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
context_debug = true;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
case FORWARD:
|
case FORWARD:
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
opengl_forward = true;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case HELP:
|
case HELP:
|
||||||
@ -434,31 +460,25 @@ int main(int argc, char** argv)
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case 'l':
|
case 'l':
|
||||||
case EXTENSIONS:
|
case EXTENSIONS:
|
||||||
list_extensions = GLFW_TRUE;
|
list_extensions = true;
|
||||||
break;
|
break;
|
||||||
case LAYERS:
|
case LAYERS:
|
||||||
list_layers = GLFW_TRUE;
|
list_layers = true;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
case MAJOR:
|
case MAJOR:
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, atoi(optarg));
|
context_major = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
case MINOR:
|
case MINOR:
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, atoi(optarg));
|
context_minor = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
case PROFILE:
|
case PROFILE:
|
||||||
if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0)
|
if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0)
|
||||||
{
|
opengl_profile = GLFW_OPENGL_CORE_PROFILE;
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE,
|
|
||||||
GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
}
|
|
||||||
else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0)
|
else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0)
|
||||||
{
|
opengl_profile = GLFW_OPENGL_COMPAT_PROFILE;
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE,
|
|
||||||
GLFW_OPENGL_COMPAT_PROFILE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
@ -468,15 +488,9 @@ int main(int argc, char** argv)
|
|||||||
case 's':
|
case 's':
|
||||||
case ROBUSTNESS:
|
case ROBUSTNESS:
|
||||||
if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0)
|
if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0)
|
||||||
{
|
context_robustness = GLFW_NO_RESET_NOTIFICATION;
|
||||||
glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS,
|
|
||||||
GLFW_NO_RESET_NOTIFICATION);
|
|
||||||
}
|
|
||||||
else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0)
|
else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0)
|
||||||
{
|
context_robustness = GLFW_LOSE_CONTEXT_ON_RESET;
|
||||||
glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS,
|
|
||||||
GLFW_LOSE_CONTEXT_ON_RESET);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
@ -489,90 +503,109 @@ int main(int argc, char** argv)
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case REDBITS:
|
case REDBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE);
|
fb_red_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_RED_BITS, atoi(optarg));
|
fb_red_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case GREENBITS:
|
case GREENBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE);
|
fb_green_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_GREEN_BITS, atoi(optarg));
|
fb_green_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case BLUEBITS:
|
case BLUEBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE);
|
fb_blue_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_BLUE_BITS, atoi(optarg));
|
fb_blue_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case ALPHABITS:
|
case ALPHABITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE);
|
fb_alpha_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_ALPHA_BITS, atoi(optarg));
|
fb_alpha_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case DEPTHBITS:
|
case DEPTHBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE);
|
fb_depth_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, atoi(optarg));
|
fb_depth_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case STENCILBITS:
|
case STENCILBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE);
|
fb_stencil_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_STENCIL_BITS, atoi(optarg));
|
fb_stencil_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case ACCUMREDBITS:
|
case ACCUMREDBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE);
|
fb_accum_red_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_ACCUM_RED_BITS, atoi(optarg));
|
fb_accum_red_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case ACCUMGREENBITS:
|
case ACCUMGREENBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE);
|
fb_accum_green_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_ACCUM_GREEN_BITS, atoi(optarg));
|
fb_accum_green_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case ACCUMBLUEBITS:
|
case ACCUMBLUEBITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE);
|
fb_accum_blue_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_ACCUM_BLUE_BITS, atoi(optarg));
|
fb_accum_blue_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case ACCUMALPHABITS:
|
case ACCUMALPHABITS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE);
|
fb_accum_alpha_bits = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, atoi(optarg));
|
fb_accum_alpha_bits = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case AUXBUFFERS:
|
case AUXBUFFERS:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE);
|
fb_aux_buffers = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_AUX_BUFFERS, atoi(optarg));
|
fb_aux_buffers = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case SAMPLES:
|
case SAMPLES:
|
||||||
if (strcmp(optarg, "-") == 0)
|
if (strcmp(optarg, "-") == 0)
|
||||||
glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE);
|
fb_samples = GLFW_DONT_CARE;
|
||||||
else
|
else
|
||||||
glfwWindowHint(GLFW_SAMPLES, atoi(optarg));
|
fb_samples = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case STEREO:
|
case STEREO:
|
||||||
glfwWindowHint(GLFW_STEREO, GLFW_TRUE);
|
fb_stereo = true;
|
||||||
break;
|
break;
|
||||||
case SRGB:
|
case SRGB:
|
||||||
glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE);
|
fb_srgb = true;
|
||||||
break;
|
break;
|
||||||
case SINGLEBUFFER:
|
case SINGLEBUFFER:
|
||||||
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);
|
fb_doublebuffer = false;
|
||||||
break;
|
break;
|
||||||
case NOERROR_SRSLY:
|
case NOERROR_SRSLY:
|
||||||
glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_TRUE);
|
context_no_error = true;
|
||||||
|
break;
|
||||||
|
case ANGLE_TYPE:
|
||||||
|
if (strcmp(optarg, ANGLE_TYPE_OPENGL) == 0)
|
||||||
|
angle_type = GLFW_ANGLE_PLATFORM_TYPE_OPENGL;
|
||||||
|
else if (strcmp(optarg, ANGLE_TYPE_OPENGLES) == 0)
|
||||||
|
angle_type = GLFW_ANGLE_PLATFORM_TYPE_OPENGLES;
|
||||||
|
else if (strcmp(optarg, ANGLE_TYPE_D3D9) == 0)
|
||||||
|
angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D9;
|
||||||
|
else if (strcmp(optarg, ANGLE_TYPE_D3D11) == 0)
|
||||||
|
angle_type = GLFW_ANGLE_PLATFORM_TYPE_D3D11;
|
||||||
|
else if (strcmp(optarg, ANGLE_TYPE_VULKAN) == 0)
|
||||||
|
angle_type = GLFW_ANGLE_PLATFORM_TYPE_VULKAN;
|
||||||
|
else if (strcmp(optarg, ANGLE_TYPE_METAL) == 0)
|
||||||
|
angle_type = GLFW_ANGLE_PLATFORM_TYPE_METAL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usage();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GRAPHICS_SWITCHING:
|
case GRAPHICS_SWITCHING:
|
||||||
glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, GLFW_TRUE);
|
cocoa_graphics_switching = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
@ -580,9 +613,52 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize GLFW and create window
|
||||||
|
|
||||||
|
if (!valid_version())
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
|
glfwInitHint(GLFW_COCOA_MENUBAR, false);
|
||||||
|
|
||||||
|
glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE, angle_type);
|
||||||
|
|
||||||
|
if (!glfwInit())
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
print_version();
|
print_version();
|
||||||
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, false);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, client_api);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, context_major);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, context_minor);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, context_release);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_CREATION_API, context_creation_api);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, context_robustness);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_DEBUG, context_debug);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_NO_ERROR, context_no_error);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, opengl_forward);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, opengl_profile);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_RED_BITS, fb_red_bits);
|
||||||
|
glfwWindowHint(GLFW_BLUE_BITS, fb_blue_bits);
|
||||||
|
glfwWindowHint(GLFW_GREEN_BITS, fb_green_bits);
|
||||||
|
glfwWindowHint(GLFW_ALPHA_BITS, fb_alpha_bits);
|
||||||
|
glfwWindowHint(GLFW_DEPTH_BITS, fb_depth_bits);
|
||||||
|
glfwWindowHint(GLFW_STENCIL_BITS, fb_stencil_bits);
|
||||||
|
glfwWindowHint(GLFW_ACCUM_RED_BITS, fb_accum_red_bits);
|
||||||
|
glfwWindowHint(GLFW_ACCUM_GREEN_BITS, fb_accum_green_bits);
|
||||||
|
glfwWindowHint(GLFW_ACCUM_BLUE_BITS, fb_accum_blue_bits);
|
||||||
|
glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, fb_accum_alpha_bits);
|
||||||
|
glfwWindowHint(GLFW_AUX_BUFFERS, fb_aux_buffers);
|
||||||
|
glfwWindowHint(GLFW_SAMPLES, fb_samples);
|
||||||
|
glfwWindowHint(GLFW_STEREO, fb_stereo);
|
||||||
|
glfwWindowHint(GLFW_SRGB_CAPABLE, fb_srgb);
|
||||||
|
glfwWindowHint(GLFW_DOUBLEBUFFER, fb_doublebuffer);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, cocoa_graphics_switching);
|
||||||
|
|
||||||
GLFWwindow* window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
@ -639,7 +715,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT))
|
if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT))
|
||||||
printf(" forward-compatible");
|
printf(" forward-compatible");
|
||||||
if (glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT))
|
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_DEBUG))
|
||||||
printf(" debug");
|
printf(" debug");
|
||||||
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET)
|
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
printf(" robustness");
|
printf(" robustness");
|
||||||
|
@ -241,6 +241,8 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
|
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
109
tests/opacity.c
109
tests/opacity.c
@ -1,109 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// Window opacity test program
|
|
||||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include <glad/gl.h>
|
|
||||||
#define GLFW_INCLUDE_NONE
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#define NK_IMPLEMENTATION
|
|
||||||
#define NK_INCLUDE_FIXED_TYPES
|
|
||||||
#define NK_INCLUDE_FONT_BAKING
|
|
||||||
#define NK_INCLUDE_DEFAULT_FONT
|
|
||||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
|
||||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
|
||||||
#define NK_INCLUDE_STANDARD_VARARGS
|
|
||||||
#include <nuklear.h>
|
|
||||||
|
|
||||||
#define NK_GLFW_GL2_IMPLEMENTATION
|
|
||||||
#include <nuklear_glfw_gl2.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static void error_callback(int error, const char* description)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error: %s\n", description);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
GLFWwindow* window;
|
|
||||||
struct nk_context* nk;
|
|
||||||
struct nk_font_atlas* atlas;
|
|
||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
|
||||||
|
|
||||||
if (!glfwInit())
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
|
||||||
glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE);
|
|
||||||
|
|
||||||
window = glfwCreateWindow(400, 400, "Opacity", NULL, NULL);
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
glfwTerminate();
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
gladLoadGL(glfwGetProcAddress);
|
|
||||||
glfwSwapInterval(1);
|
|
||||||
|
|
||||||
nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS);
|
|
||||||
nk_glfw3_font_stash_begin(&atlas);
|
|
||||||
nk_glfw3_font_stash_end();
|
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
struct nk_rect area;
|
|
||||||
|
|
||||||
glfwGetWindowSize(window, &width, &height);
|
|
||||||
area = nk_rect(0.f, 0.f, (float) width, (float) height);
|
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
nk_glfw3_new_frame();
|
|
||||||
if (nk_begin(nk, "", area, 0))
|
|
||||||
{
|
|
||||||
float opacity = glfwGetWindowOpacity(window);
|
|
||||||
nk_layout_row_dynamic(nk, 30, 2);
|
|
||||||
if (nk_slider_float(nk, 0.f, &opacity, 1.f, 0.001f))
|
|
||||||
glfwSetWindowOpacity(window, opacity);
|
|
||||||
nk_labelf(nk, NK_TEXT_LEFT, "%0.3f", opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
nk_end(nk);
|
|
||||||
nk_glfw3_render(NK_ANTI_ALIASING_ON);
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwWaitEventsTimeout(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
nk_glfw3_shutdown();
|
|
||||||
glfwTerminate();
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
417
tests/window.c
Normal file
417
tests/window.c
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
//========================================================================
|
||||||
|
// Window properties test
|
||||||
|
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define NK_IMPLEMENTATION
|
||||||
|
#define NK_INCLUDE_FIXED_TYPES
|
||||||
|
#define NK_INCLUDE_FONT_BAKING
|
||||||
|
#define NK_INCLUDE_DEFAULT_FONT
|
||||||
|
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||||
|
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||||
|
#define NK_INCLUDE_STANDARD_VARARGS
|
||||||
|
#define NK_BUTTON_TRIGGER_ON_RELEASE
|
||||||
|
#include <nuklear.h>
|
||||||
|
|
||||||
|
#define NK_GLFW_GL2_IMPLEMENTATION
|
||||||
|
#include <nuklear_glfw_gl2.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int windowed_x, windowed_y, windowed_width, windowed_height;
|
||||||
|
int last_xpos = INT_MIN, last_ypos = INT_MIN;
|
||||||
|
int last_width = INT_MIN, last_height = INT_MIN;
|
||||||
|
int limit_aspect_ratio = false, aspect_numer = 1, aspect_denom = 1;
|
||||||
|
int limit_min_size = false, min_width = 400, min_height = 400;
|
||||||
|
int limit_max_size = false, max_width = 400, max_height = 400;
|
||||||
|
char width_buffer[10] = "", height_buffer[10] = "";
|
||||||
|
char xpos_buffer[10] = "", ypos_buffer[10] = "";
|
||||||
|
char numer_buffer[10] = "", denom_buffer[10] = "";
|
||||||
|
char min_width_buffer[10] = "", min_height_buffer[10] = "";
|
||||||
|
char max_width_buffer[10] = "", max_height_buffer[10] = "";
|
||||||
|
int may_close = true;
|
||||||
|
|
||||||
|
if (!glfwInit())
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||||
|
|
||||||
|
GLFWwindow* window = glfwCreateWindow(600, 600, "Window Features", NULL, NULL);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
gladLoadGL(glfwGetProcAddress);
|
||||||
|
glfwSwapInterval(0);
|
||||||
|
|
||||||
|
bool position_supported = true;
|
||||||
|
|
||||||
|
glfwGetError(NULL);
|
||||||
|
glfwGetWindowPos(window, &last_xpos, &last_ypos);
|
||||||
|
sprintf(xpos_buffer, "%i", last_xpos);
|
||||||
|
sprintf(ypos_buffer, "%i", last_ypos);
|
||||||
|
if (glfwGetError(NULL) == GLFW_FEATURE_UNAVAILABLE)
|
||||||
|
position_supported = false;
|
||||||
|
|
||||||
|
glfwGetWindowSize(window, &last_width, &last_height);
|
||||||
|
sprintf(width_buffer, "%i", last_width);
|
||||||
|
sprintf(height_buffer, "%i", last_height);
|
||||||
|
|
||||||
|
sprintf(numer_buffer, "%i", aspect_numer);
|
||||||
|
sprintf(denom_buffer, "%i", aspect_denom);
|
||||||
|
|
||||||
|
sprintf(min_width_buffer, "%i", min_width);
|
||||||
|
sprintf(min_height_buffer, "%i", min_height);
|
||||||
|
sprintf(max_width_buffer, "%i", max_width);
|
||||||
|
sprintf(max_height_buffer, "%i", max_height);
|
||||||
|
|
||||||
|
struct nk_context* nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS);
|
||||||
|
|
||||||
|
struct nk_font_atlas* atlas;
|
||||||
|
nk_glfw3_font_stash_begin(&atlas);
|
||||||
|
nk_glfw3_font_stash_end();
|
||||||
|
|
||||||
|
while (!(may_close && glfwWindowShouldClose(window)))
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
glfwGetWindowSize(window, &width, &height);
|
||||||
|
|
||||||
|
struct nk_rect area = nk_rect(0.f, 0.f, (float) width, (float) height);
|
||||||
|
nk_window_set_bounds(nk, "main", area);
|
||||||
|
|
||||||
|
nk_glfw3_new_frame();
|
||||||
|
if (nk_begin(nk, "main", area, 0))
|
||||||
|
{
|
||||||
|
nk_layout_row_dynamic(nk, 30, 4);
|
||||||
|
|
||||||
|
if (nk_button_label(nk, "Toggle Fullscreen"))
|
||||||
|
{
|
||||||
|
if (glfwGetWindowMonitor(window))
|
||||||
|
{
|
||||||
|
glfwSetWindowMonitor(window, NULL,
|
||||||
|
windowed_x, windowed_y,
|
||||||
|
windowed_width, windowed_height, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||||
|
glfwGetWindowPos(window, &windowed_x, &windowed_y);
|
||||||
|
glfwGetWindowSize(window, &windowed_width, &windowed_height);
|
||||||
|
glfwSetWindowMonitor(window, monitor,
|
||||||
|
0, 0, mode->width, mode->height,
|
||||||
|
mode->refreshRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nk_button_label(nk, "Maximize"))
|
||||||
|
glfwMaximizeWindow(window);
|
||||||
|
if (nk_button_label(nk, "Iconify"))
|
||||||
|
glfwIconifyWindow(window);
|
||||||
|
if (nk_button_label(nk, "Restore"))
|
||||||
|
glfwRestoreWindow(window);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(nk, 30, 1);
|
||||||
|
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH))
|
||||||
|
{
|
||||||
|
nk_label(nk, "Press H to disable mouse passthrough", NK_TEXT_CENTERED);
|
||||||
|
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_H))
|
||||||
|
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
nk_label(nk, "Press Enter in a text field to set value", NK_TEXT_CENTERED);
|
||||||
|
|
||||||
|
nk_flags events;
|
||||||
|
const nk_flags flags = NK_EDIT_FIELD |
|
||||||
|
NK_EDIT_SIG_ENTER |
|
||||||
|
NK_EDIT_GOTO_END_ON_ACTIVATE;
|
||||||
|
|
||||||
|
if (position_supported)
|
||||||
|
{
|
||||||
|
int xpos, ypos;
|
||||||
|
glfwGetWindowPos(window, &xpos, &ypos);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(nk, 30, 3);
|
||||||
|
nk_label(nk, "Position", NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, xpos_buffer,
|
||||||
|
sizeof(xpos_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
xpos = atoi(xpos_buffer);
|
||||||
|
glfwSetWindowPos(window, xpos, ypos);
|
||||||
|
}
|
||||||
|
else if (xpos != last_xpos || (events & NK_EDIT_DEACTIVATED))
|
||||||
|
sprintf(xpos_buffer, "%i", xpos);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, ypos_buffer,
|
||||||
|
sizeof(ypos_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
ypos = atoi(ypos_buffer);
|
||||||
|
glfwSetWindowPos(window, xpos, ypos);
|
||||||
|
}
|
||||||
|
else if (ypos != last_ypos || (events & NK_EDIT_DEACTIVATED))
|
||||||
|
sprintf(ypos_buffer, "%i", ypos);
|
||||||
|
|
||||||
|
last_xpos = xpos;
|
||||||
|
last_ypos = ypos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nk_label(nk, "Position not supported", NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(nk, 30, 3);
|
||||||
|
nk_label(nk, "Size", NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, width_buffer,
|
||||||
|
sizeof(width_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
width = atoi(width_buffer);
|
||||||
|
glfwSetWindowSize(window, width, height);
|
||||||
|
}
|
||||||
|
else if (width != last_width || (events & NK_EDIT_DEACTIVATED))
|
||||||
|
sprintf(width_buffer, "%i", width);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, height_buffer,
|
||||||
|
sizeof(height_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
height = atoi(height_buffer);
|
||||||
|
glfwSetWindowSize(window, width, height);
|
||||||
|
}
|
||||||
|
else if (height != last_height || (events & NK_EDIT_DEACTIVATED))
|
||||||
|
sprintf(height_buffer, "%i", height);
|
||||||
|
|
||||||
|
last_width = width;
|
||||||
|
last_height = height;
|
||||||
|
|
||||||
|
bool update_ratio_limit = false;
|
||||||
|
if (nk_checkbox_label(nk, "Aspect Ratio", &limit_aspect_ratio))
|
||||||
|
update_ratio_limit = true;
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, numer_buffer,
|
||||||
|
sizeof(numer_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
aspect_numer = abs(atoi(numer_buffer));
|
||||||
|
update_ratio_limit = true;
|
||||||
|
}
|
||||||
|
else if (events & NK_EDIT_DEACTIVATED)
|
||||||
|
sprintf(numer_buffer, "%i", aspect_numer);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, denom_buffer,
|
||||||
|
sizeof(denom_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
aspect_denom = abs(atoi(denom_buffer));
|
||||||
|
update_ratio_limit = true;
|
||||||
|
}
|
||||||
|
else if (events & NK_EDIT_DEACTIVATED)
|
||||||
|
sprintf(denom_buffer, "%i", aspect_denom);
|
||||||
|
|
||||||
|
if (update_ratio_limit)
|
||||||
|
{
|
||||||
|
if (limit_aspect_ratio)
|
||||||
|
glfwSetWindowAspectRatio(window, aspect_numer, aspect_denom);
|
||||||
|
else
|
||||||
|
glfwSetWindowAspectRatio(window, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update_size_limit = false;
|
||||||
|
|
||||||
|
if (nk_checkbox_label(nk, "Minimum Size", &limit_min_size))
|
||||||
|
update_size_limit = true;
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, min_width_buffer,
|
||||||
|
sizeof(min_width_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
min_width = abs(atoi(min_width_buffer));
|
||||||
|
update_size_limit = true;
|
||||||
|
}
|
||||||
|
else if (events & NK_EDIT_DEACTIVATED)
|
||||||
|
sprintf(min_width_buffer, "%i", min_width);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, min_height_buffer,
|
||||||
|
sizeof(min_height_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
min_height = abs(atoi(min_height_buffer));
|
||||||
|
update_size_limit = true;
|
||||||
|
}
|
||||||
|
else if (events & NK_EDIT_DEACTIVATED)
|
||||||
|
sprintf(min_height_buffer, "%i", min_height);
|
||||||
|
|
||||||
|
if (nk_checkbox_label(nk, "Maximum Size", &limit_max_size))
|
||||||
|
update_size_limit = true;
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, max_width_buffer,
|
||||||
|
sizeof(max_width_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
max_width = abs(atoi(max_width_buffer));
|
||||||
|
update_size_limit = true;
|
||||||
|
}
|
||||||
|
else if (events & NK_EDIT_DEACTIVATED)
|
||||||
|
sprintf(max_width_buffer, "%i", max_width);
|
||||||
|
|
||||||
|
events = nk_edit_string_zero_terminated(nk, flags, max_height_buffer,
|
||||||
|
sizeof(max_height_buffer),
|
||||||
|
nk_filter_decimal);
|
||||||
|
if (events & NK_EDIT_COMMITED)
|
||||||
|
{
|
||||||
|
max_height = abs(atoi(max_height_buffer));
|
||||||
|
update_size_limit = true;
|
||||||
|
}
|
||||||
|
else if (events & NK_EDIT_DEACTIVATED)
|
||||||
|
sprintf(max_height_buffer, "%i", max_height);
|
||||||
|
|
||||||
|
if (update_size_limit)
|
||||||
|
{
|
||||||
|
glfwSetWindowSizeLimits(window,
|
||||||
|
limit_min_size ? min_width : GLFW_DONT_CARE,
|
||||||
|
limit_min_size ? min_height : GLFW_DONT_CARE,
|
||||||
|
limit_max_size ? max_width : GLFW_DONT_CARE,
|
||||||
|
limit_max_size ? max_height : GLFW_DONT_CARE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fb_width, fb_height;
|
||||||
|
glfwGetFramebufferSize(window, &fb_width, &fb_height);
|
||||||
|
nk_label(nk, "Framebuffer Size", NK_TEXT_LEFT);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%i", fb_width);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%i", fb_height);
|
||||||
|
|
||||||
|
float xscale, yscale;
|
||||||
|
glfwGetWindowContentScale(window, &xscale, &yscale);
|
||||||
|
nk_label(nk, "Content Scale", NK_TEXT_LEFT);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%f", xscale);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%f", yscale);
|
||||||
|
|
||||||
|
nk_layout_row_begin(nk, NK_DYNAMIC, 30, 5);
|
||||||
|
int frame_left, frame_top, frame_right, frame_bottom;
|
||||||
|
glfwGetWindowFrameSize(window, &frame_left, &frame_top, &frame_right, &frame_bottom);
|
||||||
|
nk_layout_row_push(nk, 1.f / 3.f);
|
||||||
|
nk_label(nk, "Frame Size:", NK_TEXT_LEFT);
|
||||||
|
nk_layout_row_push(nk, 1.f / 6.f);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_left);
|
||||||
|
nk_layout_row_push(nk, 1.f / 6.f);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_top);
|
||||||
|
nk_layout_row_push(nk, 1.f / 6.f);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_right);
|
||||||
|
nk_layout_row_push(nk, 1.f / 6.f);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "%i", frame_bottom);
|
||||||
|
nk_layout_row_end(nk);
|
||||||
|
|
||||||
|
nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2);
|
||||||
|
float opacity = glfwGetWindowOpacity(window);
|
||||||
|
nk_layout_row_push(nk, 1.f / 3.f);
|
||||||
|
nk_labelf(nk, NK_TEXT_LEFT, "Opacity: %0.3f", opacity);
|
||||||
|
nk_layout_row_push(nk, 2.f / 3.f);
|
||||||
|
if (nk_slider_float(nk, 0.f, &opacity, 1.f, 0.001f))
|
||||||
|
glfwSetWindowOpacity(window, opacity);
|
||||||
|
nk_layout_row_end(nk);
|
||||||
|
|
||||||
|
nk_layout_row_begin(nk, NK_DYNAMIC, 30, 2);
|
||||||
|
int should_close = glfwWindowShouldClose(window);
|
||||||
|
nk_layout_row_push(nk, 1.f / 3.f);
|
||||||
|
if (nk_checkbox_label(nk, "Should Close", &should_close))
|
||||||
|
glfwSetWindowShouldClose(window, should_close);
|
||||||
|
nk_layout_row_push(nk, 2.f / 3.f);
|
||||||
|
nk_checkbox_label(nk, "May Close", &may_close);
|
||||||
|
nk_layout_row_end(nk);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(nk, 30, 1);
|
||||||
|
nk_label(nk, "Attributes", NK_TEXT_CENTERED);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(nk, 30, width > 200 ? width / 200 : 1);
|
||||||
|
|
||||||
|
int decorated = glfwGetWindowAttrib(window, GLFW_DECORATED);
|
||||||
|
if (nk_checkbox_label(nk, "Decorated", &decorated))
|
||||||
|
glfwSetWindowAttrib(window, GLFW_DECORATED, decorated);
|
||||||
|
|
||||||
|
int resizable = glfwGetWindowAttrib(window, GLFW_RESIZABLE);
|
||||||
|
if (nk_checkbox_label(nk, "Resizable", &resizable))
|
||||||
|
glfwSetWindowAttrib(window, GLFW_RESIZABLE, resizable);
|
||||||
|
|
||||||
|
int floating = glfwGetWindowAttrib(window, GLFW_FLOATING);
|
||||||
|
if (nk_checkbox_label(nk, "Floating", &floating))
|
||||||
|
glfwSetWindowAttrib(window, GLFW_FLOATING, floating);
|
||||||
|
|
||||||
|
int passthrough = glfwGetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH);
|
||||||
|
if (nk_checkbox_label(nk, "Mouse Passthrough", &passthrough))
|
||||||
|
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, passthrough);
|
||||||
|
|
||||||
|
int auto_iconify = glfwGetWindowAttrib(window, GLFW_AUTO_ICONIFY);
|
||||||
|
if (nk_checkbox_label(nk, "Auto Iconify", &auto_iconify))
|
||||||
|
glfwSetWindowAttrib(window, GLFW_AUTO_ICONIFY, auto_iconify);
|
||||||
|
|
||||||
|
nk_value_bool(nk, "Focused", glfwGetWindowAttrib(window, GLFW_FOCUSED));
|
||||||
|
nk_value_bool(nk, "Hovered", glfwGetWindowAttrib(window, GLFW_HOVERED));
|
||||||
|
nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE));
|
||||||
|
nk_value_bool(nk, "Iconified", glfwGetWindowAttrib(window, GLFW_ICONIFIED));
|
||||||
|
nk_value_bool(nk, "Maximized", glfwGetWindowAttrib(window, GLFW_MAXIMIZED));
|
||||||
|
}
|
||||||
|
nk_end(nk);
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
nk_glfw3_render(NK_ANTI_ALIASING_ON);
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
|
||||||
|
glfwWaitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
nk_glfw3_shutdown();
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user