mirror of
https://github.com/glfw/glfw.git
synced 2025-10-03 21:30:57 +00:00
Merge branch 'master' into fix1112
This commit is contained in:
commit
ba9737e9d4
@ -1,20 +1,57 @@
|
|||||||
|
image:
|
||||||
|
- Visual Studio 2015
|
||||||
|
- Visual Studio 2019
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- ci
|
- ci
|
||||||
- master
|
- master
|
||||||
|
- 3.3-stable
|
||||||
skip_tags: true
|
skip_tags: true
|
||||||
environment:
|
environment:
|
||||||
CFLAGS: /WX
|
|
||||||
matrix:
|
matrix:
|
||||||
- BUILD_SHARED_LIBS: ON
|
- GENERATOR: MinGW Makefiles
|
||||||
- BUILD_SHARED_LIBS: OFF
|
BUILD_SHARED_LIBS: ON
|
||||||
|
CFLAGS: -Werror
|
||||||
|
- GENERATOR: MinGW Makefiles
|
||||||
|
BUILD_SHARED_LIBS: OFF
|
||||||
|
CFLAGS: -Werror
|
||||||
|
- GENERATOR: Visual Studio 10 2010
|
||||||
|
BUILD_SHARED_LIBS: ON
|
||||||
|
CFLAGS: /WX
|
||||||
|
- GENERATOR: Visual Studio 10 2010
|
||||||
|
BUILD_SHARED_LIBS: OFF
|
||||||
|
CFLAGS: /WX
|
||||||
|
- GENERATOR: Visual Studio 16 2019
|
||||||
|
BUILD_SHARED_LIBS: ON
|
||||||
|
CFLAGS: /WX
|
||||||
|
- GENERATOR: Visual Studio 16 2019
|
||||||
|
BUILD_SHARED_LIBS: OFF
|
||||||
|
CFLAGS: /WX
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
build_script:
|
exclude:
|
||||||
- mkdir build
|
- image: Visual Studio 2015
|
||||||
- cd build
|
GENERATOR: Visual Studio 16 2019
|
||||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
|
- image: Visual Studio 2019
|
||||||
- cmake --build .
|
GENERATOR: Visual Studio 10 2010
|
||||||
|
- image: Visual Studio 2019
|
||||||
|
GENERATOR: MinGW Makefiles
|
||||||
|
for:
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
except:
|
||||||
|
- GENERATOR: Visual Studio 10 2010
|
||||||
|
build_script:
|
||||||
|
- set PATH=%PATH:C:\Program Files\Git\usr\bin=C:\MinGW\bin%
|
||||||
|
- cmake -S . -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
|
||||||
|
- cmake --build build
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- GENERATOR: Visual Studio 10 2010
|
||||||
|
build_script:
|
||||||
|
- cmake -S . -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
|
||||||
|
- cmake --build build --target glfw
|
||||||
notifications:
|
notifications:
|
||||||
- provider: Email
|
- provider: Email
|
||||||
to:
|
to:
|
||||||
|
35
.gitignore
vendored
35
.gitignore
vendored
@ -1,26 +1,45 @@
|
|||||||
# External junk
|
# The canonical out-of-tree build subdirectory
|
||||||
.DS_Store
|
build
|
||||||
|
|
||||||
|
# Visual Studio clutter
|
||||||
_ReSharper*
|
_ReSharper*
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
*.sdf
|
||||||
*.suo
|
*.suo
|
||||||
*.dir
|
*.dir
|
||||||
*.vcxproj*
|
*.vcxproj*
|
||||||
*.sln
|
*.sln
|
||||||
.vs/
|
.vs
|
||||||
|
CMakeSettings.json
|
||||||
Win32
|
Win32
|
||||||
x64
|
x64
|
||||||
Debug
|
Debug
|
||||||
Release
|
Release
|
||||||
MinSizeRel
|
MinSizeRel
|
||||||
RelWithDebInfo
|
RelWithDebInfo
|
||||||
*.xcodeproj
|
*.opensdf
|
||||||
|
|
||||||
# CMake files
|
# Xcode clutter
|
||||||
|
GLFW.build
|
||||||
|
GLFW.xcodeproj
|
||||||
|
|
||||||
|
# macOS clutter
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Makefile generator clutter
|
||||||
Makefile
|
Makefile
|
||||||
|
|
||||||
|
# Ninja generator clutter
|
||||||
|
build.ninja
|
||||||
|
rules.ninja
|
||||||
|
.ninja_deps
|
||||||
|
.ninja_log
|
||||||
|
|
||||||
|
# CMake clutter
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
CMakeScripts
|
CMakeScripts
|
||||||
|
CMakeDoxyfile.in
|
||||||
|
CMakeDoxygenDefaults.cmake
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
cmake_uninstall.cmake
|
cmake_uninstall.cmake
|
||||||
|
|
||||||
@ -60,7 +79,7 @@ examples/offscreen
|
|||||||
examples/particles
|
examples/particles
|
||||||
examples/splitview
|
examples/splitview
|
||||||
examples/sharing
|
examples/sharing
|
||||||
examples/simple
|
examples/triangle-opengl
|
||||||
examples/wave
|
examples/wave
|
||||||
tests/*.app
|
tests/*.app
|
||||||
tests/*.exe
|
tests/*.exe
|
||||||
@ -80,6 +99,6 @@ tests/tearing
|
|||||||
tests/threads
|
tests/threads
|
||||||
tests/timeout
|
tests/timeout
|
||||||
tests/title
|
tests/title
|
||||||
tests/vulkan
|
tests/triangle-vulkan
|
||||||
tests/windows
|
tests/windows
|
||||||
|
|
||||||
|
10
.mailmap
Normal file
10
.mailmap
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Camilla Löwy <elmindreda@glfw.org> <elmindreda@users.sourceforge.net>
|
||||||
|
Camilla Löwy <elmindreda@glfw.org> <elmindreda@elmindreda.org>
|
||||||
|
Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
|
||||||
|
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||||
|
|
||||||
|
Marcus Geelnard <m@bitsnbites.eu> <marcus256@users.sourceforge.net>
|
||||||
|
Marcus Geelnard <m@bitsnbites.eu> <marcus@geelnards-pc.(none)>
|
||||||
|
Marcus Geelnard <m@bitsnbites.eu>
|
||||||
|
|
56
.travis.yml
56
.travis.yml
@ -4,31 +4,47 @@ branches:
|
|||||||
only:
|
only:
|
||||||
- ci
|
- ci
|
||||||
- master
|
- master
|
||||||
sudo: false
|
- 3.3-stable
|
||||||
dist: trusty
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- cmake
|
|
||||||
- libxrandr-dev
|
|
||||||
- libxinerama-dev
|
|
||||||
- libxcursor-dev
|
|
||||||
- libxi-dev
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
|
sudo: false
|
||||||
|
name: "X11 shared library"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libxrandr-dev
|
||||||
|
- libxinerama-dev
|
||||||
|
- libxcursor-dev
|
||||||
|
- libxi-dev
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=ON
|
- BUILD_SHARED_LIBS=ON
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
|
sudo: false
|
||||||
|
name: "X11 static library"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libxrandr-dev
|
||||||
|
- libxinerama-dev
|
||||||
|
- libxcursor-dev
|
||||||
|
- libxi-dev
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=OFF
|
- BUILD_SHARED_LIBS=OFF
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
sudo: required
|
sudo: required
|
||||||
|
name: "Wayland shared library"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
sources:
|
||||||
|
- ppa:kubuntu-ppa/backports
|
||||||
packages:
|
packages:
|
||||||
|
- extra-cmake-modules
|
||||||
- libwayland-dev
|
- libwayland-dev
|
||||||
- libxkbcommon-dev
|
- libxkbcommon-dev
|
||||||
- libegl1-mesa-dev
|
- libegl1-mesa-dev
|
||||||
@ -37,10 +53,15 @@ matrix:
|
|||||||
- BUILD_SHARED_LIBS=ON
|
- BUILD_SHARED_LIBS=ON
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
sudo: required
|
sudo: required
|
||||||
|
name: "Wayland static library"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
sources:
|
||||||
|
- ppa:kubuntu-ppa/backports
|
||||||
packages:
|
packages:
|
||||||
|
- extra-cmake-modules
|
||||||
- libwayland-dev
|
- libwayland-dev
|
||||||
- libxkbcommon-dev
|
- libxkbcommon-dev
|
||||||
- libegl1-mesa-dev
|
- libegl1-mesa-dev
|
||||||
@ -49,20 +70,27 @@ matrix:
|
|||||||
- BUILD_SHARED_LIBS=OFF
|
- BUILD_SHARED_LIBS=OFF
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
- os: osx
|
- os: osx
|
||||||
|
sudo: false
|
||||||
|
name: "Cocoa shared library"
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=ON
|
- BUILD_SHARED_LIBS=ON
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
|
- MACOSX_DEPLOYMENT_TARGET=10.8
|
||||||
- os: osx
|
- os: osx
|
||||||
|
sudo: false
|
||||||
|
name: "Cocoa static library"
|
||||||
env:
|
env:
|
||||||
- BUILD_SHARED_LIBS=OFF
|
- BUILD_SHARED_LIBS=OFF
|
||||||
- CFLAGS=-Werror
|
- CFLAGS=-Werror
|
||||||
|
- MACOSX_DEPLOYMENT_TARGET=10.8
|
||||||
script:
|
script:
|
||||||
- if grep -Inr '\s$' src include docs tests examples CMake *.md .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
|
- if grep -Inr '\s$' src include docs tests examples CMake *.md .gitattributes .gitignore; then
|
||||||
|
echo Trailing whitespace found, aborting;
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- if test -n "${USE_WAYLAND}";
|
- if test -n "${USE_WAYLAND}"; then
|
||||||
then wget https://mirrors.kernel.org/ubuntu/pool/universe/e/extra-cmake-modules/extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
|
||||||
sudo dpkg -i extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
|
||||||
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
||||||
pushd wayland-protocols;
|
pushd wayland-protocols;
|
||||||
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
if (NOT EXISTS "@GLFW_BINARY_DIR@/install_manifest.txt")
|
||||||
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
message(FATAL_ERROR "Cannot find install manifest: \"@GLFW_BINARY_DIR@/install_manifest.txt\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
file(READ "@GLFW_BINARY_DIR@/install_manifest.txt" files)
|
||||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||||
|
|
||||||
foreach (file ${files})
|
foreach (file ${files})
|
@ -5,7 +5,7 @@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
|||||||
|
|
||||||
Name: GLFW
|
Name: GLFW
|
||||||
Description: A multi-platform library for OpenGL, window and input
|
Description: A multi-platform library for OpenGL, window and input
|
||||||
Version: @GLFW_VERSION_FULL@
|
Version: @GLFW_VERSION@
|
||||||
URL: https://www.glfw.org/
|
URL: https://www.glfw.org/
|
||||||
Requires.private: @GLFW_PKG_DEPS@
|
Requires.private: @GLFW_PKG_DEPS@
|
||||||
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
3
CMake/glfw3Config.cmake.in
Normal file
3
CMake/glfw3Config.cmake.in
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
find_dependency(Threads)
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
|
103
CMakeLists.txt
103
CMakeLists.txt
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
|
|
||||||
project(GLFW C)
|
project(GLFW VERSION 3.4.0 LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||||
|
|
||||||
@ -8,43 +8,34 @@ if (POLICY CMP0054)
|
|||||||
cmake_policy(SET CMP0054 NEW)
|
cmake_policy(SET CMP0054 NEW)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GLFW_VERSION_MAJOR "3")
|
if (POLICY CMP0077)
|
||||||
set(GLFW_VERSION_MINOR "4")
|
cmake_policy(SET CMP0077 NEW)
|
||||||
set(GLFW_VERSION_PATCH "0")
|
endif()
|
||||||
set(GLFW_VERSION_EXTRA "")
|
|
||||||
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
|
|
||||||
set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}")
|
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
set(GLFW_STANDALONE TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
|
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE})
|
||||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
|
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ${GLFW_STANDALONE})
|
||||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
||||||
option(GLFW_INSTALL "Generate installation target" ON)
|
option(GLFW_INSTALL "Generate installation target" ON)
|
||||||
option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the application" OFF)
|
option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the application" OFF)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
if (UNIX)
|
cmake_dependent_option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF
|
||||||
option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF)
|
"UNIX" OFF)
|
||||||
endif()
|
cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF
|
||||||
|
"WIN32" OFF)
|
||||||
if (WIN32)
|
cmake_dependent_option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF
|
||||||
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
|
"UNIX;NOT APPLE" OFF)
|
||||||
endif()
|
cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
|
||||||
|
"MSVC" OFF)
|
||||||
if (UNIX AND NOT APPLE)
|
|
||||||
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS)
|
|
||||||
set(_GLFW_BUILD_DLL 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS AND UNIX)
|
if (BUILD_SHARED_LIBS AND UNIX)
|
||||||
# On Unix-like systems, shared libraries can use the soname system.
|
# On Unix-like systems, shared libraries can use the soname system.
|
||||||
@ -80,7 +71,7 @@ if (MSVC)
|
|||||||
include(CheckIncludeFile)
|
include(CheckIncludeFile)
|
||||||
check_include_file(dinput.h DINPUT_H_FOUND)
|
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||||
if (NOT DINPUT_H_FOUND)
|
if (NOT DINPUT_H_FOUND)
|
||||||
message(FATAL_ERROR "DirectX 9 SDK not found")
|
message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
|
||||||
endif()
|
endif()
|
||||||
# Workaround for VS 2008 not shipping with stdint.h
|
# Workaround for VS 2008 not shipping with stdint.h
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
|
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
|
||||||
@ -204,36 +195,33 @@ if (_GLFW_X11)
|
|||||||
|
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED)
|
||||||
|
|
||||||
list(APPEND glfw_PKG_DEPS "x11")
|
|
||||||
|
|
||||||
# Set up library and include paths
|
# Set up library and include paths
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
|
list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
|
||||||
list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
|
|
||||||
# Check for XRandR (modern resolution switching and gamma control)
|
# Check for XRandR (modern resolution switching and gamma control)
|
||||||
if (NOT X11_Xrandr_FOUND)
|
if (NOT X11_Xrandr_INCLUDE_PATH)
|
||||||
message(FATAL_ERROR "The RandR headers were not found")
|
message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for Xinerama (legacy multi-monitor support)
|
# Check for Xinerama (legacy multi-monitor support)
|
||||||
if (NOT X11_Xinerama_FOUND)
|
if (NOT X11_Xinerama_INCLUDE_PATH)
|
||||||
message(FATAL_ERROR "The Xinerama headers were not found")
|
message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for Xkb (X keyboard extension)
|
# Check for Xkb (X keyboard extension)
|
||||||
if (NOT X11_Xkb_FOUND)
|
if (NOT X11_Xkb_INCLUDE_PATH)
|
||||||
message(FATAL_ERROR "The X keyboard extension headers were not found")
|
message(FATAL_ERROR "XKB headers not found; install X11 development package")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for Xcursor (cursor creation from RGBA images)
|
# Check for Xcursor (cursor creation from RGBA images)
|
||||||
if (NOT X11_Xcursor_FOUND)
|
if (NOT X11_Xcursor_INCLUDE_PATH)
|
||||||
message(FATAL_ERROR "The Xcursor headers were not found")
|
message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
|
# Check for XInput (modern HID input)
|
||||||
"${X11_Xinerama_INCLUDE_PATH}"
|
if (NOT X11_Xi_INCLUDE_PATH)
|
||||||
"${X11_Xkb_INCLUDE_PATH}"
|
message(FATAL_ERROR "XInput headers not found; install libxi development package")
|
||||||
"${X11_Xcursor_INCLUDE_PATH}")
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@ -247,10 +235,10 @@ if (_GLFW_WAYLAND)
|
|||||||
find_package(WaylandScanner REQUIRED)
|
find_package(WaylandScanner REQUIRED)
|
||||||
find_package(WaylandProtocols 1.15 REQUIRED)
|
find_package(WaylandProtocols 1.15 REQUIRED)
|
||||||
|
|
||||||
list(APPEND glfw_PKG_DEPS "wayland-egl")
|
list(APPEND glfw_PKG_DEPS "wayland-client")
|
||||||
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
|
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
|
||||||
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}")
|
||||||
|
|
||||||
find_package(XKBCommon REQUIRED)
|
find_package(XKBCommon REQUIRED)
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
||||||
@ -274,7 +262,6 @@ endif()
|
|||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (_GLFW_OSMESA)
|
if (_GLFW_OSMESA)
|
||||||
find_package(OSMesa REQUIRED)
|
find_package(OSMesa REQUIRED)
|
||||||
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@ -285,11 +272,10 @@ if (_GLFW_COCOA)
|
|||||||
list(APPEND glfw_LIBRARIES
|
list(APPEND glfw_LIBRARIES
|
||||||
"-framework Cocoa"
|
"-framework Cocoa"
|
||||||
"-framework IOKit"
|
"-framework IOKit"
|
||||||
"-framework CoreFoundation"
|
"-framework CoreFoundation")
|
||||||
"-framework CoreVideo")
|
|
||||||
|
|
||||||
set(glfw_PKG_DEPS "")
|
set(glfw_PKG_DEPS "")
|
||||||
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
|
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@ -316,18 +302,16 @@ include(CMakePackageConfigHelpers)
|
|||||||
|
|
||||||
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/glfw3")
|
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/glfw3")
|
||||||
|
|
||||||
configure_package_config_file(src/glfw3Config.cmake.in
|
configure_package_config_file(CMake/glfw3Config.cmake.in
|
||||||
src/glfw3Config.cmake
|
src/glfw3Config.cmake
|
||||||
INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
|
INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
|
||||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||||
|
|
||||||
write_basic_package_version_file(src/glfw3ConfigVersion.cmake
|
write_basic_package_version_file(src/glfw3ConfigVersion.cmake
|
||||||
VERSION ${GLFW_VERSION_FULL}
|
VERSION ${GLFW_VERSION}
|
||||||
COMPATIBILITY SameMajorVersion)
|
COMPATIBILITY SameMajorVersion)
|
||||||
|
|
||||||
configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
|
configure_file(CMake/glfw3.pc.in src/glfw3.pc @ONLY)
|
||||||
|
|
||||||
configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY)
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Add subdirectories
|
# Add subdirectories
|
||||||
@ -364,9 +348,14 @@ if (GLFW_INSTALL)
|
|||||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
|
|
||||||
|
if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
|
||||||
|
install(DIRECTORY "${GLFW_BINARY_DIR}/docs/html"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
if (NOT TARGET uninstall)
|
if (NOT TARGET uninstall)
|
||||||
configure_file(cmake_uninstall.cmake.in
|
configure_file(CMake/cmake_uninstall.cmake.in
|
||||||
cmake_uninstall.cmake IMMEDIATE @ONLY)
|
cmake_uninstall.cmake IMMEDIATE @ONLY)
|
||||||
|
|
||||||
add_custom_target(uninstall
|
add_custom_target(uninstall
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
Copyright (c) 2002-2006 Marcus Geelnard
|
Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
|
Copyright (c) 2006-2019 Camilla Löwy
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
86
README.md
86
README.md
@ -11,7 +11,7 @@ application development. It provides a simple, platform-independent API for
|
|||||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||||
|
|
||||||
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
|
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
|
||||||
Linux both X11 and Wayland is supported.
|
Linux both X11 and Wayland are supported.
|
||||||
|
|
||||||
GLFW is licensed under the [zlib/libpng
|
GLFW is licensed under the [zlib/libpng
|
||||||
license](http://www.glfw.org/license.html).
|
license](http://www.glfw.org/license.html).
|
||||||
@ -85,10 +85,11 @@ in the documentation for more information.
|
|||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
GLFW itself depends only on the headers and libraries for your window system.
|
GLFW itself needs only CMake 3.1 or later and the headers and libraries for your
|
||||||
|
OS and window system.
|
||||||
|
|
||||||
The (experimental) Wayland backend also depends on the `extra-cmake-modules`
|
The (experimental) Wayland backend also depends on the `extra-cmake-modules`
|
||||||
package, which is used to generated Wayland protocol headers.
|
package, which is used to generate Wayland protocol headers.
|
||||||
|
|
||||||
The examples and test programs depend on a number of tiny libraries. These are
|
The examples and test programs depend on a number of tiny libraries. These are
|
||||||
located in the `deps/` directory.
|
located in the `deps/` directory.
|
||||||
@ -118,7 +119,64 @@ information on what to include when reporting a bug.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- [X11] Bugfix: Simultanous key presses were being ignored (#1112)
|
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
|
||||||
|
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427)
|
||||||
|
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
||||||
|
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
|
||||||
|
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
|
||||||
|
- Updated the minimum required CMake version to 3.1
|
||||||
|
- 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
|
||||||
|
relocatable (#1470)
|
||||||
|
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
|
||||||
|
- Bugfix: Compiling with -Wextra-semi caused warnings (#1440)
|
||||||
|
- Bugfix: Built-in mappings failed because some OEMs re-used VID/PID (#1583)
|
||||||
|
- [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access
|
||||||
|
to the window menu
|
||||||
|
- [Win32] Added a version info resource to the GLFW DLL
|
||||||
|
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
|
||||||
|
symbol redefinition (#1524)
|
||||||
|
- [Win32] Bugfix: The cursor position event was emitted before its cursor enter
|
||||||
|
event (#1490)
|
||||||
|
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
|
||||||
|
window (#1499)
|
||||||
|
- [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions
|
||||||
|
- [Win32] Bugfix: Super key was not released after Win+V hotkey (#1622)
|
||||||
|
- [Win32] Bugfix: `glfwGetKeyName` could access out of bounds and return an
|
||||||
|
invalid pointer
|
||||||
|
- [Win32] Bugfix: Some synthetic key events were reported as `GLFW_KEY_UNKNOWN`
|
||||||
|
(#1623)
|
||||||
|
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||||
|
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||||
|
- [Cocoa] Removed dependency on the CoreVideo framework
|
||||||
|
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
|
||||||
|
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
|
||||||
|
(#1412)
|
||||||
|
- [Cocoa] Bugfix: Event processing before window creation would assert (#1543)
|
||||||
|
- [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS
|
||||||
|
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
|
||||||
|
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
|
||||||
|
(#1462,#1528)
|
||||||
|
- [X11] Bugfix: Decorations could not be enabled after window creation (#1566)
|
||||||
|
- [X11] Bugfix: Content scale fallback value could be inconsistent (#1578)
|
||||||
|
- [X11] Bugfix: `glfwMaximizeWindow` had no effect on hidden windows
|
||||||
|
- [X11] Bugfix: Clearing `GLFW_FLOATING` on a hidden window caused invalid read
|
||||||
|
- [X11] Bugfix: Changing `GLFW_FLOATING` on a hidden window could silently fail
|
||||||
|
- [X11] Bugfix: Disabled cursor mode was interrupted by indicator windows
|
||||||
|
- [X11] Bugfix: Monitor physical dimensions could be reported as zero mm
|
||||||
|
- [X11] Bugfix: Window position events were not emitted during resizing (#1613)
|
||||||
|
- [X11] Bugfix: `glfwFocusWindow` could terminate on older WMs or without a WM
|
||||||
|
- [X11] Bugfix: Querying a disconnected monitor could segfault (#1602)
|
||||||
|
- [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636)
|
||||||
|
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||||
|
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
||||||
|
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
||||||
|
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||||
|
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
|
||||||
|
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
|
||||||
|
macOS versions (#1442)
|
||||||
|
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
|
||||||
|
- [X11] Bugfix: Simultanous key presses were being ignored (#1112)
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
@ -127,7 +185,7 @@ On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as
|
|||||||
well as news, documentation and other information about the project.
|
well as news, documentation and other information about the project.
|
||||||
|
|
||||||
If you have questions related to the use of GLFW, we have a
|
If you have questions related to the use of GLFW, we have a
|
||||||
[forum](http://discourse.glfw.org/), and the `#glfw` IRC channel on
|
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||||
[Freenode](http://freenode.net/).
|
[Freenode](http://freenode.net/).
|
||||||
|
|
||||||
If you have a bug to report, a patch to submit or a feature you'd like to
|
If you have a bug to report, a patch to submit or a feature you'd like to
|
||||||
@ -157,6 +215,7 @@ skills.
|
|||||||
- blanco
|
- blanco
|
||||||
- Kyle Brenneman
|
- Kyle Brenneman
|
||||||
- Rok Breulj
|
- Rok Breulj
|
||||||
|
- Kai Burjack
|
||||||
- Martin Capitanio
|
- Martin Capitanio
|
||||||
- David Carlier
|
- David Carlier
|
||||||
- Arturo Castro
|
- Arturo Castro
|
||||||
@ -189,6 +248,8 @@ skills.
|
|||||||
- Mário Freitas
|
- Mário Freitas
|
||||||
- GeO4d
|
- GeO4d
|
||||||
- Marcus Geelnard
|
- Marcus Geelnard
|
||||||
|
- Charles Giessen
|
||||||
|
- Ryan C. Gordon
|
||||||
- Stephen Gowen
|
- Stephen Gowen
|
||||||
- Kovid Goyal
|
- Kovid Goyal
|
||||||
- Eloi Marín Gratacós
|
- Eloi Marín Gratacós
|
||||||
@ -200,6 +261,7 @@ skills.
|
|||||||
- Lucas Hinderberger
|
- Lucas Hinderberger
|
||||||
- Paul Holden
|
- Paul Holden
|
||||||
- Warren Hu
|
- Warren Hu
|
||||||
|
- Charles Huber
|
||||||
- IntellectualKitty
|
- IntellectualKitty
|
||||||
- Aaron Jacobs
|
- Aaron Jacobs
|
||||||
- Erik S. V. Jansson
|
- Erik S. V. Jansson
|
||||||
@ -208,17 +270,24 @@ skills.
|
|||||||
- Cem Karan
|
- Cem Karan
|
||||||
- Osman Keskin
|
- Osman Keskin
|
||||||
- Josh Kilmer
|
- Josh Kilmer
|
||||||
|
- Byunghoon Kim
|
||||||
- Cameron King
|
- Cameron King
|
||||||
- Peter Knut
|
- Peter Knut
|
||||||
- Christoph Kubisch
|
- Christoph Kubisch
|
||||||
- Yuri Kunde Schlesner
|
- Yuri Kunde Schlesner
|
||||||
|
- Rokas Kupstys
|
||||||
- Konstantin Käfer
|
- Konstantin Käfer
|
||||||
- Eric Larson
|
- Eric Larson
|
||||||
|
- Francis Lecavalier
|
||||||
- Robin Leffmann
|
- Robin Leffmann
|
||||||
- Glenn Lewis
|
- Glenn Lewis
|
||||||
- Shane Liesegang
|
- Shane Liesegang
|
||||||
|
- Anders Lindqvist
|
||||||
|
- Leon Linhart
|
||||||
- Eyal Lotem
|
- Eyal Lotem
|
||||||
- Aaron Loucks
|
- Aaron Loucks
|
||||||
|
- Luflosi
|
||||||
|
- lukect
|
||||||
- Tristam MacDonald
|
- Tristam MacDonald
|
||||||
- Hans Mackowiak
|
- Hans Mackowiak
|
||||||
- Дмитри Малышев
|
- Дмитри Малышев
|
||||||
@ -231,6 +300,7 @@ skills.
|
|||||||
- Jonathan Mercier
|
- Jonathan Mercier
|
||||||
- Marcel Metz
|
- Marcel Metz
|
||||||
- Liam Middlebrook
|
- Liam Middlebrook
|
||||||
|
- Ave Milia
|
||||||
- Jonathan Miller
|
- Jonathan Miller
|
||||||
- Kenneth Miller
|
- Kenneth Miller
|
||||||
- Bruce Mitchener
|
- Bruce Mitchener
|
||||||
@ -258,9 +328,13 @@ skills.
|
|||||||
- Cyril Pichard
|
- Cyril Pichard
|
||||||
- Keith Pitt
|
- Keith Pitt
|
||||||
- Stanislav Podgorskiy
|
- Stanislav Podgorskiy
|
||||||
|
- Konstantin Podsvirov
|
||||||
- Nathan Poirier
|
- Nathan Poirier
|
||||||
- Alexandre Pretyman
|
- Alexandre Pretyman
|
||||||
|
- Pablo Prietz
|
||||||
- przemekmirek
|
- przemekmirek
|
||||||
|
- pthom
|
||||||
|
- Guillaume Racicot
|
||||||
- Philip Rideout
|
- Philip Rideout
|
||||||
- Eddie Ringle
|
- Eddie Ringle
|
||||||
- Max Risuhin
|
- Max Risuhin
|
||||||
@ -290,6 +364,7 @@ skills.
|
|||||||
- Paul Sultana
|
- Paul Sultana
|
||||||
- Nathan Sweet
|
- Nathan Sweet
|
||||||
- TTK-Bandit
|
- TTK-Bandit
|
||||||
|
- Jared Tiala
|
||||||
- Sergey Tikhomirov
|
- Sergey Tikhomirov
|
||||||
- Arthur Tombs
|
- Arthur Tombs
|
||||||
- Ioannis Tsakpinis
|
- Ioannis Tsakpinis
|
||||||
@ -309,6 +384,7 @@ skills.
|
|||||||
- Jay Weisskopf
|
- Jay Weisskopf
|
||||||
- Frank Wille
|
- Frank Wille
|
||||||
- Ryogo Yoshimura
|
- Ryogo Yoshimura
|
||||||
|
- Lukas Zanner
|
||||||
- Andrey Zholos
|
- Andrey Zholos
|
||||||
- Santi Zupancic
|
- Santi Zupancic
|
||||||
- Jonas Ådahl
|
- Jonas Ådahl
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
|
|
||||||
set(glfw_DOCS_SOURCES
|
# NOTE: The order of this list determines the order of items in the Guides
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
# (i.e. Pages) list in the generated documentation
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
|
set(GLFW_DOXYGEN_SOURCES
|
||||||
"${GLFW_SOURCE_DIR}/docs/main.dox"
|
"include/GLFW/glfw3.h"
|
||||||
"${GLFW_SOURCE_DIR}/docs/news.dox"
|
"include/GLFW/glfw3native.h"
|
||||||
"${GLFW_SOURCE_DIR}/docs/quick.dox"
|
"docs/main.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/moving.dox"
|
"docs/news.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/compile.dox"
|
"docs/quick.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/build.dox"
|
"docs/moving.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/intro.dox"
|
"docs/compile.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/context.dox"
|
"docs/build.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/monitor.dox"
|
"docs/intro.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/window.dox"
|
"docs/context.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/input.dox"
|
"docs/monitor.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/vulkan.dox"
|
"docs/window.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/compat.dox"
|
"docs/input.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/internal.dox")
|
"docs/vulkan.dox"
|
||||||
|
"docs/compat.dox"
|
||||||
|
"docs/internal.dox")
|
||||||
|
|
||||||
foreach(arg ${glfw_DOCS_SOURCES})
|
# Format the source list into a Doxyfile INPUT value that Doxygen can parse
|
||||||
set(GLFW_DOCS_SOURCES "${GLFW_DOCS_SOURCES} \\\n\"${arg}\"")
|
foreach(path IN LISTS GLFW_DOXYGEN_SOURCES)
|
||||||
|
set(GLFW_DOXYGEN_INPUT "${GLFW_DOXYGEN_INPUT} \\\n\"${GLFW_SOURCE_DIR}/${path}\"")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||||
@ -27,3 +30,5 @@ add_custom_target(docs ALL "${DOXYGEN_EXECUTABLE}"
|
|||||||
WORKING_DIRECTORY "${GLFW_BINARY_DIR}/docs"
|
WORKING_DIRECTORY "${GLFW_BINARY_DIR}/docs"
|
||||||
COMMENT "Generating HTML documentation" VERBATIM)
|
COMMENT "Generating HTML documentation" VERBATIM)
|
||||||
|
|
||||||
|
set_target_properties(docs PROPERTIES FOLDER "GLFW3")
|
||||||
|
|
||||||
|
10
docs/CODEOWNERS
Normal file
10
docs/CODEOWNERS
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
* @elmindreda
|
||||||
|
|
||||||
|
src/wl_* @linkmauve
|
||||||
|
|
||||||
|
docs/*.css @glfw/webdev
|
||||||
|
docs/*.less @glfw/webdev
|
||||||
|
docs/*.html @glfw/webdev
|
||||||
|
docs/*.xml @glfw/webdev
|
||||||
|
|
@ -20,14 +20,14 @@
|
|||||||
## Asking a question
|
## Asking a question
|
||||||
|
|
||||||
Questions about how to use GLFW should be asked either in the [support
|
Questions about how to use GLFW should be asked either in the [support
|
||||||
section](http://discourse.glfw.org/c/support) of the forum, under the [Stack
|
section](https://discourse.glfw.org/c/support) of the forum, under the [Stack
|
||||||
Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
|
Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
|
||||||
Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
|
Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
|
||||||
Stack Exchange or in the IRC channel `#glfw` on
|
Stack Exchange or in the IRC channel `#glfw` on
|
||||||
[Freenode](http://freenode.net/).
|
[Freenode](http://freenode.net/).
|
||||||
|
|
||||||
Questions about the design or implementation of GLFW or about future plans
|
Questions about the design or implementation of GLFW or about future plans
|
||||||
should be asked in the [dev section](http://discourse.glfw.org/c/dev) of the
|
should be asked in the [dev section](https://discourse.glfw.org/c/dev) of the
|
||||||
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
|
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
|
||||||
questions without first checking with a maintainer.
|
questions without first checking with a maintainer.
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ PROJECT_NAME = "GLFW"
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = @GLFW_VERSION_FULL@
|
PROJECT_NUMBER = @GLFW_VERSION@
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer
|
# for a project that appears at the top of each page and should give viewer
|
||||||
@ -200,6 +200,7 @@ ALIASES = "thread_safety=@par Thread safety^^" \
|
|||||||
"analysis=@par Analysis^^" \
|
"analysis=@par Analysis^^" \
|
||||||
"reentrancy=@par Reentrancy^^" \
|
"reentrancy=@par Reentrancy^^" \
|
||||||
"errors=@par Errors^^" \
|
"errors=@par Errors^^" \
|
||||||
|
"callback_signature=@par Callback signature^^" \
|
||||||
"glfw3=__GLFW 3:__" \
|
"glfw3=__GLFW 3:__" \
|
||||||
"x11=__X11:__" \
|
"x11=__X11:__" \
|
||||||
"wayland=__Wayland:__" \
|
"wayland=__Wayland:__" \
|
||||||
@ -662,7 +663,7 @@ WARN_LOGFILE = "@GLFW_BINARY_DIR@/docs/warnings.txt"
|
|||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# with spaces.
|
||||||
|
|
||||||
INPUT = @GLFW_DOCS_SOURCES@
|
INPUT = @GLFW_DOXYGEN_INPUT@
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||||
@ -1631,11 +1632,6 @@ ALLEXTERNALS = NO
|
|||||||
|
|
||||||
EXTERNAL_GROUPS = YES
|
EXTERNAL_GROUPS = YES
|
||||||
|
|
||||||
# The PERL_PATH should be the absolute path and name of the perl script
|
|
||||||
# interpreter (i.e. the result of `which perl').
|
|
||||||
|
|
||||||
PERL_PATH = /usr/bin/perl
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the dot tool
|
# Configuration options related to the dot tool
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -1648,15 +1644,6 @@ PERL_PATH = /usr/bin/perl
|
|||||||
|
|
||||||
CLASS_DIAGRAMS = YES
|
CLASS_DIAGRAMS = YES
|
||||||
|
|
||||||
# You can define message sequence charts within doxygen comments using the \msc
|
|
||||||
# command. Doxygen will then run the mscgen tool (see
|
|
||||||
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
|
|
||||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
|
||||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
|
||||||
# default search path.
|
|
||||||
|
|
||||||
MSCGEN_PATH =
|
|
||||||
|
|
||||||
# If set to YES, the inheritance and collaboration graphs will hide
|
# If set to YES, the inheritance and collaboration graphs will hide
|
||||||
# inheritance and usage relations if the target is undocumented
|
# inheritance and usage relations if the target is undocumented
|
||||||
# or is not a class.
|
# or is not a class.
|
||||||
@ -1727,7 +1714,7 @@ UML_LOOK = NO
|
|||||||
# the class node. If there are many fields or methods and many nodes the
|
# the class node. If there are many fields or methods and many nodes the
|
||||||
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
|
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
|
||||||
# threshold limits the number of items for each type to make the size more
|
# threshold limits the number of items for each type to make the size more
|
||||||
# managable. Set this to 0 for no limit. Note that the threshold may be
|
# manageable. Set this to 0 for no limit. Note that the threshold may be
|
||||||
# exceeded by 50% before the limit is enforced.
|
# exceeded by 50% before the limit is enforced.
|
||||||
|
|
||||||
UML_LIMIT_NUM_FIELDS = 10
|
UML_LIMIT_NUM_FIELDS = 10
|
||||||
|
14
docs/SUPPORT.md
Normal file
14
docs/SUPPORT.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Support resources
|
||||||
|
|
||||||
|
See the [latest documentation](http://www.glfw.org/docs/latest/) for tutorials,
|
||||||
|
guides and the API reference.
|
||||||
|
|
||||||
|
If you have questions about using GLFW, we have a
|
||||||
|
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||||
|
[Freenode](http://freenode.net/).
|
||||||
|
|
||||||
|
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||||
|
Please check the [contribution
|
||||||
|
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||||
|
information on what to include when reporting a bug.
|
||||||
|
|
140
docs/build.dox
140
docs/build.dox
@ -78,6 +78,11 @@ compiler that the GLFW functions are defined in a DLL.
|
|||||||
The following macros control which OpenGL or OpenGL ES API header is included.
|
The following macros control which OpenGL or OpenGL ES API header is included.
|
||||||
Only one of these may be defined at a time.
|
Only one of these may be defined at a time.
|
||||||
|
|
||||||
|
@note GLFW does not provide any of the API headers mentioned below. They are
|
||||||
|
provided by your development environment or your OpenGL, OpenGL ES or Vulkan
|
||||||
|
SDK, and most of them can be downloaded from the
|
||||||
|
[Khronos Registry](https://www.khronos.org/registry/).
|
||||||
|
|
||||||
@anchor GLFW_INCLUDE_GLCOREARB
|
@anchor GLFW_INCLUDE_GLCOREARB
|
||||||
__GLFW_INCLUDE_GLCOREARB__ makes the GLFW header include the modern
|
__GLFW_INCLUDE_GLCOREARB__ makes the GLFW header include the modern
|
||||||
`GL/glcorearb.h` header (`OpenGL/gl3.h` on macOS) instead of the regular OpenGL
|
`GL/glcorearb.h` header (`OpenGL/gl3.h` on macOS) instead of the regular OpenGL
|
||||||
@ -129,10 +134,6 @@ header selected above. This should only be used with the standard OpenGL header
|
|||||||
and only for compatibility with legacy code. GLU has been deprecated and should
|
and only for compatibility with legacy code. GLU has been deprecated and should
|
||||||
not be used in new code.
|
not be used in new code.
|
||||||
|
|
||||||
@note GLFW does not provide any of the API headers mentioned above. They must
|
|
||||||
be provided by your development environment or your OpenGL, OpenGL ES or Vulkan
|
|
||||||
SDK.
|
|
||||||
|
|
||||||
@note None of these macros may be defined during the compilation of GLFW itself.
|
@note None of these macros may be defined during the compilation of GLFW itself.
|
||||||
If your build includes GLFW and you define any these in your build files, make
|
If your build includes GLFW and you define any these in your build files, make
|
||||||
sure they are not applied to the GLFW sources.
|
sure they are not applied to the GLFW sources.
|
||||||
@ -166,16 +167,11 @@ must also explicitly link with `gdi32`. Other toolchains including MinGW-w64
|
|||||||
include it in the set of default libraries along with other dependencies like
|
include it in the set of default libraries along with other dependencies like
|
||||||
`user32` and `kernel32`.
|
`user32` and `kernel32`.
|
||||||
|
|
||||||
If you are using GLU, you must also link with `glu32`.
|
|
||||||
|
|
||||||
The link library for the GLFW DLL is named `glfw3dll`. When compiling an
|
The link library for the GLFW DLL is named `glfw3dll`. When compiling an
|
||||||
application that uses the DLL version of GLFW, you need to define the @ref
|
application that uses the DLL version of GLFW, you need to define the @ref
|
||||||
GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done
|
GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done
|
||||||
either with a compiler switch or by defining it in your source code.
|
either with a compiler switch or by defining it in your source code.
|
||||||
|
|
||||||
An application using the GLFW DLL does not need to link against any of its
|
|
||||||
dependencies, but you still have to link against `glu32` if it uses GLU.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_cmake_source With CMake and GLFW source
|
@subsection build_link_cmake_source With CMake and GLFW source
|
||||||
|
|
||||||
@ -186,62 +182,39 @@ build_link_cmake_package.
|
|||||||
With a few changes to your `CMakeLists.txt` you can have the GLFW source tree
|
With a few changes to your `CMakeLists.txt` you can have the GLFW source tree
|
||||||
built along with your application.
|
built along with your application.
|
||||||
|
|
||||||
When including GLFW as part of your build, you probably don't want to build the
|
Add the root directory of the GLFW source tree to your project. This will add
|
||||||
GLFW tests, examples and documentation. To disable these, set the corresponding
|
the `glfw` target to your project.
|
||||||
cache variables before adding the GLFW source tree.
|
|
||||||
|
|
||||||
@code
|
|
||||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
|
||||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|
||||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Then add the root directory of the GLFW source tree to your project. This
|
|
||||||
will add the `glfw` target and the necessary cache variables to your project.
|
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
add_subdirectory(path/to/glfw)
|
add_subdirectory(path/to/glfw)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Once GLFW has been added to the project, link against it with the `glfw` target.
|
Once GLFW has been added, link your application against the `glfw` target.
|
||||||
This adds all link-time dependencies of GLFW as it is currently configured,
|
This adds the GLFW library and its link-time dependencies as it is currently
|
||||||
the include directory for the GLFW header and, when applicable, the @ref
|
configured, the include directory for the GLFW header and, when applicable, the
|
||||||
GLFW_DLL macro.
|
@ref GLFW_DLL macro.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_link_libraries(myapp glfw)
|
target_link_libraries(myapp glfw)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
|
Note that the `glfw` target does not depend on OpenGL, as GLFW loads any OpenGL,
|
||||||
OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
|
OpenGL ES or Vulkan libraries it needs at runtime. If your application calls
|
||||||
If your application calls OpenGL directly, instead of using a modern
|
OpenGL directly, instead of using a modern
|
||||||
[extension loader library](@ref context_glext_auto) you can find it by requiring
|
[extension loader library](@ref context_glext_auto), use the OpenGL CMake
|
||||||
the OpenGL package.
|
package.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If OpenGL is found, the `OPENGL_FOUND` variable is true and the
|
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
||||||
`OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used.
|
library and include directory paths. Link against this like above.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_include_directories(myapp PUBLIC ${OPENGL_INCLUDE_DIR})
|
target_link_libraries(myapp OpenGL::GL)
|
||||||
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The OpenGL CMake package also looks for GLU. If GLU is found, the
|
|
||||||
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and
|
|
||||||
`OPENGL_glu_LIBRARY` cache variables can be used.
|
|
||||||
|
|
||||||
@code{.cmake}
|
|
||||||
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
||||||
|
|
||||||
@ -257,44 +230,30 @@ find_package(glfw3 3.4 REQUIRED)
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Once GLFW has been added to the project, link against it with the `glfw` target.
|
Once GLFW has been added to the project, link against it with the `glfw` target.
|
||||||
This adds all link-time dependencies of GLFW as it is currently configured,
|
This adds the GLFW library and its link-time dependencies, the include directory
|
||||||
the include directory for the GLFW header and, when applicable, the @ref
|
for the GLFW header and, when applicable, the @ref GLFW_DLL macro.
|
||||||
GLFW_DLL macro.
|
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_link_libraries(myapp glfw)
|
target_link_libraries(myapp glfw)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
|
Note that the `glfw` target does not depend on OpenGL, as GLFW loads any OpenGL,
|
||||||
OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
|
OpenGL ES or Vulkan libraries it needs at runtime. If your application calls
|
||||||
If your application calls OpenGL directly, instead of using a modern
|
OpenGL directly, instead of using a modern
|
||||||
[extension loader library](@ref context_glext_auto) you can find it by requiring
|
[extension loader library](@ref context_glext_auto), use the OpenGL CMake
|
||||||
the OpenGL package.
|
package.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If OpenGL is found, the `OPENGL_FOUND` variable is true and the
|
If OpenGL is found, the `OpenGL::GL` target is added to your project, containing
|
||||||
`OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used.
|
library and include directory paths. Link against this like above.
|
||||||
|
|
||||||
@code{.cmake}
|
@code{.cmake}
|
||||||
target_include_directories(myapp PUBLIC ${OPENGL_INCLUDE_DIR})
|
target_link_libraries(myapp OpenGL::GL)
|
||||||
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The OpenGL CMake package also looks for GLU. If GLU is found, the
|
|
||||||
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and
|
|
||||||
`OPENGL_glu_LIBRARY` cache variables can be used.
|
|
||||||
|
|
||||||
@code{.cmake}
|
|
||||||
target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
||||||
|
|
||||||
@ -309,42 +268,31 @@ A typical compile and link command-line when using the static version of the
|
|||||||
GLFW library may look like this:
|
GLFW library may look like this:
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3`
|
cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --static --libs glfw3)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If you are using the shared version of the GLFW library, omit the `--static`
|
If you are using the shared version of the GLFW library, omit the `--static`
|
||||||
flag.
|
flag.
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`
|
cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --libs glfw3)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
You can also use the `glfw3.pc` file without installing it first, by using the
|
You can also use the `glfw3.pc` file without installing it first, by using the
|
||||||
`PKG_CONFIG_PATH` environment variable.
|
`PKG_CONFIG_PATH` environment variable.
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`
|
env PKG_CONFIG_PATH=path/to/glfw/src cc $(pkg-config --cflags glfw3) -o myprog myprog.c $(pkg-config --libs glfw3)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The dependencies do not include OpenGL or GLU, as GLFW loads any OpenGL, OpenGL
|
The dependencies do not include OpenGL, as GLFW loads any OpenGL, OpenGL ES or
|
||||||
ES or Vulkan libraries it needs at runtime and does not use GLU. On macOS, GLU
|
Vulkan libraries it needs at runtime. If your application calls OpenGL
|
||||||
is built into the OpenGL framework, so if you need GLU you don't need to do
|
directly, instead of using a modern
|
||||||
anything extra. If you need GLU and are using Linux or BSD, you should add the
|
[extension loader library](@ref context_glext_auto), you should add the `gl`
|
||||||
`glu` pkg-config package.
|
pkg-config package.
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu`
|
cc $(pkg-config --cflags glfw3 gl) -o myprog myprog.c $(pkg-config --libs glfw3 gl)
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
If you are using the static version of the GLFW library, make sure you don't
|
|
||||||
link statically against GLU.
|
|
||||||
|
|
||||||
@code{.sh}
|
|
||||||
cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --static --libs glfw3` `pkg-config --libs glu`
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@ -354,8 +302,8 @@ If you are using the dynamic library version of GLFW, add it to the project
|
|||||||
dependencies.
|
dependencies.
|
||||||
|
|
||||||
If you are using the static library version of GLFW, add it and the Cocoa,
|
If you are using the static library version of GLFW, add it and the Cocoa,
|
||||||
OpenGL, IOKit and CoreVideo frameworks to the project as dependencies. They can
|
OpenGL and IOKit frameworks to the project as dependencies. They can all be
|
||||||
all be found in `/System/Library/Frameworks`.
|
found in `/System/Library/Frameworks`.
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_osx With command-line on macOS
|
@subsection build_link_osx With command-line on macOS
|
||||||
@ -369,7 +317,7 @@ the `-l` and `-framework` switches.
|
|||||||
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
|
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
|
||||||
|
|
||||||
@code{.sh}
|
@code{.sh}
|
||||||
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
|
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
|
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`
|
||||||
@ -378,9 +326,7 @@ for `-lglfw`.
|
|||||||
Note that you do not add the `.framework` extension to a framework when linking
|
Note that you do not add the `.framework` extension to a framework when linking
|
||||||
against it from the command-line.
|
against it from the command-line.
|
||||||
|
|
||||||
The OpenGL framework contains both the OpenGL and GLU APIs, so there is nothing
|
@note Your machine may have `libGL.*.dylib` style OpenGL library, but that is
|
||||||
special to do when using GLU. Also note that even though your machine may have
|
for the X Window System and will not work with the macOS native version of GLFW.
|
||||||
`libGL`-style OpenGL libraries, they are for use with the X Window System and
|
|
||||||
will _not_ work with the macOS native version of GLFW.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -85,6 +85,13 @@ transparent window framebuffers. If the running X server does not support this
|
|||||||
extension or there is no running compositing manager, the
|
extension or there is no running compositing manager, the
|
||||||
`GLFW_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
|
`GLFW_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
|
||||||
|
|
||||||
|
GLFW uses both the Xcursor extension and the freedesktop cursor conventions to
|
||||||
|
provide an expanded set of standard cursor shapes. If the running X server does
|
||||||
|
not support this extension or the current cursor theme does not support the
|
||||||
|
conventions, the `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR` and
|
||||||
|
`GLFW_NOT_ALLOWED_CURSOR` shapes will not be available and other shapes may use
|
||||||
|
legacy images.
|
||||||
|
|
||||||
|
|
||||||
@section compat_wayland Wayland protocols and IPC standards
|
@section compat_wayland Wayland protocols and IPC standards
|
||||||
|
|
||||||
@ -104,7 +111,7 @@ has been configured in the compositor.
|
|||||||
GLFW uses the [xdg-shell
|
GLFW uses the [xdg-shell
|
||||||
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
|
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
|
||||||
to provide better window management. This protocol is part of
|
to provide better window management. This protocol is part of
|
||||||
wayland-protocols 1.12, and mandatory at build time.
|
wayland-protocols 1.12, and is mandatory for GLFW to display a window.
|
||||||
|
|
||||||
GLFW uses the [relative pointer
|
GLFW uses the [relative pointer
|
||||||
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml)
|
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/relative-pointer/relative-pointer-unstable-v1.xml)
|
||||||
@ -230,8 +237,7 @@ at most OpenGL version 2.1.
|
|||||||
|
|
||||||
Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
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_FORWARD_COMPAT` hint must be set to
|
given version 3.0 or 3.1. The `GLFW_OPENGL_PROFILE` hint must be set to
|
||||||
`GLFW_TRUE` and 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_OPENGL_DEBUG_CONTEXT` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
|
||||||
|
|
||||||
@ -262,10 +268,10 @@ surfaces on Microsoft Windows. If any of these extensions are not available,
|
|||||||
@ref glfwGetRequiredInstanceExtensions will return an empty list and window
|
@ref glfwGetRequiredInstanceExtensions will return an empty list and window
|
||||||
surface creation will fail.
|
surface creation will fail.
|
||||||
|
|
||||||
GLFW uses the `VK_KHR_surface` and `VK_MVK_macos_surface` extensions to create
|
GLFW uses the `VK_KHR_surface` and either the `VK_MVK_macos_surface` or
|
||||||
surfaces on macOS. If any of these extensions are not available, @ref
|
`VK_EXT_metal_surface` extensions to create surfaces on macOS. If any of these
|
||||||
glfwGetRequiredInstanceExtensions will return an empty list and window surface
|
extensions are not available, @ref glfwGetRequiredInstanceExtensions will
|
||||||
creation will fail.
|
return an empty list and window surface creation will fail.
|
||||||
|
|
||||||
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
|
GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or
|
||||||
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
|
`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface`
|
||||||
|
@ -212,11 +212,13 @@ library or as a DLL / shared library / dynamic library.
|
|||||||
|
|
||||||
@anchor GLFW_BUILD_EXAMPLES
|
@anchor GLFW_BUILD_EXAMPLES
|
||||||
__GLFW_BUILD_EXAMPLES__ determines whether the GLFW examples are built
|
__GLFW_BUILD_EXAMPLES__ determines whether the GLFW examples are built
|
||||||
along with the library.
|
along with the library. This is enabled by default unless GLFW is being built
|
||||||
|
as a sub-project.
|
||||||
|
|
||||||
@anchor GLFW_BUILD_TESTS
|
@anchor GLFW_BUILD_TESTS
|
||||||
__GLFW_BUILD_TESTS__ determines whether the GLFW test programs are
|
__GLFW_BUILD_TESTS__ determines whether the GLFW test programs are
|
||||||
built along with the library.
|
built along with the library. This is enabled by default unless GLFW is being
|
||||||
|
built as a sub-project.
|
||||||
|
|
||||||
@anchor GLFW_BUILD_DOCS
|
@anchor GLFW_BUILD_DOCS
|
||||||
__GLFW_BUILD_DOCS__ determines whether the GLFW documentation is built along
|
__GLFW_BUILD_DOCS__ determines whether the GLFW documentation is built along
|
||||||
|
@ -373,12 +373,15 @@ A cursor with a [standard shape](@ref shapes) from the current system cursor
|
|||||||
theme can be can be created with @ref glfwCreateStandardCursor.
|
theme can be can be created with @ref glfwCreateStandardCursor.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
|
GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
These cursor objects behave in the exact same way as those created with @ref
|
These cursor objects behave in the exact same way as those created with @ref
|
||||||
glfwCreateCursor except that the system cursor theme provides the actual image.
|
glfwCreateCursor except that the system cursor theme provides the actual image.
|
||||||
|
|
||||||
|
A few of these shapes are not available everywhere. If a shape is unavailable,
|
||||||
|
`NULL` is returned. See @ref glfwCreateStandardCursor for details.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection cursor_destruction Cursor destruction
|
@subsubsection cursor_destruction Cursor destruction
|
||||||
|
|
||||||
@ -864,31 +867,32 @@ GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime.
|
|||||||
double seconds = glfwGetTime();
|
double seconds = glfwGetTime();
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
It returns the number of seconds since the timer was started when the library
|
It returns the number of seconds since the library was initialized with @ref
|
||||||
was initialized with @ref glfwInit. The platform-specific time sources used
|
glfwInit. The platform-specific time sources used typically have micro- or
|
||||||
usually have micro- or nanosecond resolution.
|
nanosecond resolution.
|
||||||
|
|
||||||
You can modify the reference time with @ref glfwSetTime.
|
You can modify the base time with @ref glfwSetTime.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
glfwSetTime(4.0);
|
glfwSetTime(4.0);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
This sets the timer to the specified time, in seconds.
|
This sets the time to the specified time, in seconds, and it continues to count
|
||||||
|
from there.
|
||||||
|
|
||||||
You can also access the raw timer value, measured in 1 / frequency
|
You can also access the raw timer used to implement the functions above,
|
||||||
seconds, with @ref glfwGetTimerValue.
|
with @ref glfwGetTimerValue.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
uint64_t value = glfwGetTimerValue();
|
uint64_t value = glfwGetTimerValue();
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The frequency of the raw timer varies depending on what time sources are
|
This value is in 1 / frequency seconds. The frequency of the raw
|
||||||
available on the machine. You can query its frequency, in Hz, with @ref
|
timer varies depending on the operating system and hardware. You can query the
|
||||||
glfwGetTimerFrequency.
|
frequency, in Hz, with @ref glfwGetTimerFrequency.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
uint64_t freqency = glfwGetTimerFrequency();
|
uint64_t frequency = glfwGetTimerFrequency();
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ for a disconnected monitor and only before the monitor callback returns.
|
|||||||
@section monitor_properties Monitor properties
|
@section monitor_properties Monitor properties
|
||||||
|
|
||||||
Each monitor has a current video mode, a list of supported video modes,
|
Each monitor has a current video mode, a list of supported video modes,
|
||||||
a virtual position, a human-readable name, a user pointer, an estimated physical
|
a virtual position, a content scale, a human-readable name, a user pointer, an
|
||||||
size and a gamma ramp.
|
estimated physical size and a gamma ramp.
|
||||||
|
|
||||||
|
|
||||||
@subsection monitor_modes Video modes
|
@subsection monitor_modes Video modes
|
||||||
|
912
docs/news.dox
912
docs/news.dox
@ -9,8 +9,55 @@
|
|||||||
|
|
||||||
@subsection features_34 New features in version 3.4
|
@subsection features_34 New features in version 3.4
|
||||||
|
|
||||||
|
@subsubsection standard_cursors_34 More standard cursors
|
||||||
|
|
||||||
|
GLFW now provides the standard cursor shapes @ref GLFW_RESIZE_NWSE_CURSOR and
|
||||||
|
@ref GLFW_RESIZE_NESW_CURSOR for diagonal resizing, @ref GLFW_RESIZE_ALL_CURSOR
|
||||||
|
for omni-directional resizing and @ref GLFW_NOT_ALLOWED_CURSOR for showing an
|
||||||
|
action is not allowed.
|
||||||
|
|
||||||
|
Unlike the original set, these shapes may not be available everywhere and
|
||||||
|
creation will then fail with the new @ref GLFW_CURSOR_UNAVAILABLE error.
|
||||||
|
|
||||||
|
The cursors for horizontal and vertical resizing are now referred to as @ref
|
||||||
|
GLFW_RESIZE_EW_CURSOR and @ref GLFW_RESIZE_NS_CURSOR, and the pointing hand
|
||||||
|
cursor is now referred to as @ref GLFW_POINTING_HAND_CURSOR. The older names
|
||||||
|
are still available.
|
||||||
|
|
||||||
|
For more information see @ref cursor_standard.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
|
||||||
|
|
||||||
|
GLFW now provides the
|
||||||
|
[GLFW_WIN32_KEYBOARD_MENU](@ref GLFW_WIN32_KEYBOARD_MENU_hint) window hint for
|
||||||
|
enabling keyboard access to the window menu via the Alt+Space and
|
||||||
|
Alt-and-then-Space shortcuts. This may be useful for more GUI-oriented
|
||||||
|
applications.
|
||||||
|
|
||||||
|
|
||||||
@subsection caveats_34 Caveats for version 3.4
|
@subsection caveats_34 Caveats for version 3.4
|
||||||
|
|
||||||
|
@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
|
||||||
|
a subdirectory of another CMake project. To enable these, set the @ref
|
||||||
|
GLFW_BUILD_TESTS and @ref GLFW_BUILD_EXAMPLES cache variables before adding the
|
||||||
|
GLFW subdirectory.
|
||||||
|
|
||||||
|
@code{.cmake}
|
||||||
|
set(GLFW_BUILD_EXAMPLES ON CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_BUILD_TESTS ON CACHE BOOL "" FORCE)
|
||||||
|
add_subdirectory(path/to/glfw)
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection corevideo_34 CoreVideo dependency has been removed
|
||||||
|
|
||||||
|
GLFW no longer depends on the CoreVideo framework on macOS and it no longer
|
||||||
|
needs to be specified during compilation or linking.
|
||||||
|
|
||||||
|
|
||||||
@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
|
||||||
@ -21,853 +68,22 @@
|
|||||||
@subsubsection types_34 New types in version 3.4
|
@subsubsection types_34 New types in version 3.4
|
||||||
@subsubsection constants_34 New constants in version 3.4
|
@subsubsection constants_34 New constants in version 3.4
|
||||||
|
|
||||||
|
- @ref GLFW_POINTING_HAND_CURSOR
|
||||||
@section news_33 Release notes for version 3.3
|
- @ref GLFW_RESIZE_EW_CURSOR
|
||||||
|
- @ref GLFW_RESIZE_NS_CURSOR
|
||||||
These are the release notes for version 3.3. For a more detailed view including
|
- @ref GLFW_RESIZE_NWSE_CURSOR
|
||||||
all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
|
- @ref GLFW_RESIZE_NESW_CURSOR
|
||||||
|
- @ref GLFW_RESIZE_ALL_CURSOR
|
||||||
Please review the caveats, deprecations and removals if your project was written
|
- @ref GLFW_NOT_ALLOWED_CURSOR
|
||||||
against an earlier version of GLFW 3.
|
- @ref GLFW_CURSOR_UNAVAILABLE
|
||||||
|
- @ref GLFW_WIN32_KEYBOARD_MENU
|
||||||
|
|
||||||
@subsection features_33 New features in version 3.3
|
|
||||||
|
@section news_archive Release notes for earlier versions
|
||||||
@subsubsection gamepad_33 Gamepad input via SDL_GameControllerDB
|
|
||||||
|
- [Release notes for 3.3](https://www.glfw.org/docs/3.3/news.html)
|
||||||
GLFW can now remap game controllers to a standard Xbox-like layout using
|
- [Release notes for 3.2](https://www.glfw.org/docs/3.2/news.html)
|
||||||
a built-in copy of SDL_GameControllerDB. Call @ref glfwJoystickIsGamepad to
|
- [Release notes for 3.1](https://www.glfw.org/docs/3.1/news.html)
|
||||||
check if a joystick has a mapping, @ref glfwGetGamepadState to retrieve its
|
- [Release notes for 3.0](https://www.glfw.org/docs/3.0/news.html)
|
||||||
input state, @ref glfwUpdateGamepadMappings to add newer mappings and @ref
|
|
||||||
glfwGetGamepadName and @ref glfwGetJoystickGUID for mapping related information.
|
|
||||||
|
|
||||||
For more information see @ref gamepad.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection moltenvk_33 Support for Vulkan on macOS via MoltenVK
|
|
||||||
|
|
||||||
GLFW now supports [MoltenVK](https://moltengl.com/moltenvk/), a Vulkan
|
|
||||||
implementation on top of the Metal API, and its `VK_MVK_macos_surface` window
|
|
||||||
surface creation extension. MoltenVK is included in the [macOS Vulkan
|
|
||||||
SDK](https://vulkan.lunarg.com/).
|
|
||||||
|
|
||||||
For more information see @ref vulkan_guide.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection content_scale_33 Content scale queries for DPI-aware rendering
|
|
||||||
|
|
||||||
GLFW now provides content scales for windows and monitors, i.e. the ratio
|
|
||||||
between their current DPI and the platform's default DPI, with @ref
|
|
||||||
glfwGetWindowContentScale and @ref glfwGetMonitorContentScale.
|
|
||||||
|
|
||||||
Changes of the content scale of a window can be received with the window content
|
|
||||||
scale callback, set with @ref glfwSetWindowContentScaleCallback.
|
|
||||||
|
|
||||||
The @ref GLFW_SCALE_TO_MONITOR window hint enables automatic resizing of a
|
|
||||||
window by the content scale of the monitor it is placed, on platforms like
|
|
||||||
Windows where this is necessary. This takes effect both on creation and when
|
|
||||||
the window is moved between monitors. It is related to but different from
|
|
||||||
[GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint).
|
|
||||||
|
|
||||||
For more information see @ref window_scale.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection setwindowattrib_33 Support for updating window attributes
|
|
||||||
|
|
||||||
GLFW now supports changing the [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
|
|
||||||
[GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib),
|
|
||||||
[GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
|
|
||||||
[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
|
|
||||||
[GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib) attributes for existing
|
|
||||||
windows with @ref glfwSetWindowAttrib.
|
|
||||||
|
|
||||||
For more information see @ref window_attribs.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection raw_motion_33 Support for raw mouse motion
|
|
||||||
|
|
||||||
GLFW now supports raw (unscaled and unaccelerated) mouse motion in disabled
|
|
||||||
cursor mode with the [GLFW_RAW_MOUSE_MOTION](@ref GLFW_RAW_MOUSE_MOTION) input
|
|
||||||
mode. Raw mouse motion input is not yet implemented on macOS. Call @ref
|
|
||||||
glfwRawMouseMotionSupported to check if GLFW can provide raw mouse motion on the
|
|
||||||
current system.
|
|
||||||
|
|
||||||
For more information see @ref raw_mouse_motion.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection joysticks_33 Joystick hats
|
|
||||||
|
|
||||||
GLFW can now return the state of hats (i.e. POVs or D-pads) of a joystick with
|
|
||||||
@ref glfwGetJoystickHats. For compatibility, hats are also exposed as buttons.
|
|
||||||
This can be disabled with the @ref GLFW_JOYSTICK_HAT_BUTTONS initialization
|
|
||||||
hint.
|
|
||||||
|
|
||||||
For more information see @ref joystick_hat.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection geterror_33 Error query
|
|
||||||
|
|
||||||
GLFW now supports querying the last error code for the calling thread and its
|
|
||||||
human-readable description with @ref glfwGetError. This can be used instead of
|
|
||||||
or together with the error callback.
|
|
||||||
|
|
||||||
For more information see @ref error_handling.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_33 Support for initialization hints
|
|
||||||
|
|
||||||
GLFW now supports setting library initialization hints with @ref glfwInitHint.
|
|
||||||
These must be set before initialization to take effect. Some of these hints are
|
|
||||||
platform specific but are safe to set on any platform.
|
|
||||||
|
|
||||||
For more information see @ref init_hints.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection attention_33 User attention request
|
|
||||||
|
|
||||||
GLFW now supports requesting user attention with @ref
|
|
||||||
glfwRequestWindowAttention. Where possible this calls attention to the
|
|
||||||
specified window. On platforms like macOS it calls attention to the whole
|
|
||||||
application.
|
|
||||||
|
|
||||||
For more information see @ref window_attention.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection maximize_33 Window maximization callback
|
|
||||||
|
|
||||||
GLFW now supports notifying the application that the window has been maximized
|
|
||||||
@ref glfwSetWindowMaximizeCallback. This is called both when the window was
|
|
||||||
maximized by the user and when it was done with @ref glfwMaximizeWindow.
|
|
||||||
|
|
||||||
For more information see @ref window_maximize.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection workarea_33 Query for the monitor work area
|
|
||||||
|
|
||||||
GLFW now supports querying the work area of a monitor, i.e. the area not
|
|
||||||
occupied by task bars or global menu bars, with @ref glfwGetMonitorWorkarea. On
|
|
||||||
platforms that lack this concept, the whole area of the monitor is returned.
|
|
||||||
|
|
||||||
For more information see @ref monitor_workarea.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection transparency_33 Transparent windows and framebuffers
|
|
||||||
|
|
||||||
GLFW now supports the creation of windows with transparent framebuffers on
|
|
||||||
systems with desktop compositing enabled with the @ref
|
|
||||||
GLFW_TRANSPARENT_FRAMEBUFFER window hint and attribute. This hint must be set
|
|
||||||
before window creation and leaves any window decorations opaque.
|
|
||||||
|
|
||||||
GLFW now also supports whole window transparency with @ref glfwGetWindowOpacity
|
|
||||||
and @ref glfwSetWindowOpacity. This value controls the opacity of the whole
|
|
||||||
window including decorations and unlike framebuffer transparency can be changed
|
|
||||||
at any time after window creation.
|
|
||||||
|
|
||||||
For more information see @ref window_transparency.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection key_scancode_33 Query for the scancode of a key
|
|
||||||
|
|
||||||
GLFW now supports querying the platform dependent scancode of any physical key
|
|
||||||
with @ref glfwGetKeyScancode.
|
|
||||||
|
|
||||||
For more information see @ref input_key.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection center_cursor_33 Cursor centering window hint
|
|
||||||
|
|
||||||
GLFW now supports controlling whether the cursor is centered over newly created
|
|
||||||
full screen windows with the [GLFW_CENTER_CURSOR](@ref GLFW_CENTER_CURSOR_hint)
|
|
||||||
window hint. It is enabled by default.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection cursor_hover_33 Mouse cursor hover window attribute
|
|
||||||
|
|
||||||
GLFW now supports polling whether the cursor is hovering over the window content
|
|
||||||
area with the [GLFW_HOVERED](@ref GLFW_HOVERED_attrib) window attribute. This
|
|
||||||
attribute corresponds to the [cursor enter/leave](@ref cursor_enter) event.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection focusonshow_33 Window hint and attribute for input focus on show
|
|
||||||
|
|
||||||
GLFW now has the [GLFW_FOCUS_ON_SHOW](@ref GLFW_DECORATED_hint) window hint and
|
|
||||||
attribute for controlling whether a window gets input focus when shown. It is
|
|
||||||
enabled by default. It applies both when creating an visible window with @ref
|
|
||||||
glfwCreateWindow and when showing it with @ref glfwShowWindow.
|
|
||||||
|
|
||||||
This is a workaround for GLFW 3.0 lacking @ref glfwFocusWindow and will be
|
|
||||||
corrected in the next major version.
|
|
||||||
|
|
||||||
For more information see @ref window_hide.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection device_userptr_33 Monitor and joystick user pointers
|
|
||||||
|
|
||||||
GLFW now supports setting and querying user pointers for connected monitors and
|
|
||||||
joysticks with @ref glfwSetMonitorUserPointer, @ref glfwGetMonitorUserPointer,
|
|
||||||
@ref glfwSetJoystickUserPointer and @ref glfwGetJoystickUserPointer.
|
|
||||||
|
|
||||||
For more information see @ref monitor_userptr and @ref joystick_userptr.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection macos_nib_33 macOS menu bar from nib file
|
|
||||||
|
|
||||||
GLFW will now load a `MainMenu.nib` file if found in the `Contents/Resources`
|
|
||||||
directory of the application bundle, as a way to replace the GLFW menu bar
|
|
||||||
without recompiling GLFW. This behavior can be disabled with the
|
|
||||||
[GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint) initialization hint.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection glext_33 Support for more context creation extensions
|
|
||||||
|
|
||||||
The context hint @ref GLFW_SRGB_CAPABLE now supports OpenGL ES via
|
|
||||||
`WGL_EXT_colorspace`, the context hint @ref GLFW_CONTEXT_NO_ERROR now supports
|
|
||||||
`WGL_ARB_create_context_no_error` and `GLX_ARB_create_context_no_error`, the
|
|
||||||
context hint @ref GLFW_CONTEXT_RELEASE_BEHAVIOR now supports
|
|
||||||
`EGL_KHR_context_flush_control` and @ref glfwGetProcAddress now supports
|
|
||||||
`EGL_KHR_get_all_proc_addresses`.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection osmesa_33 OSMesa off-screen context creation support
|
|
||||||
|
|
||||||
GLFW now supports creating off-screen OpenGL contexts using
|
|
||||||
[OSMesa](https://www.mesa3d.org/osmesa.html) by setting
|
|
||||||
[GLFW_CONTEXT_CREATION_API](@ref GLFW_CONTEXT_CREATION_API_hint) to
|
|
||||||
`GLFW_OSMESA_CONTEXT_API`. Native access function have been added to retrieve
|
|
||||||
the OSMesa color and depth buffers.
|
|
||||||
|
|
||||||
There is also a new null backend that uses OSMesa as its native context
|
|
||||||
creation API, intended for automated testing. This backend does not provide
|
|
||||||
input.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection caveats_33 Caveats for version 3.3
|
|
||||||
|
|
||||||
@subsubsection joystick_layout_33 Layout of joysticks have changed
|
|
||||||
|
|
||||||
The way joystick elements are arranged have changed to match SDL2 in order to
|
|
||||||
support SDL_GameControllerDB mappings. The layout of joysticks may
|
|
||||||
change again if required for compatibility with SDL2. If you need a known and
|
|
||||||
stable layout for game controllers, see if you can switch to @ref gamepad.
|
|
||||||
|
|
||||||
Existing code that depends on a specific joystick layout will likely have to be
|
|
||||||
updated.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection wait_events_33 No window required to wait for events
|
|
||||||
|
|
||||||
The @ref glfwWaitEvents and @ref glfwWaitEventsTimeout functions no longer need
|
|
||||||
a window to be created to wait for events. Before version 3.3 these functions
|
|
||||||
would return immediately if there were no user-created windows. On platforms
|
|
||||||
where only windows can receive events, an internal helper window is used.
|
|
||||||
|
|
||||||
Existing code that depends on the earlier behavior will likely have to be
|
|
||||||
updated.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection gamma_ramp_size_33 Gamma ramp size of 256 may be rejected
|
|
||||||
|
|
||||||
The documentation for versions before 3.3 stated that a gamma ramp size of 256
|
|
||||||
would always be accepted. This was never the case on X11 and could lead to
|
|
||||||
artifacts on macOS. The @ref glfwSetGamma function has been updated to always
|
|
||||||
generate a ramp of the correct size.
|
|
||||||
|
|
||||||
Existing code that hardcodes a size of 256 should be updated to use the size of
|
|
||||||
the current ramp of a monitor when setting a new ramp for that monitor.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection xinput_deadzone_33 Windows XInput deadzone removed
|
|
||||||
|
|
||||||
GLFW no longer applies any deadzone to the input state received from the XInput
|
|
||||||
API. This was never done for any other platform joystick API so this change
|
|
||||||
makes the behavior more consistent but you will need to apply your own deadzone
|
|
||||||
if desired.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection x11_clipboard_33 X11 clipboard transfer limits
|
|
||||||
|
|
||||||
GLFW now supports reading clipboard text via the `INCR` method, which removes
|
|
||||||
the limit on how much text can be read with @ref glfwGetClipboardString.
|
|
||||||
However, writing via this method is not yet supported, so you may not be able to
|
|
||||||
write a very large string with @ref glfwSetClipboardString even if you read it
|
|
||||||
from the clipboard earlier.
|
|
||||||
|
|
||||||
The exact size limit for writing to the clipboard is negotiated with each
|
|
||||||
receiving application but is at least several tens of kilobytes. Note that only
|
|
||||||
the read limit has changed. Any string that could be written before still can
|
|
||||||
be.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection x11_linking_33 X11 extension libraries are loaded dynamically
|
|
||||||
|
|
||||||
GLFW now loads all X11 extension libraries at initialization. The only X11
|
|
||||||
library you need to link against is `libX11`. The header files for the
|
|
||||||
extension libraries are still required for compilation.
|
|
||||||
|
|
||||||
Existing projects and makefiles that link GLFW directly against the extension
|
|
||||||
libraries should still build correctly but will add these libraries as load-time
|
|
||||||
dependencies.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection cmake_version_33 CMake 3.0 or later is required
|
|
||||||
|
|
||||||
The minimum CMake version has been raised from 2.8.12 to 3.0. This is only
|
|
||||||
a requirement of the GLFW CMake files. The GLFW source files do not depend on
|
|
||||||
CMake.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection deprecations_33 Deprecations in version 3.3
|
|
||||||
|
|
||||||
@subsubsection charmods_callback_33 Character with modifiers callback
|
|
||||||
|
|
||||||
The character with modifiers callback set with @ref glfwSetCharModsCallback has
|
|
||||||
been deprecated and should if possible not be used.
|
|
||||||
|
|
||||||
Existing code should still work but further bug fixes will likely not be made.
|
|
||||||
The callback will be removed in the next major version.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection clipboard_window_33 Window parameter to clipboard functions
|
|
||||||
|
|
||||||
The window parameter of the clipboard functions @ref glfwGetClipboardString and
|
|
||||||
@ref glfwSetClipboardString has been deprecated and is no longer used on any
|
|
||||||
platform. On platforms where the clipboard must be owned by a specific window,
|
|
||||||
an internal helper window is used.
|
|
||||||
|
|
||||||
Existing code should still work unless it depends on a specific window owning
|
|
||||||
the clipboard. New code may pass `NULL` as the window argument. The parameter
|
|
||||||
will be removed in a future release.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection removals_33 Removals in 3.3
|
|
||||||
|
|
||||||
@subsubsection macos_options_33 macOS specific CMake options and macros
|
|
||||||
|
|
||||||
The `GLFW_USE_RETINA`, `GLFW_USE_CHDIR` and `GLFW_USE_MENUBAR` CMake options and
|
|
||||||
the `_GLFW_USE_RETINA`, `_GLFW_USE_CHDIR` and `_GLFW_USE_MENUBAR` compile-time
|
|
||||||
macros have been removed.
|
|
||||||
|
|
||||||
These options and macros are replaced by the window hint
|
|
||||||
[GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
|
|
||||||
and the init hints
|
|
||||||
[GLFW_COCOA_CHDIR_RESOURCES](@ref GLFW_COCOA_CHDIR_RESOURCES_hint) and
|
|
||||||
[GLFW_COCOA_MENUBAR](@ref GLFW_COCOA_MENUBAR_hint).
|
|
||||||
|
|
||||||
Existing projects and makefiles that set these options or define these macros
|
|
||||||
during compilation of GLFW will still build but it will have no effect and the
|
|
||||||
default behaviors will be used.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection vulkan_sdk_33 LunarG Vulkan SDK dependency
|
|
||||||
|
|
||||||
The GLFW test programs that previously depended on the LunarG Vulkan SDK now
|
|
||||||
instead uses a Vulkan loader generated by
|
|
||||||
[glad2](https://github.com/Dav1dde/glad). This means the GLFW CMake files no
|
|
||||||
longer look for the Vulkan SDK.
|
|
||||||
|
|
||||||
Existing CMake projects that depended on the Vulkan SDK cache variables from
|
|
||||||
GLFW will need to call `find_package(Vulkan)` themselves. CMake 3.7 and later
|
|
||||||
already comes with a
|
|
||||||
[Vulkan find module](https://cmake.org/cmake/help/latest/module/FindVulkan.html)
|
|
||||||
similar to the one GLFW previously included.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection lib_suffix_33 CMake option LIB_SUFFIX
|
|
||||||
|
|
||||||
The `LIB_SUFFIX` CMake option has been removed. GLFW now uses the
|
|
||||||
GNUInstallDirs CMake package to handle platform specific details like the
|
|
||||||
library directory suffix and the `LIB_SUFFIX` CMake option has been removed.
|
|
||||||
|
|
||||||
Existing projects and makefiles that set the `LIB_SUFFIX` option will use the
|
|
||||||
suffix chosen by the GNUInstallDirs package and the option will be ignored.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection mir_removed_33 Mir support
|
|
||||||
|
|
||||||
The experimental Mir support has been completely removed as the Mir project has
|
|
||||||
implemented support for the Wayland protocol and is recommending that
|
|
||||||
applications use that instead.
|
|
||||||
|
|
||||||
Existing projects and makefiles that select Mir when compiling GLFW will fail.
|
|
||||||
Use Wayland or X11 instead.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection symbols_33 New symbols in version 3.3
|
|
||||||
|
|
||||||
@subsubsection functions_33 New functions in version 3.3
|
|
||||||
|
|
||||||
- @ref glfwInitHint
|
|
||||||
- @ref glfwGetError
|
|
||||||
- @ref glfwGetMonitorWorkarea
|
|
||||||
- @ref glfwGetMonitorContentScale
|
|
||||||
- @ref glfwGetMonitorUserPointer
|
|
||||||
- @ref glfwSetMonitorUserPointer
|
|
||||||
- @ref glfwWindowHintString
|
|
||||||
- @ref glfwGetWindowContentScale
|
|
||||||
- @ref glfwGetWindowOpacity
|
|
||||||
- @ref glfwSetWindowOpacity
|
|
||||||
- @ref glfwRequestWindowAttention
|
|
||||||
- @ref glfwSetWindowAttrib
|
|
||||||
- @ref glfwSetWindowMaximizeCallback
|
|
||||||
- @ref glfwSetWindowContentScaleCallback
|
|
||||||
- @ref glfwRawMouseMotionSupported
|
|
||||||
- @ref glfwGetKeyScancode
|
|
||||||
- @ref glfwGetJoystickHats
|
|
||||||
- @ref glfwGetJoystickGUID
|
|
||||||
- @ref glfwGetJoystickUserPointer
|
|
||||||
- @ref glfwSetJoystickUserPointer
|
|
||||||
- @ref glfwJoystickIsGamepad
|
|
||||||
- @ref glfwUpdateGamepadMappings
|
|
||||||
- @ref glfwGetGamepadName
|
|
||||||
- @ref glfwGetGamepadState
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection types_33 New types in version 3.3
|
|
||||||
|
|
||||||
- @ref GLFWwindowmaximizefun
|
|
||||||
- @ref GLFWwindowcontentscalefun
|
|
||||||
- @ref GLFWgamepadstate
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection constants_33 New constants in version 3.3
|
|
||||||
|
|
||||||
- @ref GLFW_NO_ERROR
|
|
||||||
- @ref GLFW_JOYSTICK_HAT_BUTTONS
|
|
||||||
- @ref GLFW_COCOA_CHDIR_RESOURCES
|
|
||||||
- @ref GLFW_COCOA_MENUBAR
|
|
||||||
- @ref GLFW_CENTER_CURSOR
|
|
||||||
- @ref GLFW_TRANSPARENT_FRAMEBUFFER
|
|
||||||
- @ref GLFW_HOVERED
|
|
||||||
- @ref GLFW_FOCUS_ON_SHOW
|
|
||||||
- @ref GLFW_SCALE_TO_MONITOR
|
|
||||||
- @ref GLFW_COCOA_RETINA_FRAMEBUFFER
|
|
||||||
- @ref GLFW_COCOA_FRAME_NAME
|
|
||||||
- @ref GLFW_COCOA_GRAPHICS_SWITCHING
|
|
||||||
- @ref GLFW_X11_CLASS_NAME
|
|
||||||
- @ref GLFW_X11_INSTANCE_NAME
|
|
||||||
- @ref GLFW_OSMESA_CONTEXT_API
|
|
||||||
- @ref GLFW_HAT_CENTERED
|
|
||||||
- @ref GLFW_HAT_UP
|
|
||||||
- @ref GLFW_HAT_RIGHT
|
|
||||||
- @ref GLFW_HAT_DOWN
|
|
||||||
- @ref GLFW_HAT_LEFT
|
|
||||||
- @ref GLFW_HAT_RIGHT_UP
|
|
||||||
- @ref GLFW_HAT_RIGHT_DOWN
|
|
||||||
- @ref GLFW_HAT_LEFT_UP
|
|
||||||
- @ref GLFW_HAT_LEFT_DOWN
|
|
||||||
- @ref GLFW_MOD_CAPS_LOCK
|
|
||||||
- @ref GLFW_MOD_NUM_LOCK
|
|
||||||
- @ref GLFW_LOCK_KEY_MODS
|
|
||||||
- @ref GLFW_RAW_MOUSE_MOTION
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_A
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_B
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_X
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_Y
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_LEFT_BUMPER
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_BACK
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_START
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_GUIDE
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_LEFT_THUMB
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_RIGHT_THUMB
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_DPAD_UP
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_DPAD_RIGHT
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_DPAD_DOWN
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_DPAD_LEFT
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_LAST
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_CROSS
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_CIRCLE
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_SQUARE
|
|
||||||
- @ref GLFW_GAMEPAD_BUTTON_TRIANGLE
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_LEFT_X
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_LEFT_Y
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_RIGHT_X
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_RIGHT_Y
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_LEFT_TRIGGER
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|
|
||||||
- @ref GLFW_GAMEPAD_AXIS_LAST
|
|
||||||
|
|
||||||
|
|
||||||
@section news_32 Release notes for 3.2
|
|
||||||
|
|
||||||
These are the release notes for version 3.2. For a more detailed view including
|
|
||||||
all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
|
|
||||||
|
|
||||||
|
|
||||||
@subsection features_32 New features in version 3.2
|
|
||||||
|
|
||||||
@subsubsection news_32_vulkan Support for Vulkan
|
|
||||||
|
|
||||||
GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported,
|
|
||||||
@ref glfwGetRequiredInstanceExtensions, @ref glfwGetInstanceProcAddress, @ref
|
|
||||||
glfwGetPhysicalDevicePresentationSupport and @ref glfwCreateWindowSurface.
|
|
||||||
Vulkan header inclusion can be selected with
|
|
||||||
@ref GLFW_INCLUDE_VULKAN.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_setwindowmonitor Window mode switching
|
|
||||||
|
|
||||||
GLFW now supports switching between windowed and full screen modes and updating
|
|
||||||
the monitor and desired resolution and refresh rate of full screen windows with
|
|
||||||
@ref glfwSetWindowMonitor.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_maximize Window maxmimization support
|
|
||||||
|
|
||||||
GLFW now supports window maximization with @ref glfwMaximizeWindow and the
|
|
||||||
@ref GLFW_MAXIMIZED window hint and attribute.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_focus Window input focus control
|
|
||||||
|
|
||||||
GLFW now supports giving windows input focus with @ref glfwFocusWindow.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_sizelimits Window size limit support
|
|
||||||
|
|
||||||
GLFW now supports setting both absolute and relative window size limits with
|
|
||||||
@ref glfwSetWindowSizeLimits and @ref glfwSetWindowAspectRatio.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_keyname Localized key names
|
|
||||||
|
|
||||||
GLFW now supports querying the localized name of printable keys with @ref
|
|
||||||
glfwGetKeyName, either by key token or by scancode.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_waittimeout Wait for events with timeout
|
|
||||||
|
|
||||||
GLFW now supports waiting for events for a set amount of time with @ref
|
|
||||||
glfwWaitEventsTimeout.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_icon Window icon support
|
|
||||||
|
|
||||||
GLFW now supports setting the icon of windows with @ref glfwSetWindowIcon.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_timer Raw timer access
|
|
||||||
|
|
||||||
GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref
|
|
||||||
glfwGetTimerFrequency.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_joystick Joystick connection callback
|
|
||||||
|
|
||||||
GLFW now supports notifying when a joystick has been connected or disconnected
|
|
||||||
with @ref glfwSetJoystickCallback.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_noapi Context-less windows
|
|
||||||
|
|
||||||
GLFW now supports creating windows without a OpenGL or OpenGL ES context by
|
|
||||||
setting the [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_NO_API`.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_contextapi Run-time context creation API selection
|
|
||||||
|
|
||||||
GLFW now supports selecting and querying the context creation API at run-time
|
|
||||||
with the @ref GLFW_CONTEXT_CREATION_API hint and attribute.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_noerror Error-free context creation
|
|
||||||
|
|
||||||
GLFW now supports creating and querying OpenGL and OpenGL ES contexts that do
|
|
||||||
not emit errors with the @ref GLFW_CONTEXT_NO_ERROR hint, provided the machine
|
|
||||||
supports the `GL_KHR_no_error` extension.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_32_cmake CMake config-file package support
|
|
||||||
|
|
||||||
GLFW now supports being used as a
|
|
||||||
[config-file package](@ref build_link_cmake_package) from other projects for
|
|
||||||
easy linking with the library and its dependencies.
|
|
||||||
|
|
||||||
|
|
||||||
@section news_31 Release notes for 3.1
|
|
||||||
|
|
||||||
These are the release notes for version 3.1. For a more detailed view including
|
|
||||||
all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
|
|
||||||
|
|
||||||
|
|
||||||
@subsection features_31 New features in version 3.1
|
|
||||||
|
|
||||||
@subsubsection news_31_cursor Custom mouse cursor images
|
|
||||||
|
|
||||||
GLFW now supports creating and setting both custom cursor images and standard
|
|
||||||
cursor shapes. They are created with @ref glfwCreateCursor or @ref
|
|
||||||
glfwCreateStandardCursor, set with @ref glfwSetCursor and destroyed with @ref
|
|
||||||
glfwDestroyCursor.
|
|
||||||
|
|
||||||
@see @ref cursor_object
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_drop Path drop event
|
|
||||||
|
|
||||||
GLFW now provides a callback for receiving the paths of files and directories
|
|
||||||
dropped onto GLFW windows. The callback is set with @ref glfwSetDropCallback.
|
|
||||||
|
|
||||||
@see @ref path_drop
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_emptyevent Main thread wake-up
|
|
||||||
|
|
||||||
GLFW now provides the @ref glfwPostEmptyEvent function for posting an empty
|
|
||||||
event from another thread to the main thread event queue, causing @ref
|
|
||||||
glfwWaitEvents to return.
|
|
||||||
|
|
||||||
@see @ref events
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_framesize Window frame size query
|
|
||||||
|
|
||||||
GLFW now supports querying the size, on each side, of the frame around the
|
|
||||||
content area of a window, with @ref glfwGetWindowFrameSize.
|
|
||||||
|
|
||||||
@see [Window size](@ref window_size)
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_autoiconify Simultaneous multi-monitor rendering
|
|
||||||
|
|
||||||
GLFW now supports disabling auto-iconification of full screen windows with
|
|
||||||
the [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_hint) window hint. This is
|
|
||||||
intended for people building multi-monitor installations, where you need windows
|
|
||||||
to stay in full screen despite losing input focus.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_floating Floating windows
|
|
||||||
|
|
||||||
GLFW now supports floating windows, also called topmost or always on top, for
|
|
||||||
easier debugging with the @ref GLFW_FLOATING window hint and attribute.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_focused Initially unfocused windows
|
|
||||||
|
|
||||||
GLFW now supports preventing a windowed mode window from gaining input focus on
|
|
||||||
creation, with the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) window hint.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_direct Direct access for window attributes and cursor position
|
|
||||||
|
|
||||||
GLFW now queries the window input focus, visibility and iconification attributes
|
|
||||||
and the cursor position directly instead of returning cached data.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_charmods Character with modifiers callback
|
|
||||||
|
|
||||||
GLFW now provides a callback for character events with modifier key bits. The
|
|
||||||
callback is set with @ref glfwSetCharModsCallback. Unlike the regular character
|
|
||||||
callback, this will report character events that will not result in a character
|
|
||||||
being input, for example if the Control key is held down.
|
|
||||||
|
|
||||||
@see @ref input_char
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_single Single buffered framebuffers
|
|
||||||
|
|
||||||
GLFW now supports the creation of single buffered windows, with the @ref
|
|
||||||
GLFW_DOUBLEBUFFER hint.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_glext Macro for including extension header
|
|
||||||
|
|
||||||
GLFW now includes the extension header appropriate for the chosen OpenGL or
|
|
||||||
OpenGL ES header when @ref GLFW_INCLUDE_GLEXT is defined. GLFW does not provide
|
|
||||||
these headers. They must be provided by your development environment or your
|
|
||||||
OpenGL or OpenGL ES SDK.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_release Context release behaviors
|
|
||||||
|
|
||||||
GLFW now supports controlling and querying whether the pipeline is flushed when
|
|
||||||
a context is made non-current, with the @ref GLFW_CONTEXT_RELEASE_BEHAVIOR hint
|
|
||||||
and attribute, provided the machine supports the `GL_KHR_context_flush_control`
|
|
||||||
extension.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_wayland (Experimental) Wayland support
|
|
||||||
|
|
||||||
GLFW now has an _experimental_ Wayland display protocol backend that can be
|
|
||||||
selected on Linux with a CMake option.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_31_mir (Experimental) Mir support
|
|
||||||
|
|
||||||
GLFW now has an _experimental_ Mir display server backend that can be selected
|
|
||||||
on Linux with a CMake option.
|
|
||||||
|
|
||||||
|
|
||||||
@section news_30 Release notes for 3.0
|
|
||||||
|
|
||||||
These are the release notes for version 3.0. For a more detailed view including
|
|
||||||
all fixed bugs see the [version history](https://www.glfw.org/changelog.html).
|
|
||||||
|
|
||||||
|
|
||||||
@subsection features_30 New features in version 3.0
|
|
||||||
|
|
||||||
@subsubsection news_30_cmake CMake build system
|
|
||||||
|
|
||||||
GLFW now uses the CMake build system instead of the various makefiles and
|
|
||||||
project files used by earlier versions. CMake is available for all platforms
|
|
||||||
supported by GLFW, is present in most package systems and can generate
|
|
||||||
makefiles and/or project files for most popular development environments.
|
|
||||||
|
|
||||||
For more information on how to use CMake, see the
|
|
||||||
[CMake manual](https://cmake.org/cmake/help/documentation.html).
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_multiwnd Multi-window support
|
|
||||||
|
|
||||||
GLFW now supports the creation of multiple windows, each with their own OpenGL
|
|
||||||
or OpenGL ES context, and all window functions now take a window handle. Event
|
|
||||||
callbacks are now per-window and are provided with the handle of the window that
|
|
||||||
received the event. The @ref glfwMakeContextCurrent function has been added to
|
|
||||||
select which context is current on a given thread.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_multimon Multi-monitor support
|
|
||||||
|
|
||||||
GLFW now explicitly supports multiple monitors. They can be enumerated with
|
|
||||||
@ref glfwGetMonitors, queried with @ref glfwGetVideoModes, @ref
|
|
||||||
glfwGetMonitorPos, @ref glfwGetMonitorName and @ref glfwGetMonitorPhysicalSize,
|
|
||||||
and specified at window creation to make the newly created window full screen on
|
|
||||||
that specific monitor.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_unicode Unicode support
|
|
||||||
|
|
||||||
All string arguments to GLFW functions and all strings returned by GLFW now use
|
|
||||||
the UTF-8 encoding. This includes the window title, error string, clipboard
|
|
||||||
text, monitor and joystick names as well as the extension function arguments (as
|
|
||||||
ASCII is a subset of UTF-8).
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_clipboard Clipboard text I/O
|
|
||||||
|
|
||||||
GLFW now supports reading and writing plain text to and from the system
|
|
||||||
clipboard, with the @ref glfwGetClipboardString and @ref glfwSetClipboardString
|
|
||||||
functions.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_gamma Gamma ramp support
|
|
||||||
|
|
||||||
GLFW now supports setting and reading back the gamma ramp of monitors, with the
|
|
||||||
@ref glfwGetGammaRamp and @ref glfwSetGammaRamp functions. There is also @ref
|
|
||||||
glfwSetGamma, which generates a ramp from a gamma value and then sets it.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_gles OpenGL ES support
|
|
||||||
|
|
||||||
GLFW now supports the creation of OpenGL ES contexts, by setting the
|
|
||||||
[GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint to `GLFW_OPENGL_ES_API`, where
|
|
||||||
creation of such contexts are supported. Note that GLFW _does not implement_
|
|
||||||
OpenGL ES, so your driver must provide support in a way usable by GLFW. Modern
|
|
||||||
Nvidia and Intel drivers support creation of OpenGL ES context using the GLX and
|
|
||||||
WGL APIs, while AMD provides an EGL implementation instead.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_egl (Experimental) EGL support
|
|
||||||
|
|
||||||
GLFW now has an experimental EGL context creation back end that can be selected
|
|
||||||
through CMake options.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_hidpi High-DPI support
|
|
||||||
|
|
||||||
GLFW now supports high-DPI monitors on both Windows and macOS, giving windows
|
|
||||||
full resolution framebuffers where other UI elements are scaled up. To achieve
|
|
||||||
this, @ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have
|
|
||||||
been added. These work with pixels, while the rest of the GLFW API works with
|
|
||||||
screen coordinates. This is important as OpenGL uses pixels, not screen
|
|
||||||
coordinates.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_error Error callback
|
|
||||||
|
|
||||||
GLFW now has an error callback, which can provide your application with much
|
|
||||||
more detailed diagnostics than was previously possible. The callback is passed
|
|
||||||
an error code and a description string.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_wndptr Per-window user pointer
|
|
||||||
|
|
||||||
Each window now has a user-defined pointer, retrieved with @ref
|
|
||||||
glfwGetWindowUserPointer and set with @ref glfwSetWindowUserPointer, to make it
|
|
||||||
easier to integrate GLFW into C++ code.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_iconifyfun Window iconification callback
|
|
||||||
|
|
||||||
Each window now has a callback for iconification and restoration events,
|
|
||||||
which is set with @ref glfwSetWindowIconifyCallback.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_wndposfun Window position callback
|
|
||||||
|
|
||||||
Each window now has a callback for position events, which is set with @ref
|
|
||||||
glfwSetWindowPosCallback.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_wndpos Window position query
|
|
||||||
|
|
||||||
The position of a window can now be retrieved using @ref glfwGetWindowPos.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_focusfun Window focus callback
|
|
||||||
|
|
||||||
Each windows now has a callback for focus events, which is set with @ref
|
|
||||||
glfwSetWindowFocusCallback.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_enterleave Cursor enter/leave callback
|
|
||||||
|
|
||||||
Each window now has a callback for when the mouse cursor enters or leaves its
|
|
||||||
content area, which is set with @ref glfwSetCursorEnterCallback.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_wndtitle Initial window title
|
|
||||||
|
|
||||||
The title of a window is now specified at creation time, as one of the arguments
|
|
||||||
to @ref glfwCreateWindow.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_hidden Hidden windows
|
|
||||||
|
|
||||||
Windows can now be hidden with @ref glfwHideWindow, shown using @ref
|
|
||||||
glfwShowWindow and created initially hidden with the @ref GLFW_VISIBLE window
|
|
||||||
hint and attribute. This allows for off-screen rendering in a way compatible
|
|
||||||
with most drivers, as well as moving a window to a specific position before
|
|
||||||
showing it.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_undecorated Undecorated windows
|
|
||||||
|
|
||||||
Windowed mode windows can now be created without decorations, e.g. things like
|
|
||||||
a frame, a title bar, with the @ref GLFW_DECORATED window hint and attribute.
|
|
||||||
This allows for the creation of things like splash screens.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_keymods Modifier key bit masks
|
|
||||||
|
|
||||||
[Modifier key bit mask](@ref mods) parameters have been added to the
|
|
||||||
[mouse button](@ref GLFWmousebuttonfun) and [key](@ref GLFWkeyfun) callbacks.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_scancode Platform-specific scancodes
|
|
||||||
|
|
||||||
A scancode parameter has been added to the [key callback](@ref GLFWkeyfun). Keys
|
|
||||||
that don't have a [key token](@ref keys) still get passed on with the key
|
|
||||||
parameter set to `GLFW_KEY_UNKNOWN`. These scancodes will vary between machines
|
|
||||||
and are intended to be used for key bindings.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_jsname Joystick names
|
|
||||||
|
|
||||||
The name of a joystick can now be retrieved using @ref glfwGetJoystickName.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection news_30_doxygen Doxygen documentation
|
|
||||||
|
|
||||||
You are reading it.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
@tableofcontents
|
@tableofcontents
|
||||||
|
|
||||||
This guide takes you through writing a simple application using GLFW 3. The
|
This guide takes you through writing a small application using GLFW 3. The
|
||||||
application will create a window and OpenGL context, render a rotating triangle
|
application will create a window and OpenGL context, render a rotating triangle
|
||||||
and exit when the user closes the window or presses _Escape_. This guide will
|
and exit when the user closes the window or presses _Escape_. This guide will
|
||||||
introduce a few of the most commonly used functions, but there are many more.
|
introduce a few of the most commonly used functions, but there are many more.
|
||||||
@ -135,9 +135,14 @@ require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and
|
|||||||
`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum
|
`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum
|
||||||
version is not supported on the machine, context (and window) creation fails.
|
version is not supported on the machine, context (and window) creation fails.
|
||||||
|
|
||||||
|
You can select the OpenGL profile by setting the `GLFW_OPENGL_PROFILE` hint.
|
||||||
|
This program uses the core profile as that is the only profile macOS supports
|
||||||
|
for OpenGL 3.x and 4.x.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
@ -326,19 +331,20 @@ for example, many kinds of editing tools.
|
|||||||
@section quick_example Putting it together
|
@section quick_example Putting it together
|
||||||
|
|
||||||
Now that you know how to initialize GLFW, create a window and poll for
|
Now that you know how to initialize GLFW, create a window and poll for
|
||||||
keyboard input, it's possible to create a simple program.
|
keyboard input, it's possible to create a small program.
|
||||||
|
|
||||||
This program creates a 640 by 480 windowed mode window and starts a loop that
|
This program creates a 640 by 480 windowed mode window and starts a loop that
|
||||||
clears the screen, renders a triangle and processes events until the user either
|
clears the screen, renders a triangle and processes events until the user either
|
||||||
presses _Escape_ or closes the window.
|
presses _Escape_ or closes the window.
|
||||||
|
|
||||||
@snippet simple.c code
|
@snippet triangle-opengl.c code
|
||||||
|
|
||||||
The program above can be found in the
|
The program above can be found in the
|
||||||
[source package](https://www.glfw.org/download.html) as `examples/simple.c`
|
[source package](https://www.glfw.org/download.html) as
|
||||||
and is compiled along with all other examples when you build GLFW. If you
|
`examples/triangle-opengl.c` and is compiled along with all other examples when
|
||||||
built GLFW from the source package then already have this as `simple.exe` on
|
you build GLFW. If you built GLFW from the source package then you already have
|
||||||
Windows, `simple` on Linux or `simple.app` on macOS.
|
this as `triangle-opengl.exe` on Windows, `triangle-opengl` on Linux or
|
||||||
|
`triangle-opengl.app` on macOS.
|
||||||
|
|
||||||
This tutorial used only a few of the many functions GLFW provides. There are
|
This tutorial used only a few of the many functions GLFW provides. There are
|
||||||
guides for each of the areas covered by GLFW. Each guide will introduce all the
|
guides for each of the areas covered by GLFW. Each guide will introduce all the
|
||||||
|
@ -234,6 +234,13 @@ 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`.
|
||||||
@ -383,12 +390,10 @@ Additionally, OpenGL ES 1.x cannot be returned if 2.0 or later was requested,
|
|||||||
and vice versa. This is because OpenGL ES 3.x is backward compatible with 2.0,
|
and vice versa. This is because OpenGL ES 3.x is backward compatible with 2.0,
|
||||||
but OpenGL ES 2.0 is not backward compatible with 1.x.
|
but OpenGL ES 2.0 is not backward compatible with 1.x.
|
||||||
|
|
||||||
@note @macos The OS only supports forward-compatible core profile contexts for
|
@note @macos The OS only supports core profile contexts for OpenGL versions 3.2
|
||||||
OpenGL versions 3.2 and later. Before creating an OpenGL context of version
|
and later. Before creating an OpenGL context of version 3.2 or later you must
|
||||||
3.2 or later you must set the
|
set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint accordingly.
|
||||||
[GLFW_OPENGL_FORWARD_COMPAT](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) and
|
OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
|
||||||
[GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hints accordingly. OpenGL
|
|
||||||
3.0 and 3.1 contexts are not supported at all on macOS.
|
|
||||||
|
|
||||||
@anchor GLFW_OPENGL_FORWARD_COMPAT_hint
|
@anchor GLFW_OPENGL_FORWARD_COMPAT_hint
|
||||||
__GLFW_OPENGL_FORWARD_COMPAT__ specifies whether the OpenGL context should be
|
__GLFW_OPENGL_FORWARD_COMPAT__ specifies whether the OpenGL context should be
|
||||||
@ -450,6 +455,14 @@ The no error mode for OpenGL and OpenGL ES is described in detail by the
|
|||||||
extension.
|
extension.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection window_hints_win32 Windows specific window hints
|
||||||
|
|
||||||
|
@anchor GLFW_WIN32_KEYBOARD_MENU_hint
|
||||||
|
__GLFW_WIN32_KEYBOARD_MENU__ specifies whether to allow access to the window
|
||||||
|
menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. This is
|
||||||
|
ignored on other platforms.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_osx macOS specific window hints
|
@subsubsection window_hints_osx macOS specific window hints
|
||||||
|
|
||||||
@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint
|
@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint
|
||||||
@ -530,6 +543,7 @@ GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_
|
|||||||
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_OPENGL_DEBUG_CONTEXT | `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_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_COCOA_FRAME_NAME | `""` | A UTF-8 encoded frame autosave name
|
GLFW_COCOA_FRAME_NAME | `""` | A UTF-8 encoded frame autosave name
|
||||||
GLFW_COCOA_GRAPHICS_SWITCHING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_COCOA_GRAPHICS_SWITCHING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
@ -1332,6 +1346,21 @@ unknown or the context is an OpenGL ES context. Note that the returned profile
|
|||||||
may not match the profile bits of the context flags, as GLFW will try other
|
may not match the profile bits of the context flags, as GLFW will try other
|
||||||
means of detecting the profile when no bits are set.
|
means of detecting the profile when no bits are set.
|
||||||
|
|
||||||
|
@anchor GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib
|
||||||
|
__GLFW_CONTEXT_RELEASE_BEHAVIOR__ indicates the release used by the context.
|
||||||
|
Possible values are one of `GLFW_ANY_RELEASE_BEHAVIOR`,
|
||||||
|
`GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`. If the
|
||||||
|
behavior is `GLFW_ANY_RELEASE_BEHAVIOR`, the default behavior of the context
|
||||||
|
creation API will be used. If the behavior is `GLFW_RELEASE_BEHAVIOR_FLUSH`,
|
||||||
|
the pipeline will be flushed whenever the context is released from being the
|
||||||
|
current one. If the behavior is `GLFW_RELEASE_BEHAVIOR_NONE`, the pipeline will
|
||||||
|
not be flushed on release.
|
||||||
|
|
||||||
|
@anchor GLFW_CONTEXT_NO_ERROR_attrib
|
||||||
|
__GLFW_CONTEXT_NO_ERROR__ indicates whether errors are generated by the context.
|
||||||
|
Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled, situations that
|
||||||
|
would have generated errors instead cause undefined behavior.
|
||||||
|
|
||||||
@anchor GLFW_CONTEXT_ROBUSTNESS_attrib
|
@anchor GLFW_CONTEXT_ROBUSTNESS_attrib
|
||||||
__GLFW_CONTEXT_ROBUSTNESS__ indicates the robustness strategy used by the
|
__GLFW_CONTEXT_ROBUSTNESS__ indicates the robustness strategy used by the
|
||||||
context. This is `GLFW_LOSE_CONTEXT_ON_RESET` or `GLFW_NO_RESET_NOTIFICATION`
|
context. This is `GLFW_LOSE_CONTEXT_ON_RESET` or `GLFW_NO_RESET_NOTIFICATION`
|
||||||
@ -1385,7 +1414,7 @@ glfwSwapBuffers(window);
|
|||||||
|
|
||||||
Sometimes it can be useful to select when the buffer swap will occur. With the
|
Sometimes it can be useful to select when the buffer swap will occur. With the
|
||||||
function @ref glfwSwapInterval it is possible to select the minimum number of
|
function @ref glfwSwapInterval it is possible to select the minimum number of
|
||||||
monitor refreshes the driver wait should from the time @ref glfwSwapBuffers was
|
monitor refreshes the driver should wait from the time @ref glfwSwapBuffers was
|
||||||
called before swapping the buffers:
|
called before swapping the buffers:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
link_libraries(glfw)
|
link_libraries(glfw)
|
||||||
|
|
||||||
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
|
include_directories("${GLFW_SOURCE_DIR}/deps")
|
||||||
|
|
||||||
if (MATH_LIBRARY)
|
if (MATH_LIBRARY)
|
||||||
link_libraries("${MATH_LIBRARY}")
|
link_libraries("${MATH_LIBRARY}")
|
||||||
@ -11,16 +11,10 @@ if (MSVC)
|
|||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GLFW_USE_OSMESA)
|
|
||||||
add_definitions(-DUSE_NATIVE_OSMESA)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(ICON glfw.rc)
|
set(ICON glfw.rc)
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
set(ICON glfw.icns)
|
set(ICON glfw.icns)
|
||||||
set_source_files_properties(glfw.icns PROPERTIES
|
|
||||||
MACOSX_PACKAGE_LOCATION "Resources")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h"
|
set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h"
|
||||||
@ -36,24 +30,30 @@ add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD_GL})
|
|||||||
add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL})
|
add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL})
|
||||||
add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL})
|
add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL})
|
||||||
add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL})
|
add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL})
|
||||||
add_executable(simple WIN32 MACOSX_BUNDLE simple.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(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
|
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
|
||||||
|
|
||||||
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}")
|
target_link_libraries(particles Threads::Threads)
|
||||||
if (RT_LIBRARY)
|
if (RT_LIBRARY)
|
||||||
target_link_libraries(particles "${RT_LIBRARY}")
|
target_link_libraries(particles "${RT_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WINDOWS_BINARIES boing gears heightmap particles sharing simple splitview wave)
|
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview
|
||||||
|
triangle-opengl wave)
|
||||||
set(CONSOLE_BINARIES offscreen)
|
set(CONSOLE_BINARIES offscreen)
|
||||||
|
|
||||||
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||||
|
C_STANDARD 99
|
||||||
FOLDER "GLFW3/Examples")
|
FOLDER "GLFW3/Examples")
|
||||||
|
|
||||||
|
if (GLFW_USE_OSMESA)
|
||||||
|
target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
||||||
set_target_properties(${WINDOWS_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||||
LINK_FLAGS "/ENTRY:mainCRTStartup")
|
LINK_FLAGS "/ENTRY:mainCRTStartup")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -63,15 +63,16 @@ if (APPLE)
|
|||||||
set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
|
set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
|
||||||
set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
|
set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
|
||||||
set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
|
set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
|
||||||
set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
|
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_BINARIES} PROPERTIES
|
set_source_files_properties(glfw.icns PROPERTIES
|
||||||
RESOURCE glfw.icns
|
MACOSX_PACKAGE_LOCATION "Resources")
|
||||||
|
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||||
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}
|
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
|
||||||
MACOSX_BUNDLE_ICON_FILE glfw.icns
|
MACOSX_BUNDLE_ICON_FILE glfw.icns
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in")
|
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/Info.plist.in")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <linmath.h>
|
#include <linmath.h>
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
/* Map height updates */
|
/* Map height updates */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#if USE_NATIVE_OSMESA
|
#if USE_NATIVE_OSMESA
|
||||||
@ -147,6 +148,7 @@ int main(void)
|
|||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
|
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
glFinish();
|
||||||
|
|
||||||
#if USE_NATIVE_OSMESA
|
#if USE_NATIVE_OSMESA
|
||||||
glfwGetOSMesaColorBuffer(window, &width, &height, NULL, (void**) &buffer);
|
glfwGetOSMesaColorBuffer(window, &width, &height, NULL, (void**) &buffer);
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <linmath.h>
|
#include <linmath.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
// Define tokens for GL_EXT_separate_specular_color if not already defined
|
// Define tokens for GL_EXT_separate_specular_color if not already defined
|
||||||
@ -443,7 +444,7 @@ static void draw_particles(GLFWwindow* window, double t, float dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set up vertex arrays. We use interleaved arrays, which is easier to
|
// Set up vertex arrays. We use interleaved arrays, which is easier to
|
||||||
// handle (in most situations) and it gives a linear memeory access
|
// handle (in most situations) and it gives a linear memory access
|
||||||
// access pattern (which may give better performance in some
|
// access pattern (which may give better performance in some
|
||||||
// situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords,
|
// situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords,
|
||||||
// 4 ubytes for color and 3 floats for vertex coord (in that order).
|
// 4 ubytes for color and 3 floats for vertex coord (in that order).
|
||||||
@ -653,7 +654,7 @@ static void draw_fountain(void)
|
|||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Recursive function for building variable tesselated floor
|
// Recursive function for building variable tessellated floor
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
static void tessellate_floor(float x1, float y1, float x2, float y2, int depth)
|
static void tessellate_floor(float x1, float y1, float x2, float y2, int depth)
|
||||||
@ -720,7 +721,7 @@ static void draw_floor(void)
|
|||||||
glMaterialfv(GL_FRONT, GL_SPECULAR, floor_specular);
|
glMaterialfv(GL_FRONT, GL_SPECULAR, floor_specular);
|
||||||
glMaterialf(GL_FRONT, GL_SHININESS, floor_shininess);
|
glMaterialf(GL_FRONT, GL_SHININESS, floor_shininess);
|
||||||
|
|
||||||
// Draw floor as a bunch of triangle strips (high tesselation
|
// Draw floor as a bunch of triangle strips (high tessellation
|
||||||
// improves lighting)
|
// improves lighting)
|
||||||
glNormal3f(0.f, 0.f, 1.f);
|
glNormal3f(0.f, 0.f, 1.f);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// The program uses a "split window" view, rendering four views of the
|
// The program uses a "split window" view, rendering four views of the
|
||||||
// same scene in one window (e.g. uesful for 3D modelling software). This
|
// same scene in one window (e.g. uesful for 3D modelling software). This
|
||||||
// demo uses scissors to separete the four different rendering areas from
|
// demo uses scissors to separate the four different rendering areas from
|
||||||
// each other.
|
// each other.
|
||||||
//
|
//
|
||||||
// (If the code seems a little bit strange here and there, it may be
|
// (If the code seems a little bit strange here and there, it may be
|
||||||
@ -11,6 +11,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// Simple GLFW example
|
// OpenGL triangle 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
|
||||||
@ -25,30 +25,34 @@
|
|||||||
//! [code]
|
//! [code]
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "linmath.h"
|
#include "linmath.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static const struct
|
typedef struct Vertex
|
||||||
{
|
{
|
||||||
float x, y;
|
vec2 pos;
|
||||||
float r, g, b;
|
vec3 col;
|
||||||
} vertices[3] =
|
} Vertex;
|
||||||
|
|
||||||
|
static const Vertex vertices[3] =
|
||||||
{
|
{
|
||||||
{ -0.6f, -0.4f, 1.f, 0.f, 0.f },
|
{ { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } },
|
||||||
{ 0.6f, -0.4f, 0.f, 1.f, 0.f },
|
{ { 0.6f, -0.4f }, { 0.f, 1.f, 0.f } },
|
||||||
{ 0.f, 0.6f, 0.f, 0.f, 1.f }
|
{ { 0.f, 0.6f }, { 0.f, 0.f, 1.f } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* vertex_shader_text =
|
static const char* vertex_shader_text =
|
||||||
"#version 110\n"
|
"#version 330\n"
|
||||||
"uniform mat4 MVP;\n"
|
"uniform mat4 MVP;\n"
|
||||||
"attribute vec3 vCol;\n"
|
"in vec3 vCol;\n"
|
||||||
"attribute vec2 vPos;\n"
|
"in vec2 vPos;\n"
|
||||||
"varying vec3 color;\n"
|
"out vec3 color;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
|
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
|
||||||
@ -56,11 +60,12 @@ static const char* vertex_shader_text =
|
|||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
static const char* fragment_shader_text =
|
static const char* fragment_shader_text =
|
||||||
"#version 110\n"
|
"#version 330\n"
|
||||||
"varying vec3 color;\n"
|
"in vec3 color;\n"
|
||||||
|
"out vec4 fragment;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_FragColor = vec4(color, 1.0);\n"
|
" fragment = vec4(color, 1.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
static void error_callback(int error, const char* description)
|
static void error_callback(int error, const char* description)
|
||||||
@ -76,19 +81,16 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
GLFWwindow* window;
|
|
||||||
GLuint vertex_buffer, vertex_shader, fragment_shader, program;
|
|
||||||
GLint mvp_location, vpos_location, vcol_location;
|
|
||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@ -103,53 +105,56 @@ int main(void)
|
|||||||
|
|
||||||
// NOTE: OpenGL error checks have been omitted for brevity
|
// NOTE: OpenGL error checks have been omitted for brevity
|
||||||
|
|
||||||
|
GLuint vertex_buffer;
|
||||||
glGenBuffers(1, &vertex_buffer);
|
glGenBuffers(1, &vertex_buffer);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
|
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
|
||||||
glCompileShader(vertex_shader);
|
glCompileShader(vertex_shader);
|
||||||
|
|
||||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
|
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
|
||||||
glCompileShader(fragment_shader);
|
glCompileShader(fragment_shader);
|
||||||
|
|
||||||
program = glCreateProgram();
|
const GLuint program = glCreateProgram();
|
||||||
glAttachShader(program, vertex_shader);
|
glAttachShader(program, vertex_shader);
|
||||||
glAttachShader(program, fragment_shader);
|
glAttachShader(program, fragment_shader);
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
mvp_location = glGetUniformLocation(program, "MVP");
|
const GLint mvp_location = glGetUniformLocation(program, "MVP");
|
||||||
vpos_location = glGetAttribLocation(program, "vPos");
|
const GLint vpos_location = glGetAttribLocation(program, "vPos");
|
||||||
vcol_location = glGetAttribLocation(program, "vCol");
|
const GLint vcol_location = glGetAttribLocation(program, "vCol");
|
||||||
|
|
||||||
|
GLuint vertex_array;
|
||||||
|
glGenVertexArrays(1, &vertex_array);
|
||||||
|
glBindVertexArray(vertex_array);
|
||||||
glEnableVertexAttribArray(vpos_location);
|
glEnableVertexAttribArray(vpos_location);
|
||||||
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
|
||||||
sizeof(vertices[0]), (void*) 0);
|
sizeof(Vertex), (void*) offsetof(Vertex, pos));
|
||||||
glEnableVertexAttribArray(vcol_location);
|
glEnableVertexAttribArray(vcol_location);
|
||||||
glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
|
||||||
sizeof(vertices[0]), (void*) (sizeof(float) * 2));
|
sizeof(Vertex), (void*) offsetof(Vertex, col));
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
float ratio;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
mat4x4 m, p, mvp;
|
|
||||||
|
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
ratio = width / (float) height;
|
const float ratio = width / (float) height;
|
||||||
|
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
mat4x4 m, p, mvp;
|
||||||
mat4x4_identity(m);
|
mat4x4_identity(m);
|
||||||
mat4x4_rotate_Z(m, m, (float) glfwGetTime());
|
mat4x4_rotate_Z(m, m, (float) glfwGetTime());
|
||||||
mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
|
mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
|
||||||
mat4x4_mul(mvp, p, m);
|
mat4x4_mul(mvp, p, m);
|
||||||
|
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
|
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp);
|
||||||
|
glBindVertexArray(vertex_array);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
@ -18,6 +18,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <linmath.h>
|
#include <linmath.h>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,130 +1,148 @@
|
|||||||
|
|
||||||
set(common_HEADERS internal.h mappings.h
|
add_library(glfw "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
||||||
"${GLFW_BINARY_DIR}/src/glfw_config.h"
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
internal.h mappings.h context.c init.c input.c monitor.c
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
|
vulkan.c window.c)
|
||||||
set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
|
|
||||||
|
|
||||||
if (_GLFW_COCOA)
|
if (_GLFW_COCOA)
|
||||||
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h posix_thread.h
|
||||||
posix_thread.h nsgl_context.h egl_context.h osmesa_context.h)
|
nsgl_context.h egl_context.h osmesa_context.h
|
||||||
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
|
cocoa_init.m cocoa_joystick.m cocoa_monitor.m
|
||||||
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
|
cocoa_window.m cocoa_time.c posix_thread.c
|
||||||
nsgl_context.m egl_context.c osmesa_context.c)
|
nsgl_context.m egl_context.c osmesa_context.c)
|
||||||
elseif (_GLFW_WIN32)
|
elseif (_GLFW_WIN32)
|
||||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
|
target_sources(glfw PRIVATE win32_platform.h win32_joystick.h wgl_context.h
|
||||||
wgl_context.h egl_context.h osmesa_context.h)
|
egl_context.h osmesa_context.h win32_init.c
|
||||||
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
|
win32_joystick.c win32_monitor.c win32_time.c
|
||||||
win32_monitor.c win32_time.c win32_thread.c win32_window.c
|
win32_thread.c win32_window.c wgl_context.c
|
||||||
wgl_context.c egl_context.c osmesa_context.c)
|
egl_context.c osmesa_context.c)
|
||||||
elseif (_GLFW_X11)
|
elseif (_GLFW_X11)
|
||||||
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h
|
target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h posix_time.h
|
||||||
posix_thread.h glx_context.h egl_context.h osmesa_context.h)
|
posix_thread.h glx_context.h egl_context.h
|
||||||
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
|
osmesa_context.h x11_init.c x11_monitor.c
|
||||||
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
|
x11_window.c xkb_unicode.c posix_time.c
|
||||||
egl_context.c osmesa_context.c)
|
posix_thread.c glx_context.c egl_context.c
|
||||||
|
osmesa_context.c)
|
||||||
elseif (_GLFW_WAYLAND)
|
elseif (_GLFW_WAYLAND)
|
||||||
set(glfw_HEADERS ${common_HEADERS} wl_platform.h
|
target_sources(glfw PRIVATE wl_platform.h posix_time.h posix_thread.h
|
||||||
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
|
xkb_unicode.h egl_context.h osmesa_context.h
|
||||||
osmesa_context.h)
|
wl_init.c wl_monitor.c wl_window.c posix_time.c
|
||||||
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
|
posix_thread.c xkb_unicode.c egl_context.c
|
||||||
posix_time.c posix_thread.c xkb_unicode.c
|
osmesa_context.c)
|
||||||
egl_context.c osmesa_context.c)
|
|
||||||
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
|
||||||
PROTOCOL
|
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
|
|
||||||
BASENAME xdg-shell)
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
|
||||||
PROTOCOL
|
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
|
|
||||||
BASENAME xdg-decoration)
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
|
||||||
PROTOCOL
|
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
|
|
||||||
BASENAME viewporter)
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
|
||||||
PROTOCOL
|
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
|
|
||||||
BASENAME relative-pointer-unstable-v1)
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
|
||||||
PROTOCOL
|
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
|
|
||||||
BASENAME pointer-constraints-unstable-v1)
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
|
||||||
PROTOCOL
|
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
|
|
||||||
BASENAME idle-inhibit-unstable-v1)
|
|
||||||
elseif (_GLFW_OSMESA)
|
elseif (_GLFW_OSMESA)
|
||||||
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
|
target_sources(glfw PRIVATE null_platform.h null_joystick.h posix_time.h
|
||||||
posix_time.h posix_thread.h osmesa_context.h)
|
posix_thread.h osmesa_context.h null_init.c
|
||||||
set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c
|
null_monitor.c null_window.c null_joystick.c
|
||||||
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
|
posix_time.c posix_thread.c osmesa_context.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (_GLFW_X11 OR _GLFW_WAYLAND)
|
if (_GLFW_X11 OR _GLFW_WAYLAND)
|
||||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||||
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
|
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
|
||||||
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
|
|
||||||
else()
|
else()
|
||||||
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
|
target_sources(glfw PRIVATE null_joystick.h null_joystick.c)
|
||||||
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (_GLFW_WAYLAND)
|
||||||
# For some reason, CMake doesn't know about .m
|
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
|
||||||
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
|
||||||
|
BASENAME xdg-shell)
|
||||||
|
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
|
||||||
|
BASENAME xdg-decoration)
|
||||||
|
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
|
||||||
|
BASENAME viewporter)
|
||||||
|
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
|
||||||
|
BASENAME relative-pointer-unstable-v1)
|
||||||
|
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
|
||||||
|
BASENAME pointer-constraints-unstable-v1)
|
||||||
|
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
|
||||||
|
BASENAME idle-inhibit-unstable-v1)
|
||||||
|
target_sources(glfw PRIVATE ${GLFW_WAYLAND_PROTOCOL_SOURCES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't accept
|
if (WIN32 AND BUILD_SHARED_LIBS)
|
||||||
# for all source files that VS will build
|
configure_file(glfw.rc.in glfw.rc @ONLY)
|
||||||
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw.rc")
|
||||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
|
||||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
set(windows_SOURCES ${glfw_SOURCES})
|
|
||||||
else()
|
|
||||||
set(windows_SOURCES ${common_SOURCES})
|
|
||||||
endif()
|
|
||||||
set_source_files_properties(${windows_SOURCES} PROPERTIES
|
|
||||||
COMPILE_FLAGS -Wdeclaration-after-statement)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
configure_file(glfw_config.h.in glfw_config.h @ONLY)
|
||||||
|
target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H)
|
||||||
|
target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw_config.h")
|
||||||
|
|
||||||
set_target_properties(glfw PROPERTIES
|
set_target_properties(glfw PROPERTIES
|
||||||
OUTPUT_NAME ${GLFW_LIB_NAME}
|
OUTPUT_NAME ${GLFW_LIB_NAME}
|
||||||
VERSION ${GLFW_VERSION}
|
VERSION ${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}
|
||||||
SOVERSION ${GLFW_VERSION_MAJOR}
|
SOVERSION ${GLFW_VERSION_MAJOR}
|
||||||
POSITION_INDEPENDENT_CODE ON
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
C_STANDARD 99
|
||||||
|
C_EXTENSIONS OFF
|
||||||
|
DEFINE_SYMBOL _GLFW_BUILD_DLL
|
||||||
FOLDER "GLFW3")
|
FOLDER "GLFW3")
|
||||||
|
|
||||||
target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H)
|
|
||||||
target_include_directories(glfw PUBLIC
|
target_include_directories(glfw PUBLIC
|
||||||
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_FULL_INCLUDEDIR}>")
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||||
target_include_directories(glfw PRIVATE
|
target_include_directories(glfw PRIVATE
|
||||||
"${GLFW_SOURCE_DIR}/src"
|
"${GLFW_SOURCE_DIR}/src"
|
||||||
"${GLFW_BINARY_DIR}/src"
|
"${GLFW_BINARY_DIR}/src"
|
||||||
${glfw_INCLUDE_DIRS})
|
${glfw_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(glfw PRIVATE Threads::Threads ${glfw_LIBRARIES})
|
||||||
|
|
||||||
|
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
|
||||||
|
cocoa_window.m nsgl_context.m PROPERTIES
|
||||||
|
LANGUAGE C)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
||||||
|
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
||||||
|
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
||||||
|
|
||||||
|
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't
|
||||||
|
# accept for all source files that VS will build
|
||||||
|
set_source_files_properties(context.c init.c input.c monitor.c vulkan.c
|
||||||
|
window.c win32_init.c win32_joystick.c
|
||||||
|
win32_monitor.c win32_time.c win32_thread.c
|
||||||
|
win32_window.c wgl_context.c egl_context.c
|
||||||
|
osmesa_context.c PROPERTIES
|
||||||
|
COMPILE_FLAGS -Wdeclaration-after-statement)
|
||||||
|
|
||||||
|
# Enable a reasonable set of warnings (no, -Wextra is not reasonable)
|
||||||
|
target_compile_options(glfw PRIVATE "-Wall")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
target_compile_definitions(glfw PRIVATE _UNICODE)
|
||||||
|
endif()
|
||||||
|
|
||||||
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
|
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
|
||||||
# the inclusion of stddef.h (by glfw3.h), which is itself included before
|
# the inclusion of stddef.h (by glfw3.h), which is itself included before
|
||||||
# win32_platform.h. We define them here until a saner solution can be found
|
# win32_platform.h. We define them here until a saner solution can be found
|
||||||
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
|
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
|
||||||
target_compile_definitions(glfw PRIVATE
|
if (MINGW)
|
||||||
"$<$<BOOL:${MINGW}>:UNICODE;WINVER=0x0501>")
|
target_compile_definitions(glfw PRIVATE UNICODE WINVER=0x0501)
|
||||||
|
endif()
|
||||||
# Enable a reasonable set of warnings (no, -Wextra is not reasonable)
|
|
||||||
target_compile_options(glfw PRIVATE
|
|
||||||
"$<$<C_COMPILER_ID:AppleClang>:-Wall>"
|
|
||||||
"$<$<C_COMPILER_ID:Clang>:-Wall>"
|
|
||||||
"$<$<C_COMPILER_ID:GNU>:-Wall>")
|
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
|
# Remove the dependency on the shared version of libgcc
|
||||||
|
# NOTE: MinGW-w64 has the correct default but MinGW needs this
|
||||||
|
target_link_libraries(glfw PRIVATE "-static-libgcc")
|
||||||
|
|
||||||
# Remove the lib prefix on the DLL (but not the import library)
|
# Remove the lib prefix on the DLL (but not the import library)
|
||||||
set_target_properties(glfw PROPERTIES PREFIX "")
|
set_target_properties(glfw PROPERTIES PREFIX "")
|
||||||
|
|
||||||
@ -134,21 +152,17 @@ if (BUILD_SHARED_LIBS)
|
|||||||
# Add a suffix to the import library to avoid naming conflicts
|
# Add a suffix to the import library to avoid naming conflicts
|
||||||
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
|
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
|
||||||
endif()
|
endif()
|
||||||
elseif (APPLE)
|
|
||||||
# Add -fno-common to work around a bug in Apple's GCC
|
|
||||||
target_compile_options(glfw PRIVATE "-fno-common")
|
|
||||||
|
|
||||||
|
target_compile_definitions(glfw INTERFACE GLFW_DLL)
|
||||||
|
elseif (APPLE)
|
||||||
set_target_properties(glfw PROPERTIES
|
set_target_properties(glfw PROPERTIES
|
||||||
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
|
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
|
||||||
elseif (UNIX)
|
endif()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
target_compile_definitions(glfw INTERFACE GLFW_DLL)
|
|
||||||
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
|
|
||||||
else()
|
|
||||||
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <sys/param.h> // For MAXPATHLEN
|
#include <sys/param.h> // For MAXPATHLEN
|
||||||
@ -429,9 +431,8 @@ static GLFWbool initializeTIS(void)
|
|||||||
// In case we are unbundled, make us a proper UI application
|
// In case we are unbundled, make us a proper UI application
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
// Menu bar setup must go between sharedApplication above and
|
// Menu bar setup must go between sharedApplication and finishLaunching
|
||||||
// finishLaunching below, in order to properly emulate the behavior
|
// in order to properly emulate the behavior of NSApplicationMain
|
||||||
// of NSApplicationMain
|
|
||||||
|
|
||||||
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
|
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
|
||||||
{
|
{
|
||||||
@ -446,9 +447,9 @@ static GLFWbool initializeTIS(void)
|
|||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
[NSApp stop:nil];
|
_glfw.ns.finishedLaunching = GLFW_TRUE;
|
||||||
|
|
||||||
_glfwPlatformPostEmptyEvent();
|
_glfwPlatformPostEmptyEvent();
|
||||||
|
[NSApp stop:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidHide:(NSNotification *)notification
|
- (void)applicationDidHide:(NSNotification *)notification
|
||||||
@ -462,6 +463,32 @@ static GLFWbool initializeTIS(void)
|
|||||||
@end // GLFWApplicationDelegate
|
@end // GLFWApplicationDelegate
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* _glfwLoadLocalVulkanLoaderNS(void)
|
||||||
|
{
|
||||||
|
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||||
|
if (!bundle)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CFURLRef url =
|
||||||
|
CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib"));
|
||||||
|
if (!url)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
void* handle = NULL;
|
||||||
|
|
||||||
|
if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1))
|
||||||
|
handle = _glfw_dlopen(path);
|
||||||
|
|
||||||
|
CFRelease(url);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include <IOKit/hid/IOHIDKeys.h>
|
#include <IOKit/hid/IOHIDKeys.h>
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
|
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyJoystick; }
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
|
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -329,7 +331,7 @@ void _glfwInitJoysticksNS(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
|
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||||
{
|
{
|
||||||
const long page = kHIDPage_GenericDesktop;
|
const long page = kHIDPage_GenericDesktop;
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -142,7 +144,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
|||||||
// Convert Core Graphics display mode to GLFW video mode
|
// Convert Core Graphics display mode to GLFW video mode
|
||||||
//
|
//
|
||||||
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
||||||
CVDisplayLinkRef link)
|
double fallbackRefreshRate)
|
||||||
{
|
{
|
||||||
GLFWvidmode result;
|
GLFWvidmode result;
|
||||||
result.width = (int) CGDisplayModeGetWidth(mode);
|
result.width = (int) CGDisplayModeGetWidth(mode);
|
||||||
@ -150,11 +152,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
|||||||
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
|
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
|
||||||
|
|
||||||
if (result.refreshRate == 0)
|
if (result.refreshRate == 0)
|
||||||
{
|
result.refreshRate = (int) round(fallbackRefreshRate);
|
||||||
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
|
|
||||||
if (!(time.flags & kCVTimeIsIndefinite))
|
|
||||||
result.refreshRate = (int) (time.timeScale / (double) time.timeValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
||||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
@ -213,7 +211,7 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
|||||||
|
|
||||||
// Finds and caches the NSScreen corresponding to the specified monitor
|
// Finds and caches the NSScreen corresponding to the specified monitor
|
||||||
//
|
//
|
||||||
GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
static GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
||||||
{
|
{
|
||||||
if (monitor->ns.screen)
|
if (monitor->ns.screen)
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -236,6 +234,68 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the display refresh rate queried from the I/O registry
|
||||||
|
//
|
||||||
|
static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||||
|
{
|
||||||
|
double refreshRate = 60.0;
|
||||||
|
|
||||||
|
io_iterator_t it;
|
||||||
|
io_service_t service;
|
||||||
|
|
||||||
|
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||||
|
IOServiceMatching("IOFramebuffer"),
|
||||||
|
&it) != 0)
|
||||||
|
{
|
||||||
|
return refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
|
{
|
||||||
|
const CFNumberRef indexRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFramebufferOpenGLIndex"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
if (!indexRef)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t index = 0;
|
||||||
|
CFNumberGetValue(indexRef, kCFNumberIntType, &index);
|
||||||
|
CFRelease(indexRef);
|
||||||
|
|
||||||
|
if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CFNumberRef clockRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFBCurrentPixelClock"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
const CFNumberRef countRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFBCurrentPixelCount"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
if (!clockRef || !countRef)
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint32_t clock = 0, count = 0;
|
||||||
|
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
|
||||||
|
CFNumberGetValue(countRef, kCFNumberIntType, &count);
|
||||||
|
CFRelease(clockRef);
|
||||||
|
CFRelease(countRef);
|
||||||
|
|
||||||
|
if (clock > 0 && count > 0)
|
||||||
|
refreshRate = clock / (double) count;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOObjectRelease(it);
|
||||||
|
return refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
@ -245,18 +305,16 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
|
|||||||
//
|
//
|
||||||
void _glfwPollMonitorsNS(void)
|
void _glfwPollMonitorsNS(void)
|
||||||
{
|
{
|
||||||
uint32_t i, j, displayCount, disconnectedCount;
|
uint32_t displayCount;
|
||||||
CGDirectDisplayID* displays;
|
|
||||||
_GLFWmonitor** disconnected = NULL;
|
|
||||||
|
|
||||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||||
|
|
||||||
for (i = 0; i < _glfw.monitorCount; i++)
|
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||||
_glfw.monitors[i]->ns.screen = nil;
|
_glfw.monitors[i]->ns.screen = nil;
|
||||||
|
|
||||||
disconnectedCount = _glfw.monitorCount;
|
_GLFWmonitor** disconnected = NULL;
|
||||||
|
uint32_t disconnectedCount = _glfw.monitorCount;
|
||||||
if (disconnectedCount)
|
if (disconnectedCount)
|
||||||
{
|
{
|
||||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
@ -265,19 +323,17 @@ void _glfwPollMonitorsNS(void)
|
|||||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < displayCount; i++)
|
for (uint32_t i = 0; i < displayCount; i++)
|
||||||
{
|
{
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
|
||||||
|
|
||||||
if (CGDisplayIsAsleep(displays[i]))
|
if (CGDisplayIsAsleep(displays[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < disconnectedCount; j++)
|
// HACK: Compare unit numbers instead of display IDs to work around
|
||||||
|
// display replacement on machines with automatic graphics
|
||||||
|
// switching
|
||||||
|
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||||
|
for (uint32_t j = 0; j < disconnectedCount; j++)
|
||||||
{
|
{
|
||||||
// HACK: Compare unit numbers instead of display IDs to work around
|
|
||||||
// display replacement on machines with automatic graphics
|
|
||||||
// switching
|
|
||||||
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
||||||
{
|
{
|
||||||
disconnected[j] = NULL;
|
disconnected[j] = NULL;
|
||||||
@ -290,16 +346,21 @@ void _glfwPollMonitorsNS(void)
|
|||||||
if (!name)
|
if (!name)
|
||||||
name = _glfw_strdup("Unknown");
|
name = _glfw_strdup("Unknown");
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||||
monitor->ns.displayID = displays[i];
|
monitor->ns.displayID = displays[i];
|
||||||
monitor->ns.unitNumber = unitNumber;
|
monitor->ns.unitNumber = unitNumber;
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
|
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
|
||||||
|
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
|
||||||
|
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
|
||||||
|
CGDisplayModeRelease(mode);
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
for (uint32_t i = 0; i < disconnectedCount; i++)
|
||||||
{
|
{
|
||||||
if (disconnected[i])
|
if (disconnected[i])
|
||||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
@ -313,30 +374,25 @@ void _glfwPollMonitorsNS(void)
|
|||||||
//
|
//
|
||||||
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
{
|
{
|
||||||
CFArrayRef modes;
|
|
||||||
CFIndex count, i;
|
|
||||||
CVDisplayLinkRef link;
|
|
||||||
CGDisplayModeRef native = NULL;
|
|
||||||
GLFWvidmode current;
|
GLFWvidmode current;
|
||||||
const GLFWvidmode* best;
|
|
||||||
|
|
||||||
best = _glfwChooseVideoMode(monitor, desired);
|
|
||||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||||
|
|
||||||
|
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||||
|
const CFIndex count = CFArrayGetCount(modes);
|
||||||
|
CGDisplayModeRef native = NULL;
|
||||||
|
|
||||||
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
for (CFIndex i = 0; i < count; i++)
|
||||||
count = CFArrayGetCount(modes);
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||||
if (!modeIsGood(dm))
|
if (!modeIsGood(dm))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
|
const GLFWvidmode mode =
|
||||||
|
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
|
||||||
if (_glfwCompareVideoModes(best, &mode) == 0)
|
if (_glfwCompareVideoModes(best, &mode) == 0)
|
||||||
{
|
{
|
||||||
native = dm;
|
native = dm;
|
||||||
@ -355,7 +411,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(modes);
|
CFRelease(modes);
|
||||||
CVDisplayLinkRelease(link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the previously saved (original) video mode
|
// Restore the previously saved (original) video mode
|
||||||
@ -443,26 +498,21 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
CFArrayRef modes;
|
|
||||||
CFIndex found, i, j;
|
|
||||||
GLFWvidmode* result;
|
|
||||||
CVDisplayLinkRef link;
|
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||||
|
const CFIndex found = CFArrayGetCount(modes);
|
||||||
|
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
|
||||||
|
|
||||||
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
for (CFIndex i = 0; i < found; i++)
|
||||||
found = CFArrayGetCount(modes);
|
|
||||||
result = calloc(found, sizeof(GLFWvidmode));
|
|
||||||
|
|
||||||
for (i = 0; i < found; i++)
|
|
||||||
{
|
{
|
||||||
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||||
if (!modeIsGood(dm))
|
if (!modeIsGood(dm))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
|
const GLFWvidmode mode =
|
||||||
|
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
|
||||||
|
CFIndex j;
|
||||||
|
|
||||||
for (j = 0; j < *count; j++)
|
for (j = 0; j < *count; j++)
|
||||||
{
|
{
|
||||||
@ -479,7 +529,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(modes);
|
CFRelease(modes);
|
||||||
CVDisplayLinkRelease(link);
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
@ -489,16 +538,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
CGDisplayModeRef displayMode;
|
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||||
CVDisplayLinkRef link;
|
*mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
|
||||||
|
CGDisplayModeRelease(native);
|
||||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
|
||||||
|
|
||||||
displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
|
||||||
*mode = vidmodeFromCGDisplayMode(displayMode, link);
|
|
||||||
CGDisplayModeRelease(displayMode);
|
|
||||||
|
|
||||||
CVDisplayLinkRelease(link);
|
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
@ -507,7 +549,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||||
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
||||||
|
|
||||||
CGGetDisplayTransferByTable(monitor->ns.displayID,
|
CGGetDisplayTransferByTable(monitor->ns.displayID,
|
||||||
@ -519,7 +561,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
|
|
||||||
_glfwAllocGammaArrays(ramp, size);
|
_glfwAllocGammaArrays(ramp, size);
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (uint32_t i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
ramp->red[i] = (unsigned short) (values[i] * 65535);
|
ramp->red[i] = (unsigned short) (values[i] * 65535);
|
||||||
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
|
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
|
||||||
@ -536,10 +578,9 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
int i;
|
|
||||||
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
|
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
|
||||||
|
|
||||||
for (i = 0; i < ramp->size; i++)
|
for (unsigned int i = 0; i < ramp->size; i++)
|
||||||
{
|
{
|
||||||
values[i] = ramp->red[i] / 65535.f;
|
values[i] = ramp->red[i] / 65535.f;
|
||||||
values[i + ramp->size] = ramp->green[i] / 65535.f;
|
values[i + ramp->size] = ramp->green[i] / 65535.f;
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
#include <CoreVideo/CVBase.h>
|
|
||||||
#include <CoreVideo/CVDisplayLink.h>
|
|
||||||
|
|
||||||
// NOTE: All of NSGL was deprecated in the 10.14 SDK
|
// NOTE: All of NSGL was deprecated in the 10.14 SDK
|
||||||
// This disables the pointless warnings for every symbol we use
|
// This disables the pointless warnings for every symbol we use
|
||||||
@ -41,6 +39,9 @@
|
|||||||
typedef void* id;
|
typedef void* id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||||
|
// SDK versions where one is unavailable or the other deprecated
|
||||||
|
// We use the newer names in code and these macros to handle compatibility
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||||
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||||
#define NSEventMaskAny NSAnyEventMask
|
#define NSEventMaskAny NSAnyEventMask
|
||||||
@ -60,6 +61,7 @@ typedef void* id;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||||
|
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
|
||||||
|
|
||||||
typedef struct VkMacOSSurfaceCreateInfoMVK
|
typedef struct VkMacOSSurfaceCreateInfoMVK
|
||||||
{
|
{
|
||||||
@ -69,7 +71,16 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
|
|||||||
const void* pView;
|
const void* pView;
|
||||||
} VkMacOSSurfaceCreateInfoMVK;
|
} VkMacOSSurfaceCreateInfoMVK;
|
||||||
|
|
||||||
|
typedef struct VkMetalSurfaceCreateInfoEXT
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkMetalSurfaceCreateFlagsEXT flags;
|
||||||
|
const void* pLayer;
|
||||||
|
} VkMetalSurfaceCreateInfoEXT;
|
||||||
|
|
||||||
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
|
||||||
#include "posix_thread.h"
|
#include "posix_thread.h"
|
||||||
#include "cocoa_joystick.h"
|
#include "cocoa_joystick.h"
|
||||||
@ -139,7 +150,7 @@ typedef struct _GLFWlibraryNS
|
|||||||
id keyUpMonitor;
|
id keyUpMonitor;
|
||||||
id nibObjects;
|
id nibObjects;
|
||||||
|
|
||||||
char keyName[64];
|
char keynames[GLFW_KEY_LAST + 1][17];
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
@ -167,6 +178,7 @@ typedef struct _GLFWmonitorNS
|
|||||||
CGDisplayModeRef previousMode;
|
CGDisplayModeRef previousMode;
|
||||||
uint32_t unitNumber;
|
uint32_t unitNumber;
|
||||||
id screen;
|
id screen;
|
||||||
|
double fallbackRefreshRate;
|
||||||
|
|
||||||
} _GLFWmonitorNS;
|
} _GLFWmonitorNS;
|
||||||
|
|
||||||
@ -195,3 +207,5 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
|||||||
|
|
||||||
float _glfwTransformYNS(float y);
|
float _glfwTransformYNS(float y);
|
||||||
|
|
||||||
|
void* _glfwLoadLocalVulkanLoaderNS(void);
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -33,15 +35,14 @@
|
|||||||
//
|
//
|
||||||
static NSUInteger getStyleMask(_GLFWwindow* window)
|
static NSUInteger getStyleMask(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
NSUInteger styleMask = 0;
|
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
|
||||||
|
|
||||||
if (window->monitor || !window->decorated)
|
if (window->monitor || !window->decorated)
|
||||||
styleMask |= NSWindowStyleMaskBorderless;
|
styleMask |= NSWindowStyleMaskBorderless;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
styleMask |= NSWindowStyleMaskTitled |
|
styleMask |= NSWindowStyleMaskTitled |
|
||||||
NSWindowStyleMaskClosable |
|
NSWindowStyleMaskClosable;
|
||||||
NSWindowStyleMaskMiniaturizable;
|
|
||||||
|
|
||||||
if (window->resizable)
|
if (window->resizable)
|
||||||
styleMask |= NSWindowStyleMaskResizable;
|
styleMask |= NSWindowStyleMaskResizable;
|
||||||
@ -321,12 +322,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowDidChangeScreen:(NSNotification *)notification
|
|
||||||
{
|
|
||||||
if (window->context.source == GLFW_NATIVE_CONTEXT_API)
|
|
||||||
_glfwUpdateDisplayLinkDisplayNSGL(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@ -610,10 +605,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (void)scrollWheel:(NSEvent *)event
|
- (void)scrollWheel:(NSEvent *)event
|
||||||
{
|
{
|
||||||
double deltaX, deltaY;
|
double deltaX = [event scrollingDeltaX];
|
||||||
|
double deltaY = [event scrollingDeltaY];
|
||||||
deltaX = [event scrollingDeltaX];
|
|
||||||
deltaY = [event scrollingDeltaY];
|
|
||||||
|
|
||||||
if ([event hasPreciseScrollingDeltas])
|
if ([event hasPreciseScrollingDeltas])
|
||||||
{
|
{
|
||||||
@ -730,9 +723,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
else
|
else
|
||||||
characters = (NSString*) string;
|
characters = (NSString*) string;
|
||||||
|
|
||||||
NSUInteger i, length = [characters length];
|
const NSUInteger length = [characters length];
|
||||||
|
for (NSUInteger i = 0; i < length; i++)
|
||||||
for (i = 0; i < length; i++)
|
|
||||||
{
|
{
|
||||||
const unichar codepoint = [characters characterAtIndex:i];
|
const unichar codepoint = [characters characterAtIndex:i];
|
||||||
if ((codepoint & 0xff00) == 0xf700)
|
if ((codepoint & 0xff00) == 0xf700)
|
||||||
@ -817,7 +809,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
|
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[window->ns.object center];
|
[(NSWindow*) window->ns.object center];
|
||||||
_glfw.ns.cascadePoint =
|
_glfw.ns.cascadePoint =
|
||||||
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
|
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
|
||||||
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
|
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
|
||||||
@ -893,10 +885,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (!_glfw.ns.finishedLaunching)
|
if (!_glfw.ns.finishedLaunching)
|
||||||
{
|
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
_glfw.ns.finishedLaunching = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!createNativeWindow(window, wndconfig, fbconfig))
|
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@ -963,16 +952,20 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
[window->ns.object close];
|
[window->ns.object close];
|
||||||
window->ns.object = nil;
|
window->ns.object = nil;
|
||||||
|
|
||||||
|
// HACK: Allow Cocoa to catch up before returning
|
||||||
|
_glfwPlatformPollEvents();
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
[window->ns.object setTitle:@(title)];
|
NSString* string = @(title);
|
||||||
|
[window->ns.object setTitle:string];
|
||||||
// HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
|
// HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
|
||||||
// if the window lacks NSWindowStyleMaskTitled
|
// if the window lacks NSWindowStyleMaskTitled
|
||||||
[window->ns.object setMiniwindowTitle:@(title)];
|
[window->ns.object setMiniwindowTitle:string];
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1033,7 +1026,14 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
|||||||
acquireMonitor(window);
|
acquireMonitor(window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
[window->ns.object setContentSize:NSMakeSize(width, height)];
|
{
|
||||||
|
NSRect contentRect =
|
||||||
|
[window->ns.object contentRectForFrameRect:[window->ns.object frame]];
|
||||||
|
contentRect.origin.y += contentRect.size.height - height;
|
||||||
|
contentRect.size = NSMakeSize(width, height);
|
||||||
|
[window->ns.object setFrame:[window->ns.object frameRectForContentRect:contentRect]
|
||||||
|
display:YES];
|
||||||
|
}
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
@ -1222,7 +1222,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
// HACK: Changing the style mask can cause the first responder to be cleared
|
// HACK: Changing the style mask can cause the first responder to be cleared
|
||||||
[window->ns.object makeFirstResponder:window->ns.view];
|
[window->ns.object makeFirstResponder:window->ns.view];
|
||||||
|
|
||||||
if (monitor)
|
if (window->monitor)
|
||||||
{
|
{
|
||||||
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
|
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
|
||||||
[window->ns.object setHasShadow:NO];
|
[window->ns.object setHasShadow:NO];
|
||||||
@ -1377,6 +1377,9 @@ void _glfwPlatformPollEvents(void)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
|
if (!_glfw.ns.finishedLaunching)
|
||||||
|
[NSApp run];
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
||||||
@ -1396,6 +1399,9 @@ 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.
|
||||||
@ -1414,6 +1420,9 @@ 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
|
||||||
@ -1431,6 +1440,9 @@ 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
|
||||||
@ -1504,8 +1516,17 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
|
if (scancode < 0 || scancode > 0xff ||
|
||||||
|
_glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int key = _glfw.ns.keycodes[scancode];
|
||||||
|
|
||||||
UInt32 deadKeyState = 0;
|
UInt32 deadKeyState = 0;
|
||||||
UniChar characters[8];
|
UniChar characters[4];
|
||||||
UniCharCount characterCount = 0;
|
UniCharCount characterCount = 0;
|
||||||
|
|
||||||
if (UCKeyTranslate([(NSData*) _glfw.ns.unicodeData bytes],
|
if (UCKeyTranslate([(NSData*) _glfw.ns.unicodeData bytes],
|
||||||
@ -1530,12 +1551,12 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
|||||||
characterCount,
|
characterCount,
|
||||||
kCFAllocatorNull);
|
kCFAllocatorNull);
|
||||||
CFStringGetCString(string,
|
CFStringGetCString(string,
|
||||||
_glfw.ns.keyName,
|
_glfw.ns.keynames[key],
|
||||||
sizeof(_glfw.ns.keyName),
|
sizeof(_glfw.ns.keynames[key]),
|
||||||
kCFStringEncodingUTF8);
|
kCFStringEncodingUTF8);
|
||||||
CFRelease(string);
|
CFRelease(string);
|
||||||
|
|
||||||
return _glfw.ns.keyName;
|
return _glfw.ns.keynames[key];
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
@ -1593,23 +1614,49 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (shape == GLFW_ARROW_CURSOR)
|
SEL cursorSelector = NULL;
|
||||||
cursor->ns.object = [NSCursor arrowCursor];
|
|
||||||
else if (shape == GLFW_IBEAM_CURSOR)
|
// HACK: Try to use a private message
|
||||||
cursor->ns.object = [NSCursor IBeamCursor];
|
if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
cursorSelector = NSSelectorFromString(@"_windowResizeEastWestCursor");
|
||||||
cursor->ns.object = [NSCursor crosshairCursor];
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
else if (shape == GLFW_HAND_CURSOR)
|
cursorSelector = NSSelectorFromString(@"_windowResizeNorthSouthCursor");
|
||||||
cursor->ns.object = [NSCursor pointingHandCursor];
|
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
cursorSelector = NSSelectorFromString(@"_windowResizeNorthWestSouthEastCursor");
|
||||||
cursor->ns.object = [NSCursor resizeLeftRightCursor];
|
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
cursorSelector = NSSelectorFromString(@"_windowResizeNorthEastSouthWestCursor");
|
||||||
cursor->ns.object = [NSCursor resizeUpDownCursor];
|
|
||||||
|
if (cursorSelector && [NSCursor respondsToSelector:cursorSelector])
|
||||||
|
{
|
||||||
|
id object = [NSCursor performSelector:cursorSelector];
|
||||||
|
if ([object isKindOfClass:[NSCursor class]])
|
||||||
|
cursor->ns.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cursor->ns.object)
|
if (!cursor->ns.object)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
"Cocoa: Failed to retrieve standard cursor");
|
cursor->ns.object = [NSCursor arrowCursor];
|
||||||
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor IBeamCursor];
|
||||||
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor crosshairCursor];
|
||||||
|
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor pointingHandCursor];
|
||||||
|
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor resizeLeftRightCursor];
|
||||||
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor resizeUpDownCursor];
|
||||||
|
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor closedHandCursor];
|
||||||
|
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||||
|
cursor->ns.object = [NSCursor operationNotAllowedCursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cursor->ns.object)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
|
||||||
|
"Cocoa: Standard cursor shape unavailable");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1675,11 +1722,16 @@ const char* _glfwPlatformGetClipboardString(void)
|
|||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
if (!_glfw.vk.KHR_surface || !_glfw.vk.MVK_macos_surface)
|
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
|
||||||
return;
|
{
|
||||||
|
extensions[0] = "VK_KHR_surface";
|
||||||
extensions[0] = "VK_KHR_surface";
|
extensions[1] = "VK_EXT_metal_surface";
|
||||||
extensions[1] = "VK_MVK_macos_surface";
|
}
|
||||||
|
else if (_glfw.vk.KHR_surface && _glfw.vk.MVK_macos_surface)
|
||||||
|
{
|
||||||
|
extensions[0] = "VK_KHR_surface";
|
||||||
|
extensions[1] = "VK_MVK_macos_surface";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
@ -1697,19 +1749,6 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
|
||||||
VkResult err;
|
|
||||||
VkMacOSSurfaceCreateInfoMVK sci;
|
|
||||||
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
|
|
||||||
|
|
||||||
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
|
|
||||||
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
|
|
||||||
if (!vkCreateMacOSSurfaceMVK)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
|
|
||||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: Dynamically load Core Animation to avoid adding an extra
|
// HACK: Dynamically load Core Animation to avoid adding an extra
|
||||||
// dependency for the majority who don't use MoltenVK
|
// dependency for the majority who don't use MoltenVK
|
||||||
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
|
NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
|
||||||
@ -1735,11 +1774,49 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
[window->ns.view setLayer:window->ns.layer];
|
[window->ns.view setLayer:window->ns.layer];
|
||||||
[window->ns.view setWantsLayer:YES];
|
[window->ns.view setWantsLayer:YES];
|
||||||
|
|
||||||
memset(&sci, 0, sizeof(sci));
|
VkResult err;
|
||||||
sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
|
||||||
sci.pView = window->ns.view;
|
if (_glfw.vk.EXT_metal_surface)
|
||||||
|
{
|
||||||
|
VkMetalSurfaceCreateInfoEXT sci;
|
||||||
|
|
||||||
|
PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT;
|
||||||
|
vkCreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateMetalSurfaceEXT");
|
||||||
|
if (!vkCreateMetalSurfaceEXT)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Cocoa: Vulkan instance missing VK_EXT_metal_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||||
|
sci.pLayer = window->ns.layer;
|
||||||
|
|
||||||
|
err = vkCreateMetalSurfaceEXT(instance, &sci, allocator, surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VkMacOSSurfaceCreateInfoMVK sci;
|
||||||
|
|
||||||
|
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
|
||||||
|
vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
|
||||||
|
vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
|
||||||
|
if (!vkCreateMacOSSurfaceMVK)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sci, 0, sizeof(sci));
|
||||||
|
sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||||
|
sci.pView = window->ns.view;
|
||||||
|
|
||||||
|
err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
|
||||||
|
}
|
||||||
|
|
||||||
err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -121,23 +123,24 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
XVisualInfo vi = {0};
|
|
||||||
|
|
||||||
// Only consider EGLConfigs with associated Visuals
|
|
||||||
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
|
|
||||||
if (!vi.visualid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (desired->transparent)
|
|
||||||
{
|
{
|
||||||
int count;
|
XVisualInfo vi = {0};
|
||||||
XVisualInfo* vis = XGetVisualInfo(_glfw.x11.display,
|
|
||||||
VisualIDMask, &vi,
|
// Only consider EGLConfigs with associated Visuals
|
||||||
&count);
|
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
|
||||||
if (vis)
|
if (!vi.visualid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (desired->transparent)
|
||||||
{
|
{
|
||||||
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
|
int count;
|
||||||
XFree(vis);
|
XVisualInfo* vis =
|
||||||
|
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
|
||||||
|
if (vis)
|
||||||
|
{
|
||||||
|
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
|
||||||
|
XFree(vis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
@ -47,26 +47,26 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
|||||||
#error "No supported EGL platform selected"
|
#error "No supported EGL platform selected"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EGL_SUCCESS 0x3000
|
#define EGL_SUCCESS 0x3000
|
||||||
#define EGL_NOT_INITIALIZED 0x3001
|
#define EGL_NOT_INITIALIZED 0x3001
|
||||||
#define EGL_BAD_ACCESS 0x3002
|
#define EGL_BAD_ACCESS 0x3002
|
||||||
#define EGL_BAD_ALLOC 0x3003
|
#define EGL_BAD_ALLOC 0x3003
|
||||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||||
#define EGL_BAD_CONFIG 0x3005
|
#define EGL_BAD_CONFIG 0x3005
|
||||||
#define EGL_BAD_CONTEXT 0x3006
|
#define EGL_BAD_CONTEXT 0x3006
|
||||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||||
#define EGL_BAD_DISPLAY 0x3008
|
#define EGL_BAD_DISPLAY 0x3008
|
||||||
#define EGL_BAD_MATCH 0x3009
|
#define EGL_BAD_MATCH 0x3009
|
||||||
#define EGL_BAD_NATIVE_PIXMAP 0x300a
|
#define EGL_BAD_NATIVE_PIXMAP 0x300a
|
||||||
#define EGL_BAD_NATIVE_WINDOW 0x300b
|
#define EGL_BAD_NATIVE_WINDOW 0x300b
|
||||||
#define EGL_BAD_PARAMETER 0x300c
|
#define EGL_BAD_PARAMETER 0x300c
|
||||||
#define EGL_BAD_SURFACE 0x300d
|
#define EGL_BAD_SURFACE 0x300d
|
||||||
#define EGL_CONTEXT_LOST 0x300e
|
#define EGL_CONTEXT_LOST 0x300e
|
||||||
#define EGL_COLOR_BUFFER_TYPE 0x303f
|
#define EGL_COLOR_BUFFER_TYPE 0x303f
|
||||||
#define EGL_RGB_BUFFER 0x308e
|
#define EGL_RGB_BUFFER 0x308e
|
||||||
#define EGL_SURFACE_TYPE 0x3033
|
#define EGL_SURFACE_TYPE 0x3033
|
||||||
#define EGL_WINDOW_BIT 0x0004
|
#define EGL_WINDOW_BIT 0x0004
|
||||||
#define EGL_RENDERABLE_TYPE 0x3040
|
#define EGL_RENDERABLE_TYPE 0x3040
|
||||||
#define EGL_OPENGL_ES_BIT 0x0001
|
#define EGL_OPENGL_ES_BIT 0x0001
|
||||||
#define EGL_OPENGL_ES2_BIT 0x0004
|
#define EGL_OPENGL_ES2_BIT 0x0004
|
||||||
#define EGL_OPENGL_BIT 0x0008
|
#define EGL_OPENGL_BIT 0x0008
|
||||||
@ -76,7 +76,7 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
|||||||
#define EGL_RED_SIZE 0x3024
|
#define EGL_RED_SIZE 0x3024
|
||||||
#define EGL_DEPTH_SIZE 0x3025
|
#define EGL_DEPTH_SIZE 0x3025
|
||||||
#define EGL_STENCIL_SIZE 0x3026
|
#define EGL_STENCIL_SIZE 0x3026
|
||||||
#define EGL_SAMPLES 0x3031
|
#define EGL_SAMPLES 0x3031
|
||||||
#define EGL_OPENGL_ES_API 0x30a0
|
#define EGL_OPENGL_ES_API 0x30a0
|
||||||
#define EGL_OPENGL_API 0x30a2
|
#define EGL_OPENGL_API 0x30a2
|
||||||
#define EGL_NONE 0x3038
|
#define EGL_NONE 0x3038
|
||||||
|
30
src/glfw.rc.in
Normal file
30
src/glfw.rc.in
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
#include <winver.h>
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
|
||||||
|
PRODUCTVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
FILEFLAGS 0
|
||||||
|
FILEOS VOS_NT_WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE 0
|
||||||
|
{
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
{
|
||||||
|
BLOCK "040904B0"
|
||||||
|
{
|
||||||
|
VALUE "CompanyName", "GLFW"
|
||||||
|
VALUE "FileDescription", "GLFW @GLFW_VERSION@ DLL"
|
||||||
|
VALUE "FileVersion", "@GLFW_VERSION@"
|
||||||
|
VALUE "OriginalFilename", "glfw3.dll"
|
||||||
|
VALUE "ProductName", "GLFW"
|
||||||
|
VALUE "ProductVersion", "@GLFW_VERSION@"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
{
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
|
|
@ -45,8 +45,6 @@
|
|||||||
// Define this to 1 if building GLFW for OSMesa
|
// Define this to 1 if building GLFW for OSMesa
|
||||||
#cmakedefine _GLFW_OSMESA
|
#cmakedefine _GLFW_OSMESA
|
||||||
|
|
||||||
// Define this to 1 if building as a shared library / dynamic library / DLL
|
|
||||||
#cmakedefine _GLFW_BUILD_DLL
|
|
||||||
// Define this to 1 to use Vulkan loader linked statically into application
|
// Define this to 1 to use Vulkan loader linked statically into application
|
||||||
#cmakedefine _GLFW_VULKAN_STATIC
|
#cmakedefine _GLFW_VULKAN_STATIC
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -226,8 +228,6 @@ static GLFWglproc getProcAddressGLX(const char* procname)
|
|||||||
return _glfw_dlsym(_glfw.glx.handle, procname);
|
return _glfw_dlsym(_glfw.glx.handle, procname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the OpenGL context
|
|
||||||
//
|
|
||||||
static void destroyContextGLX(_GLFWwindow* window)
|
static void destroyContextGLX(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->context.glx.window)
|
if (window->context.glx.window)
|
||||||
|
@ -29,11 +29,11 @@
|
|||||||
#define GLX_RGBA_BIT 0x00000001
|
#define GLX_RGBA_BIT 0x00000001
|
||||||
#define GLX_WINDOW_BIT 0x00000001
|
#define GLX_WINDOW_BIT 0x00000001
|
||||||
#define GLX_DRAWABLE_TYPE 0x8010
|
#define GLX_DRAWABLE_TYPE 0x8010
|
||||||
#define GLX_RENDER_TYPE 0x8011
|
#define GLX_RENDER_TYPE 0x8011
|
||||||
#define GLX_RGBA_TYPE 0x8014
|
#define GLX_RGBA_TYPE 0x8014
|
||||||
#define GLX_DOUBLEBUFFER 5
|
#define GLX_DOUBLEBUFFER 5
|
||||||
#define GLX_STEREO 6
|
#define GLX_STEREO 6
|
||||||
#define GLX_AUX_BUFFERS 7
|
#define GLX_AUX_BUFFERS 7
|
||||||
#define GLX_RED_SIZE 8
|
#define GLX_RED_SIZE 8
|
||||||
#define GLX_GREEN_SIZE 9
|
#define GLX_GREEN_SIZE 9
|
||||||
#define GLX_BLUE_SIZE 10
|
#define GLX_BLUE_SIZE 10
|
||||||
@ -42,7 +42,7 @@
|
|||||||
#define GLX_STENCIL_SIZE 13
|
#define GLX_STENCIL_SIZE 13
|
||||||
#define GLX_ACCUM_RED_SIZE 14
|
#define GLX_ACCUM_RED_SIZE 14
|
||||||
#define GLX_ACCUM_GREEN_SIZE 15
|
#define GLX_ACCUM_GREEN_SIZE 15
|
||||||
#define GLX_ACCUM_BLUE_SIZE 16
|
#define GLX_ACCUM_BLUE_SIZE 16
|
||||||
#define GLX_ACCUM_ALPHA_SIZE 17
|
#define GLX_ACCUM_ALPHA_SIZE 17
|
||||||
#define GLX_SAMPLES 0x186a1
|
#define GLX_SAMPLES 0x186a1
|
||||||
#define GLX_VISUAL_ID 0x800b
|
#define GLX_VISUAL_ID 0x800b
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "mappings.h"
|
#include "mappings.h"
|
||||||
@ -187,6 +189,8 @@ void _glfwInputError(int code, const char* format, ...)
|
|||||||
strcpy(description, "The requested format is unavailable");
|
strcpy(description, "The requested format is unavailable");
|
||||||
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
||||||
strcpy(description, "The specified window has no context");
|
strcpy(description, "The specified window has no context");
|
||||||
|
else if (code == GLFW_CURSOR_UNAVAILABLE)
|
||||||
|
strcpy(description, "The specified cursor shape is unavailable");
|
||||||
else
|
else
|
||||||
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||||
}
|
}
|
||||||
|
12
src/input.c
12
src/input.c
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -755,9 +757,13 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
|||||||
if (shape != GLFW_ARROW_CURSOR &&
|
if (shape != GLFW_ARROW_CURSOR &&
|
||||||
shape != GLFW_IBEAM_CURSOR &&
|
shape != GLFW_IBEAM_CURSOR &&
|
||||||
shape != GLFW_CROSSHAIR_CURSOR &&
|
shape != GLFW_CROSSHAIR_CURSOR &&
|
||||||
shape != GLFW_HAND_CURSOR &&
|
shape != GLFW_POINTING_HAND_CURSOR &&
|
||||||
shape != GLFW_HRESIZE_CURSOR &&
|
shape != GLFW_RESIZE_EW_CURSOR &&
|
||||||
shape != GLFW_VRESIZE_CURSOR)
|
shape != GLFW_RESIZE_NS_CURSOR &&
|
||||||
|
shape != GLFW_RESIZE_NWSE_CURSOR &&
|
||||||
|
shape != GLFW_RESIZE_NESW_CURSOR &&
|
||||||
|
shape != GLFW_RESIZE_ALL_CURSOR &&
|
||||||
|
shape != GLFW_NOT_ALLOWED_CURSOR)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -84,8 +84,8 @@ typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
|
|||||||
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
||||||
|
|
||||||
#define GL_VERSION 0x1f02
|
#define GL_VERSION 0x1f02
|
||||||
#define GL_NONE 0
|
#define GL_NONE 0
|
||||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||||
#define GL_UNSIGNED_BYTE 0x1401
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
#define GL_EXTENSIONS 0x1f03
|
#define GL_EXTENSIONS 0x1f03
|
||||||
#define GL_NUM_EXTENSIONS 0x821d
|
#define GL_NUM_EXTENSIONS 0x821d
|
||||||
@ -102,7 +102,7 @@ typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
|||||||
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
|
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
|
||||||
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
|
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
|
||||||
|
|
||||||
typedef int GLint;
|
typedef int GLint;
|
||||||
typedef unsigned int GLuint;
|
typedef unsigned int GLuint;
|
||||||
typedef unsigned int GLenum;
|
typedef unsigned int GLenum;
|
||||||
typedef unsigned int GLbitfield;
|
typedef unsigned int GLbitfield;
|
||||||
@ -128,6 +128,7 @@ typedef enum VkStructureType
|
|||||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
||||||
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
||||||
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
||||||
|
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
|
||||||
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VkStructureType;
|
} VkStructureType;
|
||||||
|
|
||||||
@ -274,6 +275,9 @@ struct _GLFWwndconfig
|
|||||||
char className[256];
|
char className[256];
|
||||||
char instanceName[256];
|
char instanceName[256];
|
||||||
} x11;
|
} x11;
|
||||||
|
struct {
|
||||||
|
GLFWbool keymenu;
|
||||||
|
} win32;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Context configuration
|
// Context configuration
|
||||||
@ -556,6 +560,7 @@ struct _GLFWlibrary
|
|||||||
GLFWbool KHR_win32_surface;
|
GLFWbool KHR_win32_surface;
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
GLFWbool MVK_macos_surface;
|
GLFWbool MVK_macos_surface;
|
||||||
|
GLFWbool EXT_metal_surface;
|
||||||
#elif defined(_GLFW_X11)
|
#elif defined(_GLFW_X11)
|
||||||
GLFWbool KHR_xlib_surface;
|
GLFWbool KHR_xlib_surface;
|
||||||
GLFWbool KHR_xcb_surface;
|
GLFWbool KHR_xcb_surface;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -104,9 +106,7 @@ static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
|
|||||||
//
|
//
|
||||||
static void pollAbsState(_GLFWjoystick* js)
|
static void pollAbsState(_GLFWjoystick* js)
|
||||||
{
|
{
|
||||||
int code;
|
for (int code = 0; code < ABS_CNT; code++)
|
||||||
|
|
||||||
for (code = 0; code < ABS_CNT; code++)
|
|
||||||
{
|
{
|
||||||
if (js->linjs.absMap[code] < 0)
|
if (js->linjs.absMap[code] < 0)
|
||||||
continue;
|
continue;
|
||||||
@ -126,18 +126,7 @@ static void pollAbsState(_GLFWjoystick* js)
|
|||||||
//
|
//
|
||||||
static GLFWbool openJoystickDevice(const char* path)
|
static GLFWbool openJoystickDevice(const char* path)
|
||||||
{
|
{
|
||||||
int jid, code;
|
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
char name[256] = "";
|
|
||||||
char guid[33] = "";
|
|
||||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
|
||||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
|
||||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
|
||||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
|
||||||
struct input_id id;
|
|
||||||
_GLFWjoystickLinux linjs = {0};
|
|
||||||
_GLFWjoystick* js = NULL;
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
{
|
||||||
if (!_glfw.joysticks[jid].present)
|
if (!_glfw.joysticks[jid].present)
|
||||||
continue;
|
continue;
|
||||||
@ -145,10 +134,16 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_GLFWjoystickLinux linjs = {0};
|
||||||
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||||
if (linjs.fd == -1)
|
if (linjs.fd == -1)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||||
|
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||||
|
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||||
|
struct input_id id;
|
||||||
|
|
||||||
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||||
@ -168,9 +163,13 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char name[256] = "";
|
||||||
|
|
||||||
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
||||||
strncpy(name, "Unknown", sizeof(name));
|
strncpy(name, "Unknown", sizeof(name));
|
||||||
|
|
||||||
|
char guid[33] = "";
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||||
if (id.vendor && id.product && id.version)
|
if (id.vendor && id.product && id.version)
|
||||||
{
|
{
|
||||||
@ -189,7 +188,9 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
name[8], name[9], name[10]);
|
name[8], name[9], name[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (code = BTN_MISC; code < KEY_CNT; code++)
|
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||||
|
|
||||||
|
for (int code = BTN_MISC; code < KEY_CNT; code++)
|
||||||
{
|
{
|
||||||
if (!isBitSet(code, keyBits))
|
if (!isBitSet(code, keyBits))
|
||||||
continue;
|
continue;
|
||||||
@ -198,7 +199,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
buttonCount++;
|
buttonCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (code = 0; code < ABS_CNT; code++)
|
for (int code = 0; code < ABS_CNT; code++)
|
||||||
{
|
{
|
||||||
linjs.absMap[code] = -1;
|
linjs.absMap[code] = -1;
|
||||||
if (!isBitSet(code, absBits))
|
if (!isBitSet(code, absBits))
|
||||||
@ -221,7 +222,8 @@ static GLFWbool openJoystickDevice(const char* path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
_GLFWjoystick* js =
|
||||||
|
_glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||||
if (!js)
|
if (!js)
|
||||||
{
|
{
|
||||||
close(linjs.fd);
|
close(linjs.fd);
|
||||||
@ -266,8 +268,6 @@ static int compareJoysticks(const void* fp, const void* sp)
|
|||||||
//
|
//
|
||||||
GLFWbool _glfwInitJoysticksLinux(void)
|
GLFWbool _glfwInitJoysticksLinux(void)
|
||||||
{
|
{
|
||||||
DIR* dir;
|
|
||||||
int count = 0;
|
|
||||||
const char* dirname = "/dev/input";
|
const char* dirname = "/dev/input";
|
||||||
|
|
||||||
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||||
@ -289,7 +289,9 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = opendir(dirname);
|
int count = 0;
|
||||||
|
|
||||||
|
DIR* dir = opendir(dirname);
|
||||||
if (dir)
|
if (dir)
|
||||||
{
|
{
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
@ -344,12 +346,11 @@ void _glfwTerminateJoysticksLinux(void)
|
|||||||
|
|
||||||
void _glfwDetectJoystickConnectionLinux(void)
|
void _glfwDetectJoystickConnectionLinux(void)
|
||||||
{
|
{
|
||||||
ssize_t offset = 0;
|
|
||||||
char buffer[16384];
|
|
||||||
|
|
||||||
if (_glfw.linjs.inotify <= 0)
|
if (_glfw.linjs.inotify <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ssize_t offset = 0;
|
||||||
|
char buffer[16384];
|
||||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||||
|
|
||||||
while (size > offset)
|
while (size > offset)
|
||||||
@ -369,9 +370,7 @@ void _glfwDetectJoystickConnectionLinux(void)
|
|||||||
openJoystickDevice(path);
|
openJoystickDevice(path);
|
||||||
else if (e->mask & IN_DELETE)
|
else if (e->mask & IN_DELETE)
|
||||||
{
|
{
|
||||||
int jid;
|
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
{
|
||||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,6 @@ const char* _glfwDefaultMappings[] =
|
|||||||
"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
|
"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
|
||||||
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
|
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
|
||||||
"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,",
|
"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,",
|
||||||
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,",
|
|
||||||
"03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,",
|
"03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,",
|
||||||
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
|
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,",
|
||||||
"03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
|
"03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,",
|
||||||
@ -207,7 +206,6 @@ const char* _glfwDefaultMappings[] =
|
|||||||
"030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
|
"030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
|
||||||
"03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,",
|
"03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,",
|
||||||
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",
|
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,",
|
||||||
"03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X,",
|
|
||||||
"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
|
"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,",
|
||||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",
|
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,",
|
||||||
"030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
|
"030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,",
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -54,6 +56,10 @@ static int compareVideoModes(const void* fp, const void* sp)
|
|||||||
if (farea != sarea)
|
if (farea != sarea)
|
||||||
return farea - sarea;
|
return farea - sarea;
|
||||||
|
|
||||||
|
// Then sort on width
|
||||||
|
if (fm->width != sm->width)
|
||||||
|
return fm->width - sm->width;
|
||||||
|
|
||||||
// Lastly sort on refresh rate
|
// Lastly sort on refresh rate
|
||||||
return fm->refreshRate - sm->refreshRate;
|
return fm->refreshRate - sm->refreshRate;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||||
|
// SDK versions where one is unavailable or the other deprecated
|
||||||
|
// We use the newer names in code and these macros to handle compatibility
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
|
||||||
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
||||||
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||||
@ -41,10 +44,6 @@ typedef struct _GLFWcontextNSGL
|
|||||||
{
|
{
|
||||||
id pixelFormat;
|
id pixelFormat;
|
||||||
id object;
|
id object;
|
||||||
CVDisplayLinkRef displayLink;
|
|
||||||
atomic_int swapInterval;
|
|
||||||
int swapIntervalsPassed;
|
|
||||||
id swapIntervalCond;
|
|
||||||
|
|
||||||
} _GLFWcontextNSGL;
|
} _GLFWcontextNSGL;
|
||||||
|
|
||||||
@ -64,5 +63,4 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||||
void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window);
|
|
||||||
|
|
||||||
|
@ -23,32 +23,13 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
// Display link callback for manual swap interval implementation
|
#include <unistd.h>
|
||||||
// This is based on a similar workaround added to SDL2
|
#include <math.h>
|
||||||
//
|
|
||||||
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink,
|
|
||||||
const CVTimeStamp* now,
|
|
||||||
const CVTimeStamp* outputTime,
|
|
||||||
CVOptionFlags flagsIn,
|
|
||||||
CVOptionFlags* flagsOut,
|
|
||||||
void* userInfo)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow *) userInfo;
|
|
||||||
|
|
||||||
const int interval = atomic_load(&window->context.nsgl.swapInterval);
|
|
||||||
if (interval > 0)
|
|
||||||
{
|
|
||||||
[window->context.nsgl.swapIntervalCond lock];
|
|
||||||
window->context.nsgl.swapIntervalsPassed++;
|
|
||||||
[window->context.nsgl.swapIntervalCond signal];
|
|
||||||
[window->context.nsgl.swapIntervalCond unlock];
|
|
||||||
}
|
|
||||||
|
|
||||||
return kCVReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
@ -68,19 +49,28 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
const int interval = atomic_load(&window->context.nsgl.swapInterval);
|
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
||||||
if (interval > 0)
|
// windows with a non-visible occlusion state
|
||||||
|
if (!([window->ns.object occlusionState] & NSWindowOcclusionStateVisible))
|
||||||
{
|
{
|
||||||
[window->context.nsgl.swapIntervalCond lock];
|
int interval = 0;
|
||||||
do
|
[window->context.nsgl.object getValues:&interval
|
||||||
|
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
|
|
||||||
|
if (interval > 0)
|
||||||
{
|
{
|
||||||
[window->context.nsgl.swapIntervalCond wait];
|
const double framerate = 60.0;
|
||||||
} while (window->context.nsgl.swapIntervalsPassed % interval != 0);
|
const uint64_t frequency = _glfwPlatformGetTimerFrequency();
|
||||||
window->context.nsgl.swapIntervalsPassed = 0;
|
const uint64_t value = _glfwPlatformGetTimerValue();
|
||||||
[window->context.nsgl.swapIntervalCond unlock];
|
|
||||||
|
const double elapsed = value / (double) frequency;
|
||||||
|
const double period = 1.0 / framerate;
|
||||||
|
const double delay = period - fmod(elapsed, period);
|
||||||
|
|
||||||
|
usleep(floorl(delay * 1e6));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARP appears to be unnecessary, but this is future-proof
|
|
||||||
[window->context.nsgl.object flushBuffer];
|
[window->context.nsgl.object flushBuffer];
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
@ -89,11 +79,14 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
|||||||
static void swapIntervalNSGL(int interval)
|
static void swapIntervalNSGL(int interval)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
atomic_store(&window->context.nsgl.swapInterval, interval);
|
if (window)
|
||||||
[window->context.nsgl.swapIntervalCond lock];
|
{
|
||||||
window->context.nsgl.swapIntervalsPassed = 0;
|
[window->context.nsgl.object setValues:&interval
|
||||||
[window->context.nsgl.swapIntervalCond unlock];
|
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
|
}
|
||||||
|
|
||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,23 +110,10 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the OpenGL context
|
|
||||||
//
|
|
||||||
static void destroyContextNSGL(_GLFWwindow* window)
|
static void destroyContextNSGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
if (window->context.nsgl.displayLink)
|
|
||||||
{
|
|
||||||
if (CVDisplayLinkIsRunning(window->context.nsgl.displayLink))
|
|
||||||
CVDisplayLinkStop(window->context.nsgl.displayLink);
|
|
||||||
|
|
||||||
CVDisplayLinkRelease(window->context.nsgl.displayLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
[window->context.nsgl.swapIntervalCond release];
|
|
||||||
window->context.nsgl.swapIntervalCond = nil;
|
|
||||||
|
|
||||||
[window->context.nsgl.pixelFormat release];
|
[window->context.nsgl.pixelFormat release];
|
||||||
window->context.nsgl.pixelFormat = nil;
|
window->context.nsgl.pixelFormat = nil;
|
||||||
|
|
||||||
@ -194,13 +174,6 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
|
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
|
||||||
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context robustness modes (GL_KHR_robustness) are not yet supported by
|
// Context robustness modes (GL_KHR_robustness) are not yet supported by
|
||||||
@ -339,7 +312,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSOpenGLContext* share = NULL;
|
NSOpenGLContext* share = nil;
|
||||||
|
|
||||||
if (ctxconfig->share)
|
if (ctxconfig->share)
|
||||||
share = ctxconfig->share->context.nsgl.object;
|
share = ctxconfig->share->context.nsgl.object;
|
||||||
@ -361,17 +334,10 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->ns.retina)
|
[window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina];
|
||||||
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
|
||||||
|
|
||||||
GLint interval = 0;
|
|
||||||
[window->context.nsgl.object setValues:&interval
|
|
||||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
|
||||||
|
|
||||||
[window->context.nsgl.object setView:window->ns.view];
|
[window->context.nsgl.object setView:window->ns.view];
|
||||||
|
|
||||||
window->context.nsgl.swapIntervalCond = [NSCondition new];
|
|
||||||
|
|
||||||
window->context.makeCurrent = makeContextCurrentNSGL;
|
window->context.makeCurrent = makeContextCurrentNSGL;
|
||||||
window->context.swapBuffers = swapBuffersNSGL;
|
window->context.swapBuffers = swapBuffersNSGL;
|
||||||
window->context.swapInterval = swapIntervalNSGL;
|
window->context.swapInterval = swapIntervalNSGL;
|
||||||
@ -379,26 +345,9 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
window->context.getProcAddress = getProcAddressNSGL;
|
window->context.getProcAddress = getProcAddressNSGL;
|
||||||
window->context.destroy = destroyContextNSGL;
|
window->context.destroy = destroyContextNSGL;
|
||||||
|
|
||||||
CVDisplayLinkCreateWithActiveCGDisplays(&window->context.nsgl.displayLink);
|
|
||||||
CVDisplayLinkSetOutputCallback(window->context.nsgl.displayLink,
|
|
||||||
&displayLinkCallback,
|
|
||||||
window);
|
|
||||||
CVDisplayLinkStart(window->context.nsgl.displayLink);
|
|
||||||
|
|
||||||
_glfwUpdateDisplayLinkDisplayNSGL(window);
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
CGDirectDisplayID displayID =
|
|
||||||
[[[window->ns.object screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
|
||||||
if (!displayID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CVDisplayLinkSetCurrentCGDisplay(window->context.nsgl.displayLink, displayID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW native API //////
|
////// GLFW native API //////
|
||||||
@ -412,7 +361,7 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
|
|||||||
if (window->context.client == GLFW_NO_API)
|
if (window->context.client == GLFW_NO_API)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
return NULL;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return window->context.nsgl.object;
|
return window->context.nsgl.object;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs
|
#define _GLFW_PLATFORM_JOYSTICK_STATE struct { int dummyJoystick; }
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; }
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@
|
|||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE
|
#define _GLFW_PLATFORM_MONITOR_STATE struct { int dummyMonitor; }
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE
|
#define _GLFW_PLATFORM_CURSOR_STATE struct { int dummyCursor; }
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE struct { int dummyLibraryWindow; }
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
|
||||||
#define _GLFW_EGL_CONTEXT_STATE
|
#define _GLFW_EGL_CONTEXT_STATE struct { int dummyEGLContext; }
|
||||||
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
|
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE struct { int dummyEGLLibraryContext; }
|
||||||
|
|
||||||
#include "osmesa_context.h"
|
#include "osmesa_context.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -24,9 +24,14 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
@ -39,7 +44,7 @@
|
|||||||
//
|
//
|
||||||
void _glfwInitTimerPOSIX(void)
|
void _glfwInitTimerPOSIX(void)
|
||||||
{
|
{
|
||||||
#if defined(CLOCK_MONOTONIC)
|
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||||
@ -62,7 +67,7 @@ void _glfwInitTimerPOSIX(void)
|
|||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerValue(void)
|
uint64_t _glfwPlatformGetTimerValue(void)
|
||||||
{
|
{
|
||||||
#if defined(CLOCK_MONOTONIC)
|
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||||
if (_glfw.timer.posix.monotonic)
|
if (_glfw.timer.posix.monotonic)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -55,6 +57,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
||||||
|
if (!_glfw.vk.handle)
|
||||||
|
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
|
||||||
#else
|
#else
|
||||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
||||||
#endif
|
#endif
|
||||||
@ -128,6 +132,8 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
||||||
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
|
||||||
|
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
|
||||||
#elif defined(_GLFW_X11)
|
#elif defined(_GLFW_X11)
|
||||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
||||||
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -75,8 +77,8 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||||
|
|
||||||
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
|
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||||
1, 0, 1, &attrib, &nativeCount))
|
1, 0, 1, &attrib, &nativeCount))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to retrieve pixel format attribute");
|
"WGL: Failed to retrieve pixel format attribute");
|
||||||
@ -139,10 +141,10 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
// Get pixel format attributes through "modern" extension
|
// Get pixel format attributes through "modern" extension
|
||||||
|
|
||||||
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
|
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||||
pixelFormat, 0,
|
pixelFormat, 0,
|
||||||
attribCount,
|
attribCount,
|
||||||
attribs, values))
|
attribs, values))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to retrieve pixel format attributes");
|
"WGL: Failed to retrieve pixel format attributes");
|
||||||
@ -360,7 +362,7 @@ static void swapIntervalWGL(int interval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.wgl.EXT_swap_control)
|
if (_glfw.wgl.EXT_swap_control)
|
||||||
_glfw.wgl.SwapIntervalEXT(interval);
|
wglSwapIntervalEXT(interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int extensionSupportedWGL(const char* extension)
|
static int extensionSupportedWGL(const char* extension)
|
||||||
@ -368,9 +370,9 @@ static int extensionSupportedWGL(const char* extension)
|
|||||||
const char* extensions = NULL;
|
const char* extensions = NULL;
|
||||||
|
|
||||||
if (_glfw.wgl.GetExtensionsStringARB)
|
if (_glfw.wgl.GetExtensionsStringARB)
|
||||||
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
|
||||||
else if (_glfw.wgl.GetExtensionsStringEXT)
|
else if (_glfw.wgl.GetExtensionsStringEXT)
|
||||||
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
extensions = wglGetExtensionsStringEXT();
|
||||||
|
|
||||||
if (!extensions)
|
if (!extensions)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@ -387,8 +389,6 @@ static GLFWglproc getProcAddressWGL(const char* procname)
|
|||||||
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
|
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the OpenGL context
|
|
||||||
//
|
|
||||||
static void destroyContextWGL(_GLFWwindow* window)
|
static void destroyContextWGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->context.wgl.handle)
|
if (window->context.wgl.handle)
|
||||||
@ -693,8 +693,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
setAttrib(0, 0);
|
setAttrib(0, 0);
|
||||||
|
|
||||||
window->context.wgl.handle =
|
window->context.wgl.handle =
|
||||||
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
|
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
|
||||||
share, attribs);
|
|
||||||
if (!window->context.wgl.handle)
|
if (!window->context.wgl.handle)
|
||||||
{
|
{
|
||||||
const DWORD error = GetLastError();
|
const DWORD error = GetLastError();
|
||||||
|
@ -76,12 +76,19 @@
|
|||||||
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||||
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
||||||
|
|
||||||
|
// WGL extension pointer typedefs
|
||||||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
|
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
||||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
|
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
|
||||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
|
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
|
||||||
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
|
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
|
||||||
|
#define wglSwapIntervalEXT _glfw.wgl.SwapIntervalEXT
|
||||||
|
#define wglGetPixelFormatAttribivARB _glfw.wgl.GetPixelFormatAttribivARB
|
||||||
|
#define wglGetExtensionsStringEXT _glfw.wgl.GetExtensionsStringEXT
|
||||||
|
#define wglGetExtensionsStringARB _glfw.wgl.GetExtensionsStringARB
|
||||||
|
#define wglCreateContextAttribsARB _glfw.wgl.CreateContextAttribsARB
|
||||||
|
|
||||||
|
// opengl32.dll function pointer typedefs
|
||||||
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
|
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
|
||||||
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
|
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
|
||||||
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
|
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
|
||||||
@ -89,8 +96,6 @@ typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
|
|||||||
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
|
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
|
||||||
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
|
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
|
||||||
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
|
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
|
||||||
|
|
||||||
// opengl32.dll function pointer typedefs
|
|
||||||
#define wglCreateContext _glfw.wgl.CreateContext
|
#define wglCreateContext _glfw.wgl.CreateContext
|
||||||
#define wglDeleteContext _glfw.wgl.DeleteContext
|
#define wglDeleteContext _glfw.wgl.DeleteContext
|
||||||
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
||||||
@ -99,10 +104,6 @@ typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
|
|||||||
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
||||||
#define wglShareLists _glfw.wgl.ShareLists
|
#define wglShareLists _glfw.wgl.ShareLists
|
||||||
|
|
||||||
#define _GLFW_RECREATION_NOT_NEEDED 0
|
|
||||||
#define _GLFW_RECREATION_REQUIRED 1
|
|
||||||
#define _GLFW_RECREATION_IMPOSSIBLE 2
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -523,7 +525,7 @@ BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
|||||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
// latter lies unless the user knew to embedd a non-default manifest
|
// latter lies unless the user knew to embed a non-default manifest
|
||||||
// announcing support for Windows 10 via supportedOS GUID
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||||
}
|
}
|
||||||
@ -538,7 +540,7 @@ BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
|
|||||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
||||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
// latter lies unless the user knew to embedd a non-default manifest
|
// latter lies unless the user knew to embed a non-default manifest
|
||||||
// announcing support for Windows 10 via supportedOS GUID
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
|
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; }
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
|
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -31,6 +33,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
|
||||||
// Callback for EnumDisplayMonitors in createMonitor
|
// Callback for EnumDisplayMonitors in createMonitor
|
||||||
@ -475,7 +478,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
HDC dc;
|
HDC dc;
|
||||||
WORD values[768];
|
WORD values[3][256];
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||||
GetDeviceGammaRamp(dc, values);
|
GetDeviceGammaRamp(dc, values);
|
||||||
@ -483,9 +486,9 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
|
|
||||||
_glfwAllocGammaArrays(ramp, 256);
|
_glfwAllocGammaArrays(ramp, 256);
|
||||||
|
|
||||||
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
|
memcpy(ramp->red, values[0], sizeof(values[0]));
|
||||||
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
|
memcpy(ramp->green, values[1], sizeof(values[1]));
|
||||||
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
|
memcpy(ramp->blue, values[2], sizeof(values[2]));
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
@ -493,7 +496,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
{
|
{
|
||||||
HDC dc;
|
HDC dc;
|
||||||
WORD values[768];
|
WORD values[3][256];
|
||||||
|
|
||||||
if (ramp->size != 256)
|
if (ramp->size != 256)
|
||||||
{
|
{
|
||||||
@ -502,9 +505,9 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
|
memcpy(values[0], ramp->red, sizeof(values[0]));
|
||||||
memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
|
memcpy(values[1], ramp->green, sizeof(values[1]));
|
||||||
memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
|
memcpy(values[2], ramp->blue, sizeof(values[2]));
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||||
SetDeviceGammaRamp(dc, values);
|
SetDeviceGammaRamp(dc, values);
|
||||||
|
@ -212,7 +212,7 @@ typedef enum
|
|||||||
|
|
||||||
// HACK: Define macros that some dinput.h variants don't
|
// HACK: Define macros that some dinput.h variants don't
|
||||||
#ifndef DIDFT_OPTIONAL
|
#ifndef DIDFT_OPTIONAL
|
||||||
#define DIDFT_OPTIONAL 0x80000000
|
#define DIDFT_OPTIONAL 0x80000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// winmm.dll function pointer typedefs
|
// winmm.dll function pointer typedefs
|
||||||
@ -315,6 +315,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
// Whether to enable framebuffer transparency on DWM
|
// Whether to enable framebuffer transparency on DWM
|
||||||
GLFWbool transparent;
|
GLFWbool transparent;
|
||||||
GLFWbool scaleToMonitor;
|
GLFWbool scaleToMonitor;
|
||||||
|
GLFWbool keymenu;
|
||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -34,8 +36,6 @@
|
|||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
|
||||||
#define _GLFW_KEY_INVALID -2
|
|
||||||
|
|
||||||
// Returns the window style for the specified window
|
// Returns the window style for the specified window
|
||||||
//
|
//
|
||||||
static DWORD getWindowStyle(const _GLFWwindow* window)
|
static DWORD getWindowStyle(const _GLFWwindow* window)
|
||||||
@ -409,7 +409,7 @@ static void updateFramebufferTransparency(const _GLFWwindow* window)
|
|||||||
// issue. When set to black, something is making the hit test
|
// issue. When set to black, something is making the hit test
|
||||||
// not resize with the window frame.
|
// not resize with the window frame.
|
||||||
SetLayeredWindowAttributes(window->win32.handle,
|
SetLayeredWindowAttributes(window->win32.handle,
|
||||||
RGB(0, 193, 48), 255, LWA_COLORKEY);
|
RGB(255, 0, 255), 255, LWA_COLORKEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteObject(region);
|
DeleteObject(region);
|
||||||
@ -446,77 +446,6 @@ static int getKeyMods(void)
|
|||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves and translates modifier keys
|
|
||||||
//
|
|
||||||
static int getAsyncKeyMods(void)
|
|
||||||
{
|
|
||||||
int mods = 0;
|
|
||||||
|
|
||||||
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_SHIFT;
|
|
||||||
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_CONTROL;
|
|
||||||
if (GetAsyncKeyState(VK_MENU) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_ALT;
|
|
||||||
if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & 0x8000)
|
|
||||||
mods |= GLFW_MOD_SUPER;
|
|
||||||
if (GetAsyncKeyState(VK_CAPITAL) & 1)
|
|
||||||
mods |= GLFW_MOD_CAPS_LOCK;
|
|
||||||
if (GetAsyncKeyState(VK_NUMLOCK) & 1)
|
|
||||||
mods |= GLFW_MOD_NUM_LOCK;
|
|
||||||
|
|
||||||
return mods;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translates a Windows key to the corresponding GLFW key
|
|
||||||
//
|
|
||||||
static int translateKey(WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
// The Ctrl keys require special handling
|
|
||||||
if (wParam == VK_CONTROL)
|
|
||||||
{
|
|
||||||
MSG next;
|
|
||||||
DWORD time;
|
|
||||||
|
|
||||||
// Right side keys have the extended key bit set
|
|
||||||
if (lParam & 0x01000000)
|
|
||||||
return GLFW_KEY_RIGHT_CONTROL;
|
|
||||||
|
|
||||||
// HACK: Alt Gr sends Left Ctrl and then Right Alt in close sequence
|
|
||||||
// We only want the Right Alt message, so if the next message is
|
|
||||||
// Right Alt we ignore this (synthetic) Left Ctrl message
|
|
||||||
time = GetMessageTime();
|
|
||||||
|
|
||||||
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
|
||||||
{
|
|
||||||
if (next.message == WM_KEYDOWN ||
|
|
||||||
next.message == WM_SYSKEYDOWN ||
|
|
||||||
next.message == WM_KEYUP ||
|
|
||||||
next.message == WM_SYSKEYUP)
|
|
||||||
{
|
|
||||||
if (next.wParam == VK_MENU &&
|
|
||||||
(next.lParam & 0x01000000) &&
|
|
||||||
next.time == time)
|
|
||||||
{
|
|
||||||
// Next message is Right Alt down so discard this
|
|
||||||
return _GLFW_KEY_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_KEY_LEFT_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wParam == VK_PROCESSKEY)
|
|
||||||
{
|
|
||||||
// IME notifies that keys have been filtered by setting the virtual
|
|
||||||
// key-code to VK_PROCESSKEY
|
|
||||||
return _GLFW_KEY_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _glfw.win32.keycodes[HIWORD(lParam) & 0x1FF];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fitToMonitor(_GLFWwindow* window)
|
static void fitToMonitor(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MONITORINFO mi = { sizeof(mi) };
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
@ -629,12 +558,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
// clicking a caption button
|
// clicking a caption button
|
||||||
if (HIWORD(lParam) == WM_LBUTTONDOWN)
|
if (HIWORD(lParam) == WM_LBUTTONDOWN)
|
||||||
{
|
{
|
||||||
if (LOWORD(lParam) == HTCLOSE ||
|
if (LOWORD(lParam) != HTCLIENT)
|
||||||
LOWORD(lParam) == HTMINBUTTON ||
|
|
||||||
LOWORD(lParam) == HTMAXBUTTON)
|
|
||||||
{
|
|
||||||
window->win32.frameAction = GLFW_TRUE;
|
window->win32.frameAction = GLFW_TRUE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -701,7 +626,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
// User trying to access application menu using ALT?
|
// User trying to access application menu using ALT?
|
||||||
case SC_KEYMENU:
|
case SC_KEYMENU:
|
||||||
return 0;
|
{
|
||||||
|
if (!window->win32.keymenu)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -733,6 +663,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);
|
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);
|
||||||
|
|
||||||
|
if (uMsg == WM_SYSCHAR && window->win32.keymenu)
|
||||||
|
break;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,13 +675,64 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
{
|
{
|
||||||
const int key = translateKey(wParam, lParam);
|
int key, scancode;
|
||||||
const int scancode = (lParam >> 16) & 0x1ff;
|
const int action = (HIWORD(lParam) & KF_UP) ? GLFW_RELEASE : GLFW_PRESS;
|
||||||
const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;
|
|
||||||
const int mods = getKeyMods();
|
const int mods = getKeyMods();
|
||||||
|
|
||||||
if (key == _GLFW_KEY_INVALID)
|
scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff));
|
||||||
|
if (!scancode)
|
||||||
|
{
|
||||||
|
// NOTE: Some synthetic key messages have a scancode of zero
|
||||||
|
// HACK: Map the virtual key back to a usable scancode
|
||||||
|
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
|
||||||
|
}
|
||||||
|
|
||||||
|
key = _glfw.win32.keycodes[scancode];
|
||||||
|
|
||||||
|
// The Ctrl keys require special handling
|
||||||
|
if (wParam == VK_CONTROL)
|
||||||
|
{
|
||||||
|
if (HIWORD(lParam) & KF_EXTENDED)
|
||||||
|
{
|
||||||
|
// Right side keys have the extended key bit set
|
||||||
|
key = GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NOTE: Alt Gr sends Left Ctrl followed by Right Alt
|
||||||
|
// HACK: We only want one event for Alt Gr, so if we detect
|
||||||
|
// this sequence we discard this Left Ctrl message now
|
||||||
|
// and later report Right Alt normally
|
||||||
|
MSG next;
|
||||||
|
const DWORD time = GetMessageTime();
|
||||||
|
|
||||||
|
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
||||||
|
{
|
||||||
|
if (next.message == WM_KEYDOWN ||
|
||||||
|
next.message == WM_SYSKEYDOWN ||
|
||||||
|
next.message == WM_KEYUP ||
|
||||||
|
next.message == WM_SYSKEYUP)
|
||||||
|
{
|
||||||
|
if (next.wParam == VK_MENU &&
|
||||||
|
(HIWORD(next.lParam) & KF_EXTENDED) &&
|
||||||
|
next.time == time)
|
||||||
|
{
|
||||||
|
// Next message is Right Alt down so discard this
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a regular Left Ctrl message
|
||||||
|
key = GLFW_KEY_LEFT_CONTROL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wParam == VK_PROCESSKEY)
|
||||||
|
{
|
||||||
|
// IME notifies that keys have been filtered by setting the
|
||||||
|
// virtual key-code to VK_PROCESSKEY
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
|
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
|
||||||
{
|
{
|
||||||
@ -830,7 +815,19 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
const int x = GET_X_LPARAM(lParam);
|
const int x = GET_X_LPARAM(lParam);
|
||||||
const int y = GET_Y_LPARAM(lParam);
|
const int y = GET_Y_LPARAM(lParam);
|
||||||
|
|
||||||
// Disabled cursor motion input is provided by WM_INPUT
|
if (!window->win32.cursorTracked)
|
||||||
|
{
|
||||||
|
TRACKMOUSEEVENT tme;
|
||||||
|
ZeroMemory(&tme, sizeof(tme));
|
||||||
|
tme.cbSize = sizeof(tme);
|
||||||
|
tme.dwFlags = TME_LEAVE;
|
||||||
|
tme.hwndTrack = window->win32.handle;
|
||||||
|
TrackMouseEvent(&tme);
|
||||||
|
|
||||||
|
window->win32.cursorTracked = GLFW_TRUE;
|
||||||
|
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
{
|
{
|
||||||
const int dx = x - window->win32.lastCursorPosX;
|
const int dx = x - window->win32.lastCursorPosX;
|
||||||
@ -851,19 +848,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
window->win32.lastCursorPosX = x;
|
window->win32.lastCursorPosX = x;
|
||||||
window->win32.lastCursorPosY = y;
|
window->win32.lastCursorPosY = y;
|
||||||
|
|
||||||
if (!window->win32.cursorTracked)
|
|
||||||
{
|
|
||||||
TRACKMOUSEEVENT tme;
|
|
||||||
ZeroMemory(&tme, sizeof(tme));
|
|
||||||
tme.cbSize = sizeof(tme);
|
|
||||||
tme.dwFlags = TME_LEAVE;
|
|
||||||
tme.hwndTrack = window->win32.handle;
|
|
||||||
TrackMouseEvent(&tme);
|
|
||||||
|
|
||||||
window->win32.cursorTracked = GLFW_TRUE;
|
|
||||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,6 +926,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
case WM_ENTERMENULOOP:
|
case WM_ENTERMENULOOP:
|
||||||
{
|
{
|
||||||
|
if (window->win32.frameAction)
|
||||||
|
break;
|
||||||
|
|
||||||
// HACK: Enable the cursor while the user is moving or
|
// HACK: Enable the cursor while the user is moving or
|
||||||
// resizing the window or using the window menu
|
// resizing the window or using the window menu
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
@ -953,6 +940,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
case WM_EXITMENULOOP:
|
case WM_EXITMENULOOP:
|
||||||
{
|
{
|
||||||
|
if (window->win32.frameAction)
|
||||||
|
break;
|
||||||
|
|
||||||
// HACK: Disable the cursor once the user is done moving or
|
// HACK: Disable the cursor once the user is done moving or
|
||||||
// resizing the window or using the menu
|
// resizing the window or using the menu
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
@ -1225,6 +1215,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
xpos = CW_USEDEFAULT;
|
xpos = CW_USEDEFAULT;
|
||||||
ypos = CW_USEDEFAULT;
|
ypos = CW_USEDEFAULT;
|
||||||
|
|
||||||
|
window->win32.maximized = wndconfig->maximized;
|
||||||
if (wndconfig->maximized)
|
if (wndconfig->maximized)
|
||||||
style |= WS_MAXIMIZE;
|
style |= WS_MAXIMIZE;
|
||||||
|
|
||||||
@ -1271,13 +1262,15 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
||||||
|
window->win32.keymenu = wndconfig->win32.keymenu;
|
||||||
|
|
||||||
// Adjust window size to account for DPI scaling of the window frame and
|
// Adjust window rect to account for DPI scaling of the window frame and
|
||||||
// optionally DPI scaling of the content area
|
// (if enabled) DPI scaling of the content area
|
||||||
// This cannot be done until we know what monitor it was placed on
|
// This cannot be done until we know what monitor the window was placed on
|
||||||
if (!window->monitor)
|
if (!window->monitor)
|
||||||
{
|
{
|
||||||
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
||||||
|
WINDOWPLACEMENT wp = { sizeof(wp) };
|
||||||
|
|
||||||
if (wndconfig->scaleToMonitor)
|
if (wndconfig->scaleToMonitor)
|
||||||
{
|
{
|
||||||
@ -1298,10 +1291,11 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
else
|
else
|
||||||
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
|
|
||||||
SetWindowPos(window->win32.handle, NULL,
|
// Only update the restored window rect as the window may be maximized
|
||||||
rect.left, rect.top,
|
GetWindowPlacement(window->win32.handle, &wp);
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
wp.rcNormalPosition = rect;
|
||||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
wp.showCmd = SW_HIDE;
|
||||||
|
SetWindowPlacement(window->win32.handle, &wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
DragAcceptFiles(window->win32.handle, TRUE);
|
DragAcceptFiles(window->win32.handle, TRUE);
|
||||||
@ -1722,7 +1716,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
|
|
||||||
_glfwInputWindowMonitor(window, monitor);
|
_glfwInputWindowMonitor(window, monitor);
|
||||||
|
|
||||||
if (monitor)
|
if (window->monitor)
|
||||||
{
|
{
|
||||||
MONITORINFO mi = { sizeof(mi) };
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS;
|
UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS;
|
||||||
@ -1918,30 +1912,40 @@ void _glfwPlatformPollEvents(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: Release modifier keys that the system did not emit KEYUP for
|
||||||
|
// NOTE: Shift keys on Windows tend to "stick" when both are pressed as
|
||||||
|
// no key up message is generated by the first key release
|
||||||
|
// NOTE: Windows key is not reported as released by the Win+V hotkey
|
||||||
|
// Other Win hotkeys are handled implicitly by _glfwInputWindowFocus
|
||||||
|
// because they change the input focus
|
||||||
|
// NOTE: The other half of this is in the WM_*KEY* handler in windowProc
|
||||||
handle = GetActiveWindow();
|
handle = GetActiveWindow();
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
// NOTE: Shift keys on Windows tend to "stick" when both are pressed as
|
|
||||||
// no key up message is generated by the first key release
|
|
||||||
// The other half of this is in the handling of WM_KEYUP
|
|
||||||
// HACK: Query actual key state and synthesize release events as needed
|
|
||||||
window = GetPropW(handle, L"GLFW");
|
window = GetPropW(handle, L"GLFW");
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
|
int i;
|
||||||
const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
|
const int keys[4][2] =
|
||||||
|
{
|
||||||
|
{ VK_LSHIFT, GLFW_KEY_LEFT_SHIFT },
|
||||||
|
{ VK_RSHIFT, GLFW_KEY_RIGHT_SHIFT },
|
||||||
|
{ VK_LWIN, GLFW_KEY_LEFT_SUPER },
|
||||||
|
{ VK_RWIN, GLFW_KEY_RIGHT_SUPER }
|
||||||
|
};
|
||||||
|
|
||||||
if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
const int mods = getAsyncKeyMods();
|
const int vk = keys[i][0];
|
||||||
const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT];
|
const int key = keys[i][1];
|
||||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
|
const int scancode = _glfw.win32.scancodes[key];
|
||||||
}
|
|
||||||
else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS)
|
if ((GetKeyState(vk) & 0x8000))
|
||||||
{
|
continue;
|
||||||
const int mods = getAsyncKeyMods();
|
if (window->keys[key] != GLFW_PRESS)
|
||||||
const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT];
|
continue;
|
||||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
|
|
||||||
|
_glfwInputKey(window, key, scancode, GLFW_RELEASE, getKeyMods());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2023,6 +2027,13 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
{
|
{
|
||||||
|
if (scancode < 0 || scancode > (KF_EXTENDED | 0xff) ||
|
||||||
|
_glfw.win32.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2052,14 +2063,25 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||||||
id = OCR_IBEAM;
|
id = OCR_IBEAM;
|
||||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
id = OCR_CROSS;
|
id = OCR_CROSS;
|
||||||
else if (shape == GLFW_HAND_CURSOR)
|
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||||
id = OCR_HAND;
|
id = OCR_HAND;
|
||||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
id = OCR_SIZEWE;
|
id = OCR_SIZEWE;
|
||||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
id = OCR_SIZENS;
|
id = OCR_SIZENS;
|
||||||
|
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||||
|
id = OCR_SIZENWSE;
|
||||||
|
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||||
|
id = OCR_SIZENESW;
|
||||||
|
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||||
|
id = OCR_SIZEALL;
|
||||||
|
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||||
|
id = OCR_NO;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
cursor->win32.handle = LoadImageW(NULL,
|
cursor->win32.handle = LoadImageW(NULL,
|
||||||
MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,
|
MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -361,6 +363,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||||
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
case GLFW_WIN32_KEYBOARD_MENU:
|
||||||
|
_glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
return;
|
||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -36,6 +40,7 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/timerfd.h>
|
#include <sys/timerfd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
|
||||||
|
|
||||||
@ -123,6 +128,7 @@ static void pointerHandleLeave(void* data,
|
|||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerFocus = NULL;
|
_glfw.wl.pointerFocus = NULL;
|
||||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||||
|
_glfw.wl.cursorPreviousName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursor(_GLFWwindow* window, const char* name)
|
static void setCursor(_GLFWwindow* window, const char* name)
|
||||||
@ -167,6 +173,7 @@ static void setCursor(_GLFWwindow* window, const char* name)
|
|||||||
wl_surface_damage(surface, 0, 0,
|
wl_surface_damage(surface, 0, 0,
|
||||||
image->width, image->height);
|
image->width, image->height);
|
||||||
wl_surface_commit(surface);
|
wl_surface_commit(surface);
|
||||||
|
_glfw.wl.cursorPreviousName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHandleMotion(void* data,
|
static void pointerHandleMotion(void* data,
|
||||||
@ -176,48 +183,47 @@ static void pointerHandleMotion(void* data,
|
|||||||
wl_fixed_t sy)
|
wl_fixed_t sy)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||||
const char* cursorName;
|
const char* cursorName = NULL;
|
||||||
|
double x, y;
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
return;
|
return;
|
||||||
else
|
x = wl_fixed_to_double(sx);
|
||||||
{
|
y = wl_fixed_to_double(sy);
|
||||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
|
||||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (window->wl.decorations.focus)
|
switch (window->wl.decorations.focus)
|
||||||
{
|
{
|
||||||
case mainWindow:
|
case mainWindow:
|
||||||
_glfwInputCursorPos(window,
|
window->wl.cursorPosX = x;
|
||||||
wl_fixed_to_double(sx),
|
window->wl.cursorPosY = y;
|
||||||
wl_fixed_to_double(sy));
|
_glfwInputCursorPos(window, x, y);
|
||||||
|
_glfw.wl.cursorPreviousName = NULL;
|
||||||
return;
|
return;
|
||||||
case topDecoration:
|
case topDecoration:
|
||||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
if (y < _GLFW_DECORATION_WIDTH)
|
||||||
cursorName = "n-resize";
|
cursorName = "n-resize";
|
||||||
else
|
else
|
||||||
cursorName = "left_ptr";
|
cursorName = "left_ptr";
|
||||||
break;
|
break;
|
||||||
case leftDecoration:
|
case leftDecoration:
|
||||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
if (y < _GLFW_DECORATION_WIDTH)
|
||||||
cursorName = "nw-resize";
|
cursorName = "nw-resize";
|
||||||
else
|
else
|
||||||
cursorName = "w-resize";
|
cursorName = "w-resize";
|
||||||
break;
|
break;
|
||||||
case rightDecoration:
|
case rightDecoration:
|
||||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
if (y < _GLFW_DECORATION_WIDTH)
|
||||||
cursorName = "ne-resize";
|
cursorName = "ne-resize";
|
||||||
else
|
else
|
||||||
cursorName = "e-resize";
|
cursorName = "e-resize";
|
||||||
break;
|
break;
|
||||||
case bottomDecoration:
|
case bottomDecoration:
|
||||||
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
|
if (x < _GLFW_DECORATION_WIDTH)
|
||||||
cursorName = "sw-resize";
|
cursorName = "sw-resize";
|
||||||
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
|
else if (x > window->wl.width + _GLFW_DECORATION_WIDTH)
|
||||||
cursorName = "se-resize";
|
cursorName = "se-resize";
|
||||||
else
|
else
|
||||||
cursorName = "s-resize";
|
cursorName = "s-resize";
|
||||||
@ -225,7 +231,8 @@ static void pointerHandleMotion(void* data,
|
|||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
setCursor(window, cursorName);
|
if (_glfw.wl.cursorPreviousName != cursorName)
|
||||||
|
setCursor(window, cursorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHandleButton(void* data,
|
static void pointerHandleButton(void* data,
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -198,7 +200,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_PLATFORM_ERROR,
|
||||||
"Wayland: Gamma ramp access it not available");
|
"Wayland: Gamma ramp access is not available");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,8 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
|
||||||
|
|
||||||
struct wl_cursor_image {
|
struct wl_cursor_image {
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
@ -247,6 +247,7 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct wl_cursor_theme* cursorTheme;
|
struct wl_cursor_theme* cursorTheme;
|
||||||
struct wl_cursor_theme* cursorThemeHiDPI;
|
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||||
struct wl_surface* cursorSurface;
|
struct wl_surface* cursorSurface;
|
||||||
|
const char* cursorPreviousName;
|
||||||
int cursorTimerfd;
|
int cursorTimerfd;
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
|
|
||||||
@ -330,7 +331,7 @@ typedef struct _GLFWlibraryWayland
|
|||||||
typedef struct _GLFWmonitorWayland
|
typedef struct _GLFWmonitorWayland
|
||||||
{
|
{
|
||||||
struct wl_output* output;
|
struct wl_output* output;
|
||||||
int name;
|
uint32_t name;
|
||||||
int currentMode;
|
int currentMode;
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
|
109
src/wl_window.c
109
src/wl_window.c
@ -23,6 +23,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ static int createTmpfileCloexec(char* tmpname)
|
|||||||
* SCM_RIGHTS methods.
|
* SCM_RIGHTS methods.
|
||||||
*
|
*
|
||||||
* posix_fallocate() is used to guarantee that disk space is available
|
* posix_fallocate() is used to guarantee that disk space is available
|
||||||
* for the file at the given size. If disk space is insufficent, errno
|
* for the file at the given size. If disk space is insufficient, errno
|
||||||
* is set to ENOSPC. If posix_fallocate() is not supported, program may
|
* is set to ENOSPC. If posix_fallocate() is not supported, program may
|
||||||
* receive SIGBUS on accessing mmap()'ed file contents instead.
|
* receive SIGBUS on accessing mmap()'ed file contents instead.
|
||||||
*/
|
*/
|
||||||
@ -768,28 +770,6 @@ static void handleEvents(int timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translates a GLFW standard cursor to a theme cursor name
|
|
||||||
//
|
|
||||||
static char *translateCursorShape(int shape)
|
|
||||||
{
|
|
||||||
switch (shape)
|
|
||||||
{
|
|
||||||
case GLFW_ARROW_CURSOR:
|
|
||||||
return "left_ptr";
|
|
||||||
case GLFW_IBEAM_CURSOR:
|
|
||||||
return "xterm";
|
|
||||||
case GLFW_CROSSHAIR_CURSOR:
|
|
||||||
return "crosshair";
|
|
||||||
case GLFW_HAND_CURSOR:
|
|
||||||
return "grabbing";
|
|
||||||
case GLFW_HRESIZE_CURSOR:
|
|
||||||
return "sb_h_double_arrow";
|
|
||||||
case GLFW_VRESIZE_CURSOR:
|
|
||||||
return "sb_v_double_arrow";
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -1231,26 +1211,79 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
{
|
{
|
||||||
struct wl_cursor* standardCursor;
|
const char* name = NULL;
|
||||||
|
|
||||||
standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
|
// Try the XDG names first
|
||||||
translateCursorShape(shape));
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
if (!standardCursor)
|
name = "default";
|
||||||
{
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
name = "text";
|
||||||
"Wayland: Standard cursor \"%s\" not found",
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
translateCursorShape(shape));
|
name = "crosshair";
|
||||||
return GLFW_FALSE;
|
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||||
}
|
name = "pointer";
|
||||||
|
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
|
name = "ew-resize";
|
||||||
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
|
name = "ns-resize";
|
||||||
|
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||||
|
name = "nwse-resize";
|
||||||
|
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||||
|
name = "nesw-resize";
|
||||||
|
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||||
|
name = "all-scroll";
|
||||||
|
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||||
|
name = "not-allowed";
|
||||||
|
|
||||||
cursor->wl.cursor = standardCursor;
|
cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);
|
||||||
cursor->wl.currentImage = 0;
|
|
||||||
|
|
||||||
if (_glfw.wl.cursorThemeHiDPI)
|
if (_glfw.wl.cursorThemeHiDPI)
|
||||||
{
|
{
|
||||||
standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI,
|
cursor->wl.cursorHiDPI =
|
||||||
translateCursorShape(shape));
|
wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);
|
||||||
cursor->wl.cursorHiDPI = standardCursor;
|
}
|
||||||
|
|
||||||
|
if (!cursor->wl.cursor)
|
||||||
|
{
|
||||||
|
// Fall back to the core X11 names
|
||||||
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
|
name = "left_ptr";
|
||||||
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
|
name = "xterm";
|
||||||
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
|
name = "crosshair";
|
||||||
|
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||||
|
name = "hand2";
|
||||||
|
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
|
name = "sb_h_double_arrow";
|
||||||
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
|
name = "sb_v_double_arrow";
|
||||||
|
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||||
|
name = "fleur";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
|
||||||
|
"Wayland: Standard cursor shape unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);
|
||||||
|
if (!cursor->wl.cursor)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create standard cursor \"%s\"",
|
||||||
|
name);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.cursorThemeHiDPI)
|
||||||
|
{
|
||||||
|
if (!cursor->wl.cursorHiDPI)
|
||||||
|
{
|
||||||
|
cursor->wl.cursorHiDPI =
|
||||||
|
wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
314
src/x11_init.c
314
src/x11_init.c
@ -24,16 +24,17 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <X11/Xresource.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
// Translate an X11 key code to a GLFW key code.
|
// Translate an X11 key code to a GLFW key code.
|
||||||
@ -52,7 +53,7 @@ static int translateKeyCode(int scancode)
|
|||||||
// Note: This way we always force "NumLock = ON", which is intentional
|
// Note: This way we always force "NumLock = ON", which is intentional
|
||||||
// since the returned key code should correspond to a physical
|
// since the returned key code should correspond to a physical
|
||||||
// location.
|
// location.
|
||||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1);
|
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 1);
|
||||||
switch (keySym)
|
switch (keySym)
|
||||||
{
|
{
|
||||||
case XK_KP_0: return GLFW_KEY_KP_0;
|
case XK_KP_0: return GLFW_KEY_KP_0;
|
||||||
@ -74,7 +75,7 @@ static int translateKeyCode(int scancode)
|
|||||||
|
|
||||||
// Now try primary keysym for function keys (non-printable keys)
|
// Now try primary keysym for function keys (non-printable keys)
|
||||||
// These should not depend on the current keyboard layout
|
// These should not depend on the current keyboard layout
|
||||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
|
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -329,14 +330,13 @@ static void createKeyTables(void)
|
|||||||
//
|
//
|
||||||
static GLFWbool hasUsableInputMethodStyle(void)
|
static GLFWbool hasUsableInputMethodStyle(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
GLFWbool found = GLFW_FALSE;
|
GLFWbool found = GLFW_FALSE;
|
||||||
XIMStyles* styles = NULL;
|
XIMStyles* styles = NULL;
|
||||||
|
|
||||||
if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL)
|
if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
for (i = 0; i < styles->count_styles; i++)
|
for (unsigned int i = 0; i < styles->count_styles; i++)
|
||||||
{
|
{
|
||||||
if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
|
if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
|
||||||
{
|
{
|
||||||
@ -355,10 +355,9 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
|
|||||||
unsigned long atomCount,
|
unsigned long atomCount,
|
||||||
const char* atomName)
|
const char* atomName)
|
||||||
{
|
{
|
||||||
unsigned long i;
|
|
||||||
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
||||||
|
|
||||||
for (i = 0; i < atomCount; i++)
|
for (unsigned int i = 0; i < atomCount; i++)
|
||||||
{
|
{
|
||||||
if (supportedAtoms[i] == atom)
|
if (supportedAtoms[i] == atom)
|
||||||
return atom;
|
return atom;
|
||||||
@ -371,18 +370,11 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
|
|||||||
//
|
//
|
||||||
static void detectEWMH(void)
|
static void detectEWMH(void)
|
||||||
{
|
{
|
||||||
|
// First we read the _NET_SUPPORTING_WM_CHECK property on the root window
|
||||||
|
|
||||||
Window* windowFromRoot = NULL;
|
Window* windowFromRoot = NULL;
|
||||||
Window* windowFromChild = NULL;
|
|
||||||
|
|
||||||
// First we need a couple of atoms
|
|
||||||
const Atom supportingWmCheck =
|
|
||||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
|
|
||||||
const Atom wmSupported =
|
|
||||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
|
||||||
|
|
||||||
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
|
|
||||||
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
|
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||||
supportingWmCheck,
|
_glfw.x11.NET_SUPPORTING_WM_CHECK,
|
||||||
XA_WINDOW,
|
XA_WINDOW,
|
||||||
(unsigned char**) &windowFromRoot))
|
(unsigned char**) &windowFromRoot))
|
||||||
{
|
{
|
||||||
@ -391,10 +383,12 @@ static void detectEWMH(void)
|
|||||||
|
|
||||||
_glfwGrabErrorHandlerX11();
|
_glfwGrabErrorHandlerX11();
|
||||||
|
|
||||||
// It should be the ID of a child window (of the root)
|
// If it exists, it should be the XID of a top-level window
|
||||||
// Then we look for the same property on the child window
|
// Then we look for the same property on that window
|
||||||
|
|
||||||
|
Window* windowFromChild = NULL;
|
||||||
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
|
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
|
||||||
supportingWmCheck,
|
_glfw.x11.NET_SUPPORTING_WM_CHECK,
|
||||||
XA_WINDOW,
|
XA_WINDOW,
|
||||||
(unsigned char**) &windowFromChild))
|
(unsigned char**) &windowFromChild))
|
||||||
{
|
{
|
||||||
@ -404,7 +398,8 @@ static void detectEWMH(void)
|
|||||||
|
|
||||||
_glfwReleaseErrorHandlerX11();
|
_glfwReleaseErrorHandlerX11();
|
||||||
|
|
||||||
// It should be the ID of that same child window
|
// If the property exists, it should contain the XID of the window
|
||||||
|
|
||||||
if (*windowFromRoot != *windowFromChild)
|
if (*windowFromRoot != *windowFromChild)
|
||||||
{
|
{
|
||||||
XFree(windowFromRoot);
|
XFree(windowFromRoot);
|
||||||
@ -415,19 +410,20 @@ static void detectEWMH(void)
|
|||||||
XFree(windowFromRoot);
|
XFree(windowFromRoot);
|
||||||
XFree(windowFromChild);
|
XFree(windowFromChild);
|
||||||
|
|
||||||
// We are now fairly sure that an EWMH-compliant window manager is running
|
// We are now fairly sure that an EWMH-compliant WM is currently running
|
||||||
|
// We can now start querying the WM about what features it supports by
|
||||||
|
// looking in the _NET_SUPPORTED property on the root window
|
||||||
|
// It should contain a list of supported EWMH protocol and state atoms
|
||||||
|
|
||||||
Atom* supportedAtoms;
|
Atom* supportedAtoms = NULL;
|
||||||
unsigned long atomCount;
|
const unsigned long atomCount =
|
||||||
|
_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||||
// Now we need to check the _NET_SUPPORTED property of the root window
|
_glfw.x11.NET_SUPPORTED,
|
||||||
// It should be a list of supported WM protocol and state atoms
|
XA_ATOM,
|
||||||
atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
|
(unsigned char**) &supportedAtoms);
|
||||||
wmSupported,
|
|
||||||
XA_ATOM,
|
|
||||||
(unsigned char**) &supportedAtoms);
|
|
||||||
|
|
||||||
// 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");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||||
@ -618,6 +614,12 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||||
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
||||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||||
|
_glfw.x11.xcursor.GetTheme = (PFN_XcursorGetTheme)
|
||||||
|
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetTheme");
|
||||||
|
_glfw.x11.xcursor.GetDefaultSize = (PFN_XcursorGetDefaultSize)
|
||||||
|
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetDefaultSize");
|
||||||
|
_glfw.x11.xcursor.LibraryLoadImage = (PFN_XcursorLibraryLoadImage)
|
||||||
|
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorLibraryLoadImage");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
@ -662,6 +664,14 @@ static GLFWbool initExtensions(void)
|
|||||||
if (supported)
|
if (supported)
|
||||||
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.x11.xkb.group = 0;
|
||||||
|
XkbStateRec state;
|
||||||
|
if (XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state) == Success)
|
||||||
|
{
|
||||||
|
XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);
|
||||||
|
_glfw.x11.xkb.group = (unsigned int)state.group;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
@ -707,9 +717,6 @@ static GLFWbool initExtensions(void)
|
|||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
|
||||||
// Detect whether an EWMH-conformant window manager is running
|
|
||||||
detectEWMH();
|
|
||||||
|
|
||||||
// String format atoms
|
// String format atoms
|
||||||
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
||||||
_glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
_glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
||||||
@ -753,6 +760,10 @@ static GLFWbool initExtensions(void)
|
|||||||
XInternAtom(_glfw.x11.display, "WM_STATE", False);
|
XInternAtom(_glfw.x11.display, "WM_STATE", False);
|
||||||
_glfw.x11.WM_DELETE_WINDOW =
|
_glfw.x11.WM_DELETE_WINDOW =
|
||||||
XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
|
XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
|
||||||
|
_glfw.x11.NET_SUPPORTED =
|
||||||
|
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
||||||
|
_glfw.x11.NET_SUPPORTING_WM_CHECK =
|
||||||
|
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
|
||||||
_glfw.x11.NET_WM_ICON =
|
_glfw.x11.NET_WM_ICON =
|
||||||
XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
|
XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
|
||||||
_glfw.x11.NET_WM_PING =
|
_glfw.x11.NET_WM_PING =
|
||||||
@ -777,6 +788,9 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
|
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect whether an EWMH-conformant window manager is running
|
||||||
|
detectEWMH();
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,13 +798,10 @@ static GLFWbool initExtensions(void)
|
|||||||
//
|
//
|
||||||
static void getSystemContentScale(float* xscale, float* yscale)
|
static void getSystemContentScale(float* xscale, float* yscale)
|
||||||
{
|
{
|
||||||
// NOTE: Fall back to the display-wide DPI instead of RandR monitor DPI if
|
// Start by assuming the default X11 DPI
|
||||||
// Xft.dpi retrieval below fails as we don't currently have an exact
|
// NOTE: Some desktop environments (KDE) may remove the Xft.dpi field when it
|
||||||
// policy for which monitor a window is considered to "be on"
|
// would be set to 96, so assume that is the case if we cannot find it
|
||||||
float xdpi = DisplayWidth(_glfw.x11.display, _glfw.x11.screen) *
|
float xdpi = 96.f, ydpi = 96.f;
|
||||||
25.4f / DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
|
|
||||||
float ydpi = DisplayHeight(_glfw.x11.display, _glfw.x11.screen) *
|
|
||||||
25.4f / DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
|
|
||||||
|
|
||||||
// NOTE: Basing the scale on Xft.dpi where available should provide the most
|
// NOTE: Basing the scale on Xft.dpi where available should provide the most
|
||||||
// consistent user experience (matches Qt, Gtk, etc), although not
|
// consistent user experience (matches Qt, Gtk, etc), although not
|
||||||
@ -925,15 +936,216 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
|
|||||||
|
|
||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
#if !defined(X_HAVE_UTF8_STRING)
|
// HACK: If the application has left the locale as "C" then both wide
|
||||||
// HACK: If the current locale is "C" and the Xlib UTF-8 functions are
|
// character text input and explicit UTF-8 input via XIM will break
|
||||||
// unavailable, apply the environment's locale in the hope that it's
|
// This sets the CTYPE part of the current locale from the environment
|
||||||
// both available and not "C"
|
// in the hope that it is set to something more sane than "C"
|
||||||
// This is done because the "C" locale breaks wide character input,
|
|
||||||
// which is what we fall back on when UTF-8 support is missing
|
|
||||||
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
|
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
_glfw.x11.xlib.handle = _glfw_dlopen("libX11-6.so");
|
||||||
|
#else
|
||||||
|
_glfw.x11.xlib.handle = _glfw_dlopen("libX11.so.6");
|
||||||
#endif
|
#endif
|
||||||
|
if (!_glfw.x11.xlib.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load Xlib");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.x11.xlib.AllocClassHint = (PFN_XAllocClassHint)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XAllocClassHint");
|
||||||
|
_glfw.x11.xlib.AllocSizeHints = (PFN_XAllocSizeHints)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XAllocSizeHints");
|
||||||
|
_glfw.x11.xlib.AllocWMHints = (PFN_XAllocWMHints)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XAllocWMHints");
|
||||||
|
_glfw.x11.xlib.ChangeProperty = (PFN_XChangeProperty)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XChangeProperty");
|
||||||
|
_glfw.x11.xlib.ChangeWindowAttributes = (PFN_XChangeWindowAttributes)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XChangeWindowAttributes");
|
||||||
|
_glfw.x11.xlib.CheckIfEvent = (PFN_XCheckIfEvent)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCheckIfEvent");
|
||||||
|
_glfw.x11.xlib.CheckTypedWindowEvent = (PFN_XCheckTypedWindowEvent)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCheckTypedWindowEvent");
|
||||||
|
_glfw.x11.xlib.CloseDisplay = (PFN_XCloseDisplay)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCloseDisplay");
|
||||||
|
_glfw.x11.xlib.CloseIM = (PFN_XCloseIM)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCloseIM");
|
||||||
|
_glfw.x11.xlib.ConvertSelection = (PFN_XConvertSelection)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XConvertSelection");
|
||||||
|
_glfw.x11.xlib.CreateColormap = (PFN_XCreateColormap)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateColormap");
|
||||||
|
_glfw.x11.xlib.CreateFontCursor = (PFN_XCreateFontCursor)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateFontCursor");
|
||||||
|
_glfw.x11.xlib.CreateIC = (PFN_XCreateIC)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateIC");
|
||||||
|
_glfw.x11.xlib.CreateWindow = (PFN_XCreateWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XCreateWindow");
|
||||||
|
_glfw.x11.xlib.DefineCursor = (PFN_XDefineCursor)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDefineCursor");
|
||||||
|
_glfw.x11.xlib.DeleteContext = (PFN_XDeleteContext)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDeleteContext");
|
||||||
|
_glfw.x11.xlib.DeleteProperty = (PFN_XDeleteProperty)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDeleteProperty");
|
||||||
|
_glfw.x11.xlib.DestroyIC = (PFN_XDestroyIC)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyIC");
|
||||||
|
_glfw.x11.xlib.DestroyWindow = (PFN_XDestroyWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XDestroyWindow");
|
||||||
|
_glfw.x11.xlib.EventsQueued = (PFN_XEventsQueued)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XEventsQueued");
|
||||||
|
_glfw.x11.xlib.FilterEvent = (PFN_XFilterEvent)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFilterEvent");
|
||||||
|
_glfw.x11.xlib.FindContext = (PFN_XFindContext)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFindContext");
|
||||||
|
_glfw.x11.xlib.Flush = (PFN_XFlush)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFlush");
|
||||||
|
_glfw.x11.xlib.Free = (PFN_XFree)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFree");
|
||||||
|
_glfw.x11.xlib.FreeColormap = (PFN_XFreeColormap)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFreeColormap");
|
||||||
|
_glfw.x11.xlib.FreeCursor = (PFN_XFreeCursor)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFreeCursor");
|
||||||
|
_glfw.x11.xlib.FreeEventData = (PFN_XFreeEventData)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XFreeEventData");
|
||||||
|
_glfw.x11.xlib.GetErrorText = (PFN_XGetErrorText)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetErrorText");
|
||||||
|
_glfw.x11.xlib.GetEventData = (PFN_XGetEventData)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetEventData");
|
||||||
|
_glfw.x11.xlib.GetICValues = (PFN_XGetICValues)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetICValues");
|
||||||
|
_glfw.x11.xlib.GetIMValues = (PFN_XGetIMValues)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetIMValues");
|
||||||
|
_glfw.x11.xlib.GetInputFocus = (PFN_XGetInputFocus)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetInputFocus");
|
||||||
|
_glfw.x11.xlib.GetKeyboardMapping = (PFN_XGetKeyboardMapping)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetKeyboardMapping");
|
||||||
|
_glfw.x11.xlib.GetScreenSaver = (PFN_XGetScreenSaver)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetScreenSaver");
|
||||||
|
_glfw.x11.xlib.GetSelectionOwner = (PFN_XGetSelectionOwner)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetSelectionOwner");
|
||||||
|
_glfw.x11.xlib.GetVisualInfo = (PFN_XGetVisualInfo)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetVisualInfo");
|
||||||
|
_glfw.x11.xlib.GetWMNormalHints = (PFN_XGetWMNormalHints)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetWMNormalHints");
|
||||||
|
_glfw.x11.xlib.GetWindowAttributes = (PFN_XGetWindowAttributes)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetWindowAttributes");
|
||||||
|
_glfw.x11.xlib.GetWindowProperty = (PFN_XGetWindowProperty)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGetWindowProperty");
|
||||||
|
_glfw.x11.xlib.GrabPointer = (PFN_XGrabPointer)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XGrabPointer");
|
||||||
|
_glfw.x11.xlib.IconifyWindow = (PFN_XIconifyWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XIconifyWindow");
|
||||||
|
_glfw.x11.xlib.InitThreads = (PFN_XInitThreads)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XInitThreads");
|
||||||
|
_glfw.x11.xlib.InternAtom = (PFN_XInternAtom)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XInternAtom");
|
||||||
|
_glfw.x11.xlib.LookupString = (PFN_XLookupString)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XLookupString");
|
||||||
|
_glfw.x11.xlib.MapRaised = (PFN_XMapRaised)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XMapRaised");
|
||||||
|
_glfw.x11.xlib.MapWindow = (PFN_XMapWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XMapWindow");
|
||||||
|
_glfw.x11.xlib.MoveResizeWindow = (PFN_XMoveResizeWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XMoveResizeWindow");
|
||||||
|
_glfw.x11.xlib.MoveWindow = (PFN_XMoveWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XMoveWindow");
|
||||||
|
_glfw.x11.xlib.NextEvent = (PFN_XNextEvent)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XNextEvent");
|
||||||
|
_glfw.x11.xlib.OpenDisplay = (PFN_XOpenDisplay)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XOpenDisplay");
|
||||||
|
_glfw.x11.xlib.OpenIM = (PFN_XOpenIM)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XOpenIM");
|
||||||
|
_glfw.x11.xlib.PeekEvent = (PFN_XPeekEvent)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XPeekEvent");
|
||||||
|
_glfw.x11.xlib.Pending = (PFN_XPending)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XPending");
|
||||||
|
_glfw.x11.xlib.QueryExtension = (PFN_XQueryExtension)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XQueryExtension");
|
||||||
|
_glfw.x11.xlib.QueryPointer = (PFN_XQueryPointer)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XQueryPointer");
|
||||||
|
_glfw.x11.xlib.RaiseWindow = (PFN_XRaiseWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XRaiseWindow");
|
||||||
|
_glfw.x11.xlib.ResizeWindow = (PFN_XResizeWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XResizeWindow");
|
||||||
|
_glfw.x11.xlib.ResourceManagerString = (PFN_XResourceManagerString)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XResourceManagerString");
|
||||||
|
_glfw.x11.xlib.SaveContext = (PFN_XSaveContext)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSaveContext");
|
||||||
|
_glfw.x11.xlib.SelectInput = (PFN_XSelectInput)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSelectInput");
|
||||||
|
_glfw.x11.xlib.SendEvent = (PFN_XSendEvent)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSendEvent");
|
||||||
|
_glfw.x11.xlib.SetClassHint = (PFN_XSetClassHint)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetClassHint");
|
||||||
|
_glfw.x11.xlib.SetErrorHandler = (PFN_XSetErrorHandler)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetErrorHandler");
|
||||||
|
_glfw.x11.xlib.SetICFocus = (PFN_XSetICFocus)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetICFocus");
|
||||||
|
_glfw.x11.xlib.SetInputFocus = (PFN_XSetInputFocus)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetInputFocus");
|
||||||
|
_glfw.x11.xlib.SetLocaleModifiers = (PFN_XSetLocaleModifiers)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetLocaleModifiers");
|
||||||
|
_glfw.x11.xlib.SetScreenSaver = (PFN_XSetScreenSaver)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetScreenSaver");
|
||||||
|
_glfw.x11.xlib.SetSelectionOwner = (PFN_XSetSelectionOwner)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetSelectionOwner");
|
||||||
|
_glfw.x11.xlib.SetWMHints = (PFN_XSetWMHints)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetWMHints");
|
||||||
|
_glfw.x11.xlib.SetWMNormalHints = (PFN_XSetWMNormalHints)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetWMNormalHints");
|
||||||
|
_glfw.x11.xlib.SetWMProtocols = (PFN_XSetWMProtocols)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSetWMProtocols");
|
||||||
|
_glfw.x11.xlib.SupportsLocale = (PFN_XSupportsLocale)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSupportsLocale");
|
||||||
|
_glfw.x11.xlib.Sync = (PFN_XSync)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XSync");
|
||||||
|
_glfw.x11.xlib.TranslateCoordinates = (PFN_XTranslateCoordinates)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XTranslateCoordinates");
|
||||||
|
_glfw.x11.xlib.UndefineCursor = (PFN_XUndefineCursor)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XUndefineCursor");
|
||||||
|
_glfw.x11.xlib.UngrabPointer = (PFN_XUngrabPointer)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XUngrabPointer");
|
||||||
|
_glfw.x11.xlib.UnmapWindow = (PFN_XUnmapWindow)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XUnmapWindow");
|
||||||
|
_glfw.x11.xlib.UnsetICFocus = (PFN_XUnsetICFocus)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XUnsetICFocus");
|
||||||
|
_glfw.x11.xlib.VisualIDFromVisual = (PFN_XVisualIDFromVisual)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XVisualIDFromVisual");
|
||||||
|
_glfw.x11.xlib.WarpPointer = (PFN_XWarpPointer)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XWarpPointer");
|
||||||
|
_glfw.x11.xkb.FreeKeyboard = (PFN_XkbFreeKeyboard)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbFreeKeyboard");
|
||||||
|
_glfw.x11.xkb.FreeNames = (PFN_XkbFreeNames)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbFreeNames");
|
||||||
|
_glfw.x11.xkb.GetMap = (PFN_XkbGetMap)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbGetMap");
|
||||||
|
_glfw.x11.xkb.GetNames = (PFN_XkbGetNames)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbGetNames");
|
||||||
|
_glfw.x11.xkb.GetState = (PFN_XkbGetState)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbGetState");
|
||||||
|
_glfw.x11.xkb.KeycodeToKeysym = (PFN_XkbKeycodeToKeysym)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbKeycodeToKeysym");
|
||||||
|
_glfw.x11.xkb.QueryExtension = (PFN_XkbQueryExtension)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbQueryExtension");
|
||||||
|
_glfw.x11.xkb.SelectEventDetails = (PFN_XkbSelectEventDetails)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbSelectEventDetails");
|
||||||
|
_glfw.x11.xkb.SetDetectableAutoRepeat = (PFN_XkbSetDetectableAutoRepeat)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XkbSetDetectableAutoRepeat");
|
||||||
|
_glfw.x11.xrm.DestroyDatabase = (PFN_XrmDestroyDatabase)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmDestroyDatabase");
|
||||||
|
_glfw.x11.xrm.GetResource = (PFN_XrmGetResource)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmGetResource");
|
||||||
|
_glfw.x11.xrm.GetStringDatabase = (PFN_XrmGetStringDatabase)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmGetStringDatabase");
|
||||||
|
_glfw.x11.xrm.Initialize = (PFN_XrmInitialize)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmInitialize");
|
||||||
|
_glfw.x11.xrm.UniqueQuark = (PFN_XrmUniqueQuark)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "XrmUniqueQuark");
|
||||||
|
_glfw.x11.xlib.utf8LookupString = (PFN_Xutf8LookupString)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "Xutf8LookupString");
|
||||||
|
_glfw.x11.xlib.utf8SetWMProperties = (PFN_Xutf8SetWMProperties)
|
||||||
|
_glfw_dlsym(_glfw.x11.xlib.handle, "Xutf8SetWMProperties");
|
||||||
|
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
XrmInitialize();
|
XrmInitialize();
|
||||||
@ -1079,6 +1291,12 @@ void _glfwPlatformTerminate(void)
|
|||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
_glfwTerminateJoysticksLinux();
|
_glfwTerminateJoysticksLinux();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_glfw.x11.xlib.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.x11.xlib.handle);
|
||||||
|
_glfw.x11.xlib.handle = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -54,9 +56,7 @@ static int calculateRefreshRate(const XRRModeInfo* mi)
|
|||||||
//
|
//
|
||||||
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
|
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < sr->nmode; i++)
|
||||||
|
|
||||||
for (i = 0; i < sr->nmode; i++)
|
|
||||||
{
|
{
|
||||||
if (sr->modes[i].id == id)
|
if (sr->modes[i].id == id)
|
||||||
return sr->modes + i;
|
return sr->modes + i;
|
||||||
@ -102,7 +102,7 @@ void _glfwPollMonitorsX11(void)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
int i, j, disconnectedCount, screenCount = 0;
|
int disconnectedCount, screenCount = 0;
|
||||||
_GLFWmonitor** disconnected = NULL;
|
_GLFWmonitor** disconnected = NULL;
|
||||||
XineramaScreenInfo* screens = NULL;
|
XineramaScreenInfo* screens = NULL;
|
||||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||||
@ -122,14 +122,11 @@ void _glfwPollMonitorsX11(void)
|
|||||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < sr->noutput; i++)
|
for (int i = 0; i < sr->noutput; i++)
|
||||||
{
|
{
|
||||||
int type, widthMM, heightMM;
|
int j, type, widthMM, heightMM;
|
||||||
XRROutputInfo* oi;
|
|
||||||
XRRCrtcInfo* ci;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
|
|
||||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||||
if (oi->connection != RR_Connected || oi->crtc == None)
|
if (oi->connection != RR_Connected || oi->crtc == None)
|
||||||
{
|
{
|
||||||
XRRFreeOutputInfo(oi);
|
XRRFreeOutputInfo(oi);
|
||||||
@ -152,7 +149,7 @@ void _glfwPollMonitorsX11(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
{
|
{
|
||||||
widthMM = oi->mm_height;
|
widthMM = oi->mm_height;
|
||||||
@ -164,7 +161,17 @@ void _glfwPollMonitorsX11(void)
|
|||||||
heightMM = oi->mm_height;
|
heightMM = oi->mm_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
if (widthMM <= 0 || heightMM <= 0)
|
||||||
|
{
|
||||||
|
// HACK: If RandR does not provide a physical size, assume the
|
||||||
|
// X11 default 96 DPI and calcuate from the CRTC viewport
|
||||||
|
// NOTE: These members are affected by rotation, unlike the mode
|
||||||
|
// info and output info members
|
||||||
|
widthMM = (int) (ci->width * 25.4f / 96.f);
|
||||||
|
heightMM = (int) (ci->height * 25.4f / 96.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||||
monitor->x11.output = sr->outputs[i];
|
monitor->x11.output = sr->outputs[i];
|
||||||
monitor->x11.crtc = oi->crtc;
|
monitor->x11.crtc = oi->crtc;
|
||||||
|
|
||||||
@ -196,7 +203,7 @@ void _glfwPollMonitorsX11(void)
|
|||||||
if (screens)
|
if (screens)
|
||||||
XFree(screens);
|
XFree(screens);
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
for (int i = 0; i < disconnectedCount; i++)
|
||||||
{
|
{
|
||||||
if (disconnected[i])
|
if (disconnected[i])
|
||||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
@ -221,24 +228,20 @@ void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
XRRScreenResources* sr;
|
|
||||||
XRRCrtcInfo* ci;
|
|
||||||
XRROutputInfo* oi;
|
|
||||||
GLFWvidmode current;
|
GLFWvidmode current;
|
||||||
const GLFWvidmode* best;
|
|
||||||
RRMode native = None;
|
RRMode native = None;
|
||||||
int i;
|
|
||||||
|
|
||||||
best = _glfwChooseVideoMode(monitor, desired);
|
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
XRRScreenResources* sr =
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||||
|
|
||||||
for (i = 0; i < oi->nmode; i++)
|
for (int i = 0; i < oi->nmode; i++)
|
||||||
{
|
{
|
||||||
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||||
if (!modeIsGood(mi))
|
if (!modeIsGood(mi))
|
||||||
@ -279,14 +282,12 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
XRRScreenResources* sr;
|
|
||||||
XRRCrtcInfo* ci;
|
|
||||||
|
|
||||||
if (monitor->x11.oldMode == None)
|
if (monitor->x11.oldMode == None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
XRRScreenResources* sr =
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
XRRSetCrtcConfig(_glfw.x11.display,
|
XRRSetCrtcConfig(_glfw.x11.display,
|
||||||
sr, monitor->x11.crtc,
|
sr, monitor->x11.crtc,
|
||||||
@ -317,18 +318,20 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
XRRScreenResources* sr;
|
XRRScreenResources* sr =
|
||||||
XRRCrtcInfo* ci;
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
if (ci)
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
{
|
||||||
|
if (xpos)
|
||||||
|
*xpos = ci->x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = ci->y;
|
||||||
|
|
||||||
if (xpos)
|
XRRFreeCrtcInfo(ci);
|
||||||
*xpos = ci->x;
|
}
|
||||||
if (ypos)
|
|
||||||
*ypos = ci->y;
|
|
||||||
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,11 +351,9 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos
|
|||||||
|
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
XRRScreenResources* sr;
|
XRRScreenResources* sr =
|
||||||
XRRCrtcInfo* ci;
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
|
||||||
|
|
||||||
areaX = ci->x;
|
areaX = ci->x;
|
||||||
areaY = ci->y;
|
areaY = ci->y;
|
||||||
@ -444,24 +445,21 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
|||||||
|
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
int i, j;
|
XRRScreenResources* sr =
|
||||||
XRRScreenResources* sr;
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
XRRCrtcInfo* ci;
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
XRROutputInfo* oi;
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||||
|
|
||||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
|
||||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
|
||||||
|
|
||||||
result = calloc(oi->nmode, sizeof(GLFWvidmode));
|
result = calloc(oi->nmode, sizeof(GLFWvidmode));
|
||||||
|
|
||||||
for (i = 0; i < oi->nmode; i++)
|
for (int i = 0; i < oi->nmode; i++)
|
||||||
{
|
{
|
||||||
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||||
if (!modeIsGood(mi))
|
if (!modeIsGood(mi))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
|
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
|
||||||
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < *count; j++)
|
for (j = 0; j < *count; j++)
|
||||||
{
|
{
|
||||||
@ -495,15 +493,19 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
{
|
{
|
||||||
XRRScreenResources* sr;
|
XRRScreenResources* sr =
|
||||||
XRRCrtcInfo* ci;
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
if (ci)
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
{
|
||||||
|
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||||
|
if (mi) // mi can be NULL if the monitor has been disconnected
|
||||||
|
*mode = vidmodeFromModeInfo(mi, ci);
|
||||||
|
|
||||||
*mode = vidmodeFromModeInfo(getModeInfo(sr, ci->mode), ci);
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xresource.h>
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
|
||||||
// The XRandR extension provides mode setting and gamma control
|
// The XRandR extension provides mode setting and gamma control
|
||||||
@ -47,6 +48,199 @@
|
|||||||
// 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>
|
||||||
|
|
||||||
|
typedef XClassHint* (* PFN_XAllocClassHint)(void);
|
||||||
|
typedef XSizeHints* (* PFN_XAllocSizeHints)(void);
|
||||||
|
typedef XWMHints* (* PFN_XAllocWMHints)(void);
|
||||||
|
typedef int (* PFN_XChangeProperty)(Display*,Window,Atom,Atom,int,int,const unsigned char*,int);
|
||||||
|
typedef int (* PFN_XChangeWindowAttributes)(Display*,Window,unsigned long,XSetWindowAttributes*);
|
||||||
|
typedef Bool (* PFN_XCheckIfEvent)(Display*,XEvent*,Bool(*)(Display*,XEvent*,XPointer),XPointer);
|
||||||
|
typedef Bool (* PFN_XCheckTypedWindowEvent)(Display*,Window,int,XEvent*);
|
||||||
|
typedef int (* PFN_XCloseDisplay)(Display*);
|
||||||
|
typedef Status (* PFN_XCloseIM)(XIM);
|
||||||
|
typedef int (* PFN_XConvertSelection)(Display*,Atom,Atom,Atom,Window,Time);
|
||||||
|
typedef Colormap (* PFN_XCreateColormap)(Display*,Window,Visual*,int);
|
||||||
|
typedef Cursor (* PFN_XCreateFontCursor)(Display*,unsigned int);
|
||||||
|
typedef XIC (* PFN_XCreateIC)(XIM,...);
|
||||||
|
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_XDeleteContext)(Display*,XID,XContext);
|
||||||
|
typedef int (* PFN_XDeleteProperty)(Display*,Window,Atom);
|
||||||
|
typedef void (* PFN_XDestroyIC)(XIC);
|
||||||
|
typedef int (* PFN_XDestroyWindow)(Display*,Window);
|
||||||
|
typedef int (* PFN_XEventsQueued)(Display*,int);
|
||||||
|
typedef Bool (* PFN_XFilterEvent)(XEvent*,Window);
|
||||||
|
typedef int (* PFN_XFindContext)(Display*,XID,XContext,XPointer*);
|
||||||
|
typedef int (* PFN_XFlush)(Display*);
|
||||||
|
typedef int (* PFN_XFree)(void*);
|
||||||
|
typedef int (* PFN_XFreeColormap)(Display*,Colormap);
|
||||||
|
typedef int (* PFN_XFreeCursor)(Display*,Cursor);
|
||||||
|
typedef void (* PFN_XFreeEventData)(Display*,XGenericEventCookie*);
|
||||||
|
typedef int (* PFN_XGetErrorText)(Display*,int,char*,int);
|
||||||
|
typedef Bool (* PFN_XGetEventData)(Display*,XGenericEventCookie*);
|
||||||
|
typedef char* (* PFN_XGetICValues)(XIC,...);
|
||||||
|
typedef char* (* PFN_XGetIMValues)(XIM,...);
|
||||||
|
typedef int (* PFN_XGetInputFocus)(Display*,Window*,int*);
|
||||||
|
typedef KeySym* (* PFN_XGetKeyboardMapping)(Display*,KeyCode,int,int*);
|
||||||
|
typedef int (* PFN_XGetScreenSaver)(Display*,int*,int*,int*,int*);
|
||||||
|
typedef Window (* PFN_XGetSelectionOwner)(Display*,Atom);
|
||||||
|
typedef XVisualInfo* (* PFN_XGetVisualInfo)(Display*,long,XVisualInfo*,int*);
|
||||||
|
typedef Status (* PFN_XGetWMNormalHints)(Display*,Window,XSizeHints*,long*);
|
||||||
|
typedef Status (* PFN_XGetWindowAttributes)(Display*,Window,XWindowAttributes*);
|
||||||
|
typedef int (* PFN_XGetWindowProperty)(Display*,Window,Atom,long,long,Bool,Atom,Atom*,int*,unsigned long*,unsigned long*,unsigned char**);
|
||||||
|
typedef int (* PFN_XGrabPointer)(Display*,Window,Bool,unsigned int,int,int,Window,Cursor,Time);
|
||||||
|
typedef Status (* PFN_XIconifyWindow)(Display*,Window,int);
|
||||||
|
typedef Status (* PFN_XInitThreads)(void);
|
||||||
|
typedef Atom (* PFN_XInternAtom)(Display*,const char*,Bool);
|
||||||
|
typedef int (* PFN_XLookupString)(XKeyEvent*,char*,int,KeySym*,XComposeStatus*);
|
||||||
|
typedef int (* PFN_XMapRaised)(Display*,Window);
|
||||||
|
typedef int (* PFN_XMapWindow)(Display*,Window);
|
||||||
|
typedef int (* PFN_XMoveResizeWindow)(Display*,Window,int,int,unsigned int,unsigned int);
|
||||||
|
typedef int (* PFN_XMoveWindow)(Display*,Window,int,int);
|
||||||
|
typedef int (* PFN_XNextEvent)(Display*,XEvent*);
|
||||||
|
typedef Display* (* PFN_XOpenDisplay)(const char*);
|
||||||
|
typedef XIM (* PFN_XOpenIM)(Display*,XrmDatabase*,char*,char*);
|
||||||
|
typedef int (* PFN_XPeekEvent)(Display*,XEvent*);
|
||||||
|
typedef int (* PFN_XPending)(Display*);
|
||||||
|
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 int (* PFN_XRaiseWindow)(Display*,Window);
|
||||||
|
typedef int (* PFN_XResizeWindow)(Display*,Window,unsigned int,unsigned int);
|
||||||
|
typedef char* (* PFN_XResourceManagerString)(Display*);
|
||||||
|
typedef int (* PFN_XSaveContext)(Display*,XID,XContext,const char*);
|
||||||
|
typedef int (* PFN_XSelectInput)(Display*,Window,long);
|
||||||
|
typedef Status (* PFN_XSendEvent)(Display*,Window,Bool,long,XEvent*);
|
||||||
|
typedef int (* PFN_XSetClassHint)(Display*,Window,XClassHint*);
|
||||||
|
typedef XErrorHandler (* PFN_XSetErrorHandler)(XErrorHandler);
|
||||||
|
typedef void (* PFN_XSetICFocus)(XIC);
|
||||||
|
typedef int (* PFN_XSetInputFocus)(Display*,Window,int,Time);
|
||||||
|
typedef char* (* PFN_XSetLocaleModifiers)(const char*);
|
||||||
|
typedef int (* PFN_XSetScreenSaver)(Display*,int,int,int,int);
|
||||||
|
typedef int (* PFN_XSetSelectionOwner)(Display*,Atom,Window,Time);
|
||||||
|
typedef int (* PFN_XSetWMHints)(Display*,Window,XWMHints*);
|
||||||
|
typedef void (* PFN_XSetWMNormalHints)(Display*,Window,XSizeHints*);
|
||||||
|
typedef Status (* PFN_XSetWMProtocols)(Display*,Window,Atom*,int);
|
||||||
|
typedef Bool (* PFN_XSupportsLocale)(void);
|
||||||
|
typedef int (* PFN_XSync)(Display*,Bool);
|
||||||
|
typedef Bool (* PFN_XTranslateCoordinates)(Display*,Window,Window,int,int,int*,int*,Window*);
|
||||||
|
typedef int (* PFN_XUndefineCursor)(Display*,Window);
|
||||||
|
typedef int (* PFN_XUngrabPointer)(Display*,Time);
|
||||||
|
typedef int (* PFN_XUnmapWindow)(Display*,Window);
|
||||||
|
typedef void (* PFN_XUnsetICFocus)(XIC);
|
||||||
|
typedef VisualID (* PFN_XVisualIDFromVisual)(Visual*);
|
||||||
|
typedef int (* PFN_XWarpPointer)(Display*,Window,Window,int,int,unsigned int,unsigned int,int,int);
|
||||||
|
typedef void (* PFN_XkbFreeKeyboard)(XkbDescPtr,unsigned int,Bool);
|
||||||
|
typedef void (* PFN_XkbFreeNames)(XkbDescPtr,unsigned int,Bool);
|
||||||
|
typedef XkbDescPtr (* PFN_XkbGetMap)(Display*,unsigned int,unsigned int);
|
||||||
|
typedef Status (* PFN_XkbGetNames)(Display*,unsigned int,XkbDescPtr);
|
||||||
|
typedef Status (* PFN_XkbGetState)(Display*,unsigned int,XkbStatePtr);
|
||||||
|
typedef KeySym (* PFN_XkbKeycodeToKeysym)(Display*,KeyCode,int,int);
|
||||||
|
typedef Bool (* PFN_XkbQueryExtension)(Display*,int*,int*,int*,int*,int*);
|
||||||
|
typedef Bool (* PFN_XkbSelectEventDetails)(Display*,unsigned int,unsigned int,unsigned long,unsigned long);
|
||||||
|
typedef Bool (* PFN_XkbSetDetectableAutoRepeat)(Display*,Bool,Bool*);
|
||||||
|
typedef void (* PFN_XrmDestroyDatabase)(XrmDatabase);
|
||||||
|
typedef Bool (* PFN_XrmGetResource)(XrmDatabase,const char*,const char*,char**,XrmValue*);
|
||||||
|
typedef XrmDatabase (* PFN_XrmGetStringDatabase)(const char*);
|
||||||
|
typedef void (* PFN_XrmInitialize)(void);
|
||||||
|
typedef XrmQuark (* PFN_XrmUniqueQuark)(void);
|
||||||
|
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*);
|
||||||
|
#define XAllocClassHint _glfw.x11.xlib.AllocClassHint
|
||||||
|
#define XAllocSizeHints _glfw.x11.xlib.AllocSizeHints
|
||||||
|
#define XAllocWMHints _glfw.x11.xlib.AllocWMHints
|
||||||
|
#define XChangeProperty _glfw.x11.xlib.ChangeProperty
|
||||||
|
#define XChangeWindowAttributes _glfw.x11.xlib.ChangeWindowAttributes
|
||||||
|
#define XCheckIfEvent _glfw.x11.xlib.CheckIfEvent
|
||||||
|
#define XCheckTypedWindowEvent _glfw.x11.xlib.CheckTypedWindowEvent
|
||||||
|
#define XCloseDisplay _glfw.x11.xlib.CloseDisplay
|
||||||
|
#define XCloseIM _glfw.x11.xlib.CloseIM
|
||||||
|
#define XConvertSelection _glfw.x11.xlib.ConvertSelection
|
||||||
|
#define XCreateColormap _glfw.x11.xlib.CreateColormap
|
||||||
|
#define XCreateFontCursor _glfw.x11.xlib.CreateFontCursor
|
||||||
|
#define XCreateIC _glfw.x11.xlib.CreateIC
|
||||||
|
#define XCreateWindow _glfw.x11.xlib.CreateWindow
|
||||||
|
#define XDefineCursor _glfw.x11.xlib.DefineCursor
|
||||||
|
#define XDeleteContext _glfw.x11.xlib.DeleteContext
|
||||||
|
#define XDeleteProperty _glfw.x11.xlib.DeleteProperty
|
||||||
|
#define XDestroyIC _glfw.x11.xlib.DestroyIC
|
||||||
|
#define XDestroyWindow _glfw.x11.xlib.DestroyWindow
|
||||||
|
#define XEventsQueued _glfw.x11.xlib.EventsQueued
|
||||||
|
#define XFilterEvent _glfw.x11.xlib.FilterEvent
|
||||||
|
#define XFindContext _glfw.x11.xlib.FindContext
|
||||||
|
#define XFlush _glfw.x11.xlib.Flush
|
||||||
|
#define XFree _glfw.x11.xlib.Free
|
||||||
|
#define XFreeColormap _glfw.x11.xlib.FreeColormap
|
||||||
|
#define XFreeCursor _glfw.x11.xlib.FreeCursor
|
||||||
|
#define XFreeEventData _glfw.x11.xlib.FreeEventData
|
||||||
|
#define XGetErrorText _glfw.x11.xlib.GetErrorText
|
||||||
|
#define XGetEventData _glfw.x11.xlib.GetEventData
|
||||||
|
#define XGetICValues _glfw.x11.xlib.GetICValues
|
||||||
|
#define XGetIMValues _glfw.x11.xlib.GetIMValues
|
||||||
|
#define XGetInputFocus _glfw.x11.xlib.GetInputFocus
|
||||||
|
#define XGetKeyboardMapping _glfw.x11.xlib.GetKeyboardMapping
|
||||||
|
#define XGetScreenSaver _glfw.x11.xlib.GetScreenSaver
|
||||||
|
#define XGetSelectionOwner _glfw.x11.xlib.GetSelectionOwner
|
||||||
|
#define XGetVisualInfo _glfw.x11.xlib.GetVisualInfo
|
||||||
|
#define XGetWMNormalHints _glfw.x11.xlib.GetWMNormalHints
|
||||||
|
#define XGetWindowAttributes _glfw.x11.xlib.GetWindowAttributes
|
||||||
|
#define XGetWindowProperty _glfw.x11.xlib.GetWindowProperty
|
||||||
|
#define XGrabPointer _glfw.x11.xlib.GrabPointer
|
||||||
|
#define XIconifyWindow _glfw.x11.xlib.IconifyWindow
|
||||||
|
#define XInitThreads _glfw.x11.xlib.InitThreads
|
||||||
|
#define XInternAtom _glfw.x11.xlib.InternAtom
|
||||||
|
#define XLookupString _glfw.x11.xlib.LookupString
|
||||||
|
#define XMapRaised _glfw.x11.xlib.MapRaised
|
||||||
|
#define XMapWindow _glfw.x11.xlib.MapWindow
|
||||||
|
#define XMoveResizeWindow _glfw.x11.xlib.MoveResizeWindow
|
||||||
|
#define XMoveWindow _glfw.x11.xlib.MoveWindow
|
||||||
|
#define XNextEvent _glfw.x11.xlib.NextEvent
|
||||||
|
#define XOpenDisplay _glfw.x11.xlib.OpenDisplay
|
||||||
|
#define XOpenIM _glfw.x11.xlib.OpenIM
|
||||||
|
#define XPeekEvent _glfw.x11.xlib.PeekEvent
|
||||||
|
#define XPending _glfw.x11.xlib.Pending
|
||||||
|
#define XQueryExtension _glfw.x11.xlib.QueryExtension
|
||||||
|
#define XQueryPointer _glfw.x11.xlib.QueryPointer
|
||||||
|
#define XRaiseWindow _glfw.x11.xlib.RaiseWindow
|
||||||
|
#define XResizeWindow _glfw.x11.xlib.ResizeWindow
|
||||||
|
#define XResourceManagerString _glfw.x11.xlib.ResourceManagerString
|
||||||
|
#define XSaveContext _glfw.x11.xlib.SaveContext
|
||||||
|
#define XSelectInput _glfw.x11.xlib.SelectInput
|
||||||
|
#define XSendEvent _glfw.x11.xlib.SendEvent
|
||||||
|
#define XSetClassHint _glfw.x11.xlib.SetClassHint
|
||||||
|
#define XSetErrorHandler _glfw.x11.xlib.SetErrorHandler
|
||||||
|
#define XSetICFocus _glfw.x11.xlib.SetICFocus
|
||||||
|
#define XSetInputFocus _glfw.x11.xlib.SetInputFocus
|
||||||
|
#define XSetLocaleModifiers _glfw.x11.xlib.SetLocaleModifiers
|
||||||
|
#define XSetScreenSaver _glfw.x11.xlib.SetScreenSaver
|
||||||
|
#define XSetSelectionOwner _glfw.x11.xlib.SetSelectionOwner
|
||||||
|
#define XSetWMHints _glfw.x11.xlib.SetWMHints
|
||||||
|
#define XSetWMNormalHints _glfw.x11.xlib.SetWMNormalHints
|
||||||
|
#define XSetWMProtocols _glfw.x11.xlib.SetWMProtocols
|
||||||
|
#define XSupportsLocale _glfw.x11.xlib.SupportsLocale
|
||||||
|
#define XSync _glfw.x11.xlib.Sync
|
||||||
|
#define XTranslateCoordinates _glfw.x11.xlib.TranslateCoordinates
|
||||||
|
#define XUndefineCursor _glfw.x11.xlib.UndefineCursor
|
||||||
|
#define XUngrabPointer _glfw.x11.xlib.UngrabPointer
|
||||||
|
#define XUnmapWindow _glfw.x11.xlib.UnmapWindow
|
||||||
|
#define XUnsetICFocus _glfw.x11.xlib.UnsetICFocus
|
||||||
|
#define XVisualIDFromVisual _glfw.x11.xlib.VisualIDFromVisual
|
||||||
|
#define XWarpPointer _glfw.x11.xlib.WarpPointer
|
||||||
|
#define XkbFreeKeyboard _glfw.x11.xkb.FreeKeyboard
|
||||||
|
#define XkbFreeNames _glfw.x11.xkb.FreeNames
|
||||||
|
#define XkbGetMap _glfw.x11.xkb.GetMap
|
||||||
|
#define XkbGetNames _glfw.x11.xkb.GetNames
|
||||||
|
#define XkbGetState _glfw.x11.xkb.GetState
|
||||||
|
#define XkbKeycodeToKeysym _glfw.x11.xkb.KeycodeToKeysym
|
||||||
|
#define XkbQueryExtension _glfw.x11.xkb.QueryExtension
|
||||||
|
#define XkbSelectEventDetails _glfw.x11.xkb.SelectEventDetails
|
||||||
|
#define XkbSetDetectableAutoRepeat _glfw.x11.xkb.SetDetectableAutoRepeat
|
||||||
|
#define XrmDestroyDatabase _glfw.x11.xrm.DestroyDatabase
|
||||||
|
#define XrmGetResource _glfw.x11.xrm.GetResource
|
||||||
|
#define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase
|
||||||
|
#define XrmInitialize _glfw.x11.xrm.Initialize
|
||||||
|
#define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark
|
||||||
|
#define Xutf8LookupString _glfw.x11.xlib.utf8LookupString
|
||||||
|
#define Xutf8SetWMProperties _glfw.x11.xlib.utf8SetWMProperties
|
||||||
|
|
||||||
typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
|
typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
|
||||||
typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
|
typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
|
||||||
typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
|
typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
|
||||||
@ -85,9 +279,15 @@ typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
|
|||||||
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
|
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
|
||||||
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
|
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
|
||||||
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
|
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
|
||||||
|
typedef char* (* PFN_XcursorGetTheme)(Display*);
|
||||||
|
typedef int (* PFN_XcursorGetDefaultSize)(Display*);
|
||||||
|
typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int);
|
||||||
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
|
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
|
||||||
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
|
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
|
||||||
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
|
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
|
||||||
|
#define XcursorGetTheme _glfw.x11.xcursor.GetTheme
|
||||||
|
#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize
|
||||||
|
#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage
|
||||||
|
|
||||||
typedef Bool (* PFN_XineramaIsActive)(Display*);
|
typedef Bool (* PFN_XineramaIsActive)(Display*);
|
||||||
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
|
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
|
||||||
@ -180,6 +380,7 @@ typedef struct _GLFWwindowX11
|
|||||||
{
|
{
|
||||||
Colormap colormap;
|
Colormap colormap;
|
||||||
Window handle;
|
Window handle;
|
||||||
|
Window parent;
|
||||||
XIC ic;
|
XIC ic;
|
||||||
|
|
||||||
GLFWbool overrideRedirect;
|
GLFWbool overrideRedirect;
|
||||||
@ -228,7 +429,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
// Clipboard string (while the selection is owned)
|
// Clipboard string (while the selection is owned)
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
// Key name string
|
// Key name string
|
||||||
char keyName[5];
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
// X11 keycode to GLFW key LUT
|
// X11 keycode to GLFW key LUT
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
// GLFW key to X11 keycode LUT
|
// GLFW key to X11 keycode LUT
|
||||||
@ -239,6 +440,8 @@ typedef struct _GLFWlibraryX11
|
|||||||
_GLFWwindow* disabledCursorWindow;
|
_GLFWwindow* disabledCursorWindow;
|
||||||
|
|
||||||
// Window manager atoms
|
// Window manager atoms
|
||||||
|
Atom NET_SUPPORTED;
|
||||||
|
Atom NET_SUPPORTING_WM_CHECK;
|
||||||
Atom WM_PROTOCOLS;
|
Atom WM_PROTOCOLS;
|
||||||
Atom WM_STATE;
|
Atom WM_STATE;
|
||||||
Atom WM_DELETE_WINDOW;
|
Atom WM_DELETE_WINDOW;
|
||||||
@ -292,6 +495,100 @@ typedef struct _GLFWlibraryX11
|
|||||||
Atom ATOM_PAIR;
|
Atom ATOM_PAIR;
|
||||||
Atom GLFW_SELECTION;
|
Atom GLFW_SELECTION;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
PFN_XAllocClassHint AllocClassHint;
|
||||||
|
PFN_XAllocSizeHints AllocSizeHints;
|
||||||
|
PFN_XAllocWMHints AllocWMHints;
|
||||||
|
PFN_XChangeProperty ChangeProperty;
|
||||||
|
PFN_XChangeWindowAttributes ChangeWindowAttributes;
|
||||||
|
PFN_XCheckIfEvent CheckIfEvent;
|
||||||
|
PFN_XCheckTypedWindowEvent CheckTypedWindowEvent;
|
||||||
|
PFN_XCloseDisplay CloseDisplay;
|
||||||
|
PFN_XCloseIM CloseIM;
|
||||||
|
PFN_XConvertSelection ConvertSelection;
|
||||||
|
PFN_XCreateColormap CreateColormap;
|
||||||
|
PFN_XCreateFontCursor CreateFontCursor;
|
||||||
|
PFN_XCreateIC CreateIC;
|
||||||
|
PFN_XCreateWindow CreateWindow;
|
||||||
|
PFN_XDefineCursor DefineCursor;
|
||||||
|
PFN_XDeleteContext DeleteContext;
|
||||||
|
PFN_XDeleteProperty DeleteProperty;
|
||||||
|
PFN_XDestroyIC DestroyIC;
|
||||||
|
PFN_XDestroyWindow DestroyWindow;
|
||||||
|
PFN_XEventsQueued EventsQueued;
|
||||||
|
PFN_XFilterEvent FilterEvent;
|
||||||
|
PFN_XFindContext FindContext;
|
||||||
|
PFN_XFlush Flush;
|
||||||
|
PFN_XFree Free;
|
||||||
|
PFN_XFreeColormap FreeColormap;
|
||||||
|
PFN_XFreeCursor FreeCursor;
|
||||||
|
PFN_XFreeEventData FreeEventData;
|
||||||
|
PFN_XGetErrorText GetErrorText;
|
||||||
|
PFN_XGetEventData GetEventData;
|
||||||
|
PFN_XGetICValues GetICValues;
|
||||||
|
PFN_XGetIMValues GetIMValues;
|
||||||
|
PFN_XGetInputFocus GetInputFocus;
|
||||||
|
PFN_XGetKeyboardMapping GetKeyboardMapping;
|
||||||
|
PFN_XGetScreenSaver GetScreenSaver;
|
||||||
|
PFN_XGetSelectionOwner GetSelectionOwner;
|
||||||
|
PFN_XGetVisualInfo GetVisualInfo;
|
||||||
|
PFN_XGetWMNormalHints GetWMNormalHints;
|
||||||
|
PFN_XGetWindowAttributes GetWindowAttributes;
|
||||||
|
PFN_XGetWindowProperty GetWindowProperty;
|
||||||
|
PFN_XGrabPointer GrabPointer;
|
||||||
|
PFN_XIconifyWindow IconifyWindow;
|
||||||
|
PFN_XInitThreads InitThreads;
|
||||||
|
PFN_XInternAtom InternAtom;
|
||||||
|
PFN_XLookupString LookupString;
|
||||||
|
PFN_XMapRaised MapRaised;
|
||||||
|
PFN_XMapWindow MapWindow;
|
||||||
|
PFN_XMoveResizeWindow MoveResizeWindow;
|
||||||
|
PFN_XMoveWindow MoveWindow;
|
||||||
|
PFN_XNextEvent NextEvent;
|
||||||
|
PFN_XOpenDisplay OpenDisplay;
|
||||||
|
PFN_XOpenIM OpenIM;
|
||||||
|
PFN_XPeekEvent PeekEvent;
|
||||||
|
PFN_XPending Pending;
|
||||||
|
PFN_XQueryExtension QueryExtension;
|
||||||
|
PFN_XQueryPointer QueryPointer;
|
||||||
|
PFN_XRaiseWindow RaiseWindow;
|
||||||
|
PFN_XResizeWindow ResizeWindow;
|
||||||
|
PFN_XResourceManagerString ResourceManagerString;
|
||||||
|
PFN_XSaveContext SaveContext;
|
||||||
|
PFN_XSelectInput SelectInput;
|
||||||
|
PFN_XSendEvent SendEvent;
|
||||||
|
PFN_XSetClassHint SetClassHint;
|
||||||
|
PFN_XSetErrorHandler SetErrorHandler;
|
||||||
|
PFN_XSetICFocus SetICFocus;
|
||||||
|
PFN_XSetInputFocus SetInputFocus;
|
||||||
|
PFN_XSetLocaleModifiers SetLocaleModifiers;
|
||||||
|
PFN_XSetScreenSaver SetScreenSaver;
|
||||||
|
PFN_XSetSelectionOwner SetSelectionOwner;
|
||||||
|
PFN_XSetWMHints SetWMHints;
|
||||||
|
PFN_XSetWMNormalHints SetWMNormalHints;
|
||||||
|
PFN_XSetWMProtocols SetWMProtocols;
|
||||||
|
PFN_XSupportsLocale SupportsLocale;
|
||||||
|
PFN_XSync Sync;
|
||||||
|
PFN_XTranslateCoordinates TranslateCoordinates;
|
||||||
|
PFN_XUndefineCursor UndefineCursor;
|
||||||
|
PFN_XUngrabPointer UngrabPointer;
|
||||||
|
PFN_XUnmapWindow UnmapWindow;
|
||||||
|
PFN_XUnsetICFocus UnsetICFocus;
|
||||||
|
PFN_XVisualIDFromVisual VisualIDFromVisual;
|
||||||
|
PFN_XWarpPointer WarpPointer;
|
||||||
|
PFN_Xutf8LookupString utf8LookupString;
|
||||||
|
PFN_Xutf8SetWMProperties utf8SetWMProperties;
|
||||||
|
} xlib;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
PFN_XrmDestroyDatabase DestroyDatabase;
|
||||||
|
PFN_XrmGetResource GetResource;
|
||||||
|
PFN_XrmGetStringDatabase GetStringDatabase;
|
||||||
|
PFN_XrmInitialize Initialize;
|
||||||
|
PFN_XrmUniqueQuark UniqueQuark;
|
||||||
|
} xrm;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLFWbool available;
|
GLFWbool available;
|
||||||
void* handle;
|
void* handle;
|
||||||
@ -321,13 +618,23 @@ typedef struct _GLFWlibraryX11
|
|||||||
} randr;
|
} randr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLFWbool available;
|
GLFWbool available;
|
||||||
GLFWbool detectable;
|
GLFWbool detectable;
|
||||||
int majorOpcode;
|
int majorOpcode;
|
||||||
int eventBase;
|
int eventBase;
|
||||||
int errorBase;
|
int errorBase;
|
||||||
int major;
|
int major;
|
||||||
int minor;
|
int minor;
|
||||||
|
unsigned int group;
|
||||||
|
PFN_XkbFreeKeyboard FreeKeyboard;
|
||||||
|
PFN_XkbFreeNames FreeNames;
|
||||||
|
PFN_XkbGetMap GetMap;
|
||||||
|
PFN_XkbGetNames GetNames;
|
||||||
|
PFN_XkbGetState GetState;
|
||||||
|
PFN_XkbKeycodeToKeysym KeycodeToKeysym;
|
||||||
|
PFN_XkbQueryExtension QueryExtension;
|
||||||
|
PFN_XkbSelectEventDetails SelectEventDetails;
|
||||||
|
PFN_XkbSetDetectableAutoRepeat SetDetectableAutoRepeat;
|
||||||
} xkb;
|
} xkb;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -349,6 +656,9 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XcursorImageCreate ImageCreate;
|
PFN_XcursorImageCreate ImageCreate;
|
||||||
PFN_XcursorImageDestroy ImageDestroy;
|
PFN_XcursorImageDestroy ImageDestroy;
|
||||||
PFN_XcursorImageLoadCursor ImageLoadCursor;
|
PFN_XcursorImageLoadCursor ImageLoadCursor;
|
||||||
|
PFN_XcursorGetTheme GetTheme;
|
||||||
|
PFN_XcursorGetDefaultSize GetDefaultSize;
|
||||||
|
PFN_XcursorLibraryLoadImage LibraryLoadImage;
|
||||||
} xcursor;
|
} xcursor;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
442
src/x11_window.c
442
src/x11_window.c
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -48,6 +50,10 @@
|
|||||||
#define Button6 6
|
#define Button6 6
|
||||||
#define Button7 7
|
#define Button7 7
|
||||||
|
|
||||||
|
// Motif WM hints flags
|
||||||
|
#define MWM_HINTS_DECORATIONS 2
|
||||||
|
#define MWM_DECOR_ALL 1
|
||||||
|
|
||||||
#define _GLFW_XDND_VERSION 5
|
#define _GLFW_XDND_VERSION 5
|
||||||
|
|
||||||
|
|
||||||
@ -213,10 +219,7 @@ static int translateKey(int scancode)
|
|||||||
static void sendEventToWM(_GLFWwindow* window, Atom type,
|
static void sendEventToWM(_GLFWwindow* window, Atom type,
|
||||||
long a, long b, long c, long d, long e)
|
long a, long b, long c, long d, long e)
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event = { ClientMessage };
|
||||||
memset(&event, 0, sizeof(event));
|
|
||||||
|
|
||||||
event.type = ClientMessage;
|
|
||||||
event.xclient.window = window->x11.handle;
|
event.xclient.window = window->x11.handle;
|
||||||
event.xclient.format = 32; // Data is 32-bit longs
|
event.xclient.format = 32; // Data is 32-bit longs
|
||||||
event.xclient.message_type = type;
|
event.xclient.message_type = type;
|
||||||
@ -610,46 +613,41 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
window->x11.transparent = _glfwIsVisualTransparentX11(visual);
|
window->x11.transparent = _glfwIsVisualTransparentX11(visual);
|
||||||
|
|
||||||
// Create the actual window
|
XSetWindowAttributes wa = { 0 };
|
||||||
|
wa.colormap = window->x11.colormap;
|
||||||
|
wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
|
||||||
|
PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
|
||||||
|
ExposureMask | FocusChangeMask | VisibilityChangeMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
|
||||||
|
|
||||||
|
_glfwGrabErrorHandlerX11();
|
||||||
|
|
||||||
|
window->x11.parent = _glfw.x11.root;
|
||||||
|
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
||||||
|
_glfw.x11.root,
|
||||||
|
0, 0, // Position
|
||||||
|
width, height,
|
||||||
|
0, // Border width
|
||||||
|
depth, // Color depth
|
||||||
|
InputOutput,
|
||||||
|
visual,
|
||||||
|
CWBorderPixel | CWColormap | CWEventMask,
|
||||||
|
&wa);
|
||||||
|
|
||||||
|
_glfwReleaseErrorHandlerX11();
|
||||||
|
|
||||||
|
if (!window->x11.handle)
|
||||||
{
|
{
|
||||||
XSetWindowAttributes wa;
|
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
|
||||||
const unsigned long wamask = CWBorderPixel | CWColormap | CWEventMask;
|
"X11: Failed to create window");
|
||||||
|
return GLFW_FALSE;
|
||||||
wa.colormap = window->x11.colormap;
|
|
||||||
wa.border_pixel = 0;
|
|
||||||
wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
|
|
||||||
PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
|
|
||||||
ExposureMask | FocusChangeMask | VisibilityChangeMask |
|
|
||||||
EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
|
|
||||||
|
|
||||||
_glfwGrabErrorHandlerX11();
|
|
||||||
|
|
||||||
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
|
||||||
_glfw.x11.root,
|
|
||||||
0, 0,
|
|
||||||
width, height,
|
|
||||||
0, // Border width
|
|
||||||
depth, // Color depth
|
|
||||||
InputOutput,
|
|
||||||
visual,
|
|
||||||
wamask,
|
|
||||||
&wa);
|
|
||||||
|
|
||||||
_glfwReleaseErrorHandlerX11();
|
|
||||||
|
|
||||||
if (!window->x11.handle)
|
|
||||||
{
|
|
||||||
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
|
|
||||||
"X11: Failed to create window");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
XSaveContext(_glfw.x11.display,
|
|
||||||
window->x11.handle,
|
|
||||||
_glfw.x11.context,
|
|
||||||
(XPointer) window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XSaveContext(_glfw.x11.display,
|
||||||
|
window->x11.handle,
|
||||||
|
_glfw.x11.context,
|
||||||
|
(XPointer) window);
|
||||||
|
|
||||||
if (!wndconfig->decorated)
|
if (!wndconfig->decorated)
|
||||||
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
|
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
|
||||||
|
|
||||||
@ -679,7 +677,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||||
PropModeReplace, (unsigned char*) &states, count);
|
PropModeReplace, (unsigned char*) states, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,6 +782,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
NULL);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
_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);
|
||||||
|
|
||||||
@ -944,11 +949,8 @@ static void handleSelectionRequest(XEvent* event)
|
|||||||
{
|
{
|
||||||
const XSelectionRequestEvent* request = &event->xselectionrequest;
|
const XSelectionRequestEvent* request = &event->xselectionrequest;
|
||||||
|
|
||||||
XEvent reply;
|
XEvent reply = { SelectionNotify };
|
||||||
memset(&reply, 0, sizeof(reply));
|
|
||||||
|
|
||||||
reply.xselection.property = writeTargetToProperty(request);
|
reply.xselection.property = writeTargetToProperty(request);
|
||||||
reply.xselection.type = SelectionNotify;
|
|
||||||
reply.xselection.display = request->display;
|
reply.xselection.display = request->display;
|
||||||
reply.xselection.requestor = request->requestor;
|
reply.xselection.requestor = request->requestor;
|
||||||
reply.xselection.selection = request->selection;
|
reply.xselection.selection = request->selection;
|
||||||
@ -960,7 +962,6 @@ static void handleSelectionRequest(XEvent* event)
|
|||||||
|
|
||||||
static const char* getSelectionString(Atom selection)
|
static const char* getSelectionString(Atom selection)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
char** selectionString = NULL;
|
char** selectionString = NULL;
|
||||||
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
|
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
|
||||||
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
|
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
|
||||||
@ -981,7 +982,7 @@ static const char* getSelectionString(Atom selection)
|
|||||||
free(*selectionString);
|
free(*selectionString);
|
||||||
*selectionString = NULL;
|
*selectionString = NULL;
|
||||||
|
|
||||||
for (i = 0; i < targetCount; i++)
|
for (size_t i = 0; i < targetCount; i++)
|
||||||
{
|
{
|
||||||
char* data;
|
char* data;
|
||||||
Atom actualType;
|
Atom actualType;
|
||||||
@ -1165,7 +1166,6 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
//
|
//
|
||||||
static void processEvent(XEvent *event)
|
static void processEvent(XEvent *event)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = NULL;
|
|
||||||
int keycode = 0;
|
int keycode = 0;
|
||||||
Bool filtered = False;
|
Bool filtered = False;
|
||||||
|
|
||||||
@ -1186,6 +1186,18 @@ static void processEvent(XEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.xkb.available)
|
||||||
|
{
|
||||||
|
if (event->type == _glfw.x11.xkb.eventBase + XkbEventCode)
|
||||||
|
{
|
||||||
|
if (((XkbEvent*) event)->any.xkb_type == XkbStateNotify &&
|
||||||
|
(((XkbEvent*) event)->state.changed & XkbGroupStateMask))
|
||||||
|
{
|
||||||
|
_glfw.x11.xkb.group = ((XkbEvent*) event)->state.group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (event->type == GenericEvent)
|
if (event->type == GenericEvent)
|
||||||
{
|
{
|
||||||
if (_glfw.x11.xi.available)
|
if (_glfw.x11.xi.available)
|
||||||
@ -1235,6 +1247,7 @@ static void processEvent(XEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_GLFWwindow* window = NULL;
|
||||||
if (XFindContext(_glfw.x11.display,
|
if (XFindContext(_glfw.x11.display,
|
||||||
event->xany.window,
|
event->xany.window,
|
||||||
_glfw.x11.context,
|
_glfw.x11.context,
|
||||||
@ -1246,6 +1259,12 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
|
case ReparentNotify:
|
||||||
|
{
|
||||||
|
window->x11.parent = event->xreparent.parent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
const int key = translateKey(keycode);
|
const int key = translateKey(keycode);
|
||||||
@ -1531,18 +1550,28 @@ static void processEvent(XEvent *event)
|
|||||||
window->x11.height = event->xconfigure.height;
|
window->x11.height = event->xconfigure.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->xconfigure.x != window->x11.xpos ||
|
int xpos = event->xconfigure.x;
|
||||||
event->xconfigure.y != window->x11.ypos)
|
int ypos = event->xconfigure.y;
|
||||||
{
|
|
||||||
if (window->x11.overrideRedirect || event->xany.send_event)
|
|
||||||
{
|
|
||||||
_glfwInputWindowPos(window,
|
|
||||||
event->xconfigure.x,
|
|
||||||
event->xconfigure.y);
|
|
||||||
|
|
||||||
window->x11.xpos = event->xconfigure.x;
|
// NOTE: ConfigureNotify events from the server are in local
|
||||||
window->x11.ypos = event->xconfigure.y;
|
// coordinates, so if we are reparented we need to translate
|
||||||
}
|
// the position into root (screen) coordinates
|
||||||
|
if (!event->xany.send_event && window->x11.parent != _glfw.x11.root)
|
||||||
|
{
|
||||||
|
Window dummy;
|
||||||
|
XTranslateCoordinates(_glfw.x11.display,
|
||||||
|
window->x11.parent,
|
||||||
|
_glfw.x11.root,
|
||||||
|
xpos, ypos,
|
||||||
|
&xpos, &ypos,
|
||||||
|
&dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xpos != window->x11.xpos || ypos != window->x11.ypos)
|
||||||
|
{
|
||||||
|
_glfwInputWindowPos(window, xpos, ypos);
|
||||||
|
window->x11.xpos = xpos;
|
||||||
|
window->x11.ypos = ypos;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1647,10 +1676,7 @@ static void processEvent(XEvent *event)
|
|||||||
}
|
}
|
||||||
else if (_glfw.x11.xdnd.version >= 2)
|
else if (_glfw.x11.xdnd.version >= 2)
|
||||||
{
|
{
|
||||||
XEvent reply;
|
XEvent reply = { ClientMessage };
|
||||||
memset(&reply, 0, sizeof(reply));
|
|
||||||
|
|
||||||
reply.type = ClientMessage;
|
|
||||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||||
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
||||||
reply.xclient.format = 32;
|
reply.xclient.format = 32;
|
||||||
@ -1683,10 +1709,7 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
_glfwInputCursorPos(window, xpos, ypos);
|
_glfwInputCursorPos(window, xpos, ypos);
|
||||||
|
|
||||||
XEvent reply;
|
XEvent reply = { ClientMessage };
|
||||||
memset(&reply, 0, sizeof(reply));
|
|
||||||
|
|
||||||
reply.type = ClientMessage;
|
|
||||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||||
reply.xclient.message_type = _glfw.x11.XdndStatus;
|
reply.xclient.message_type = _glfw.x11.XdndStatus;
|
||||||
reply.xclient.format = 32;
|
reply.xclient.format = 32;
|
||||||
@ -1739,10 +1762,7 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
if (_glfw.x11.xdnd.version >= 2)
|
if (_glfw.x11.xdnd.version >= 2)
|
||||||
{
|
{
|
||||||
XEvent reply;
|
XEvent reply = { ClientMessage };
|
||||||
memset(&reply, 0, sizeof(reply));
|
|
||||||
|
|
||||||
reply.type = ClientMessage;
|
|
||||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||||
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
||||||
reply.xclient.format = 32;
|
reply.xclient.format = 32;
|
||||||
@ -1761,9 +1781,6 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
|
||||||
disableCursor(window);
|
|
||||||
|
|
||||||
if (event->xfocus.mode == NotifyGrab ||
|
if (event->xfocus.mode == NotifyGrab ||
|
||||||
event->xfocus.mode == NotifyUngrab)
|
event->xfocus.mode == NotifyUngrab)
|
||||||
{
|
{
|
||||||
@ -1772,6 +1789,9 @@ static void processEvent(XEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
|
disableCursor(window);
|
||||||
|
|
||||||
if (window->x11.ic)
|
if (window->x11.ic)
|
||||||
XSetICFocus(window->x11.ic);
|
XSetICFocus(window->x11.ic);
|
||||||
|
|
||||||
@ -1781,9 +1801,6 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
|
||||||
enableCursor(window);
|
|
||||||
|
|
||||||
if (event->xfocus.mode == NotifyGrab ||
|
if (event->xfocus.mode == NotifyGrab ||
|
||||||
event->xfocus.mode == NotifyUngrab)
|
event->xfocus.mode == NotifyUngrab)
|
||||||
{
|
{
|
||||||
@ -1792,6 +1809,9 @@ static void processEvent(XEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
|
enableCursor(window);
|
||||||
|
|
||||||
if (window->x11.ic)
|
if (window->x11.ic)
|
||||||
XUnsetICFocus(window->x11.ic);
|
XUnsetICFocus(window->x11.ic);
|
||||||
|
|
||||||
@ -2339,18 +2359,67 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (_glfw.x11.NET_WM_STATE &&
|
if (!_glfw.x11.NET_WM_STATE ||
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
|
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfwPlatformWindowVisible(window))
|
||||||
{
|
{
|
||||||
sendEventToWM(window,
|
sendEventToWM(window,
|
||||||
_glfw.x11.NET_WM_STATE,
|
_glfw.x11.NET_WM_STATE,
|
||||||
_NET_WM_STATE_ADD,
|
_NET_WM_STATE_ADD,
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
|
||||||
1, 0);
|
1, 0);
|
||||||
XFlush(_glfw.x11.display);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Atom* states = NULL;
|
||||||
|
unsigned long count =
|
||||||
|
_glfwGetWindowPropertyX11(window->x11.handle,
|
||||||
|
_glfw.x11.NET_WM_STATE,
|
||||||
|
XA_ATOM,
|
||||||
|
(unsigned char**) &states);
|
||||||
|
|
||||||
|
// NOTE: We don't check for failure as this property may not exist yet
|
||||||
|
// and that's fine (and we'll create it implicitly with append)
|
||||||
|
|
||||||
|
Atom missing[2] =
|
||||||
|
{
|
||||||
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
|
||||||
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ
|
||||||
|
};
|
||||||
|
unsigned long missingCount = 2;
|
||||||
|
|
||||||
|
for (unsigned long i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
for (unsigned long j = 0; j < missingCount; j++)
|
||||||
|
{
|
||||||
|
if (states[i] == missing[j])
|
||||||
|
{
|
||||||
|
missing[j] = missing[missingCount - 1];
|
||||||
|
missingCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (states)
|
||||||
|
XFree(states);
|
||||||
|
|
||||||
|
if (!missingCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
|
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||||
|
PropModeAppend,
|
||||||
|
(unsigned char*) missing,
|
||||||
|
missingCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFlush(_glfw.x11.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||||
@ -2370,6 +2439,9 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION)
|
||||||
|
return;
|
||||||
|
|
||||||
sendEventToWM(window,
|
sendEventToWM(window,
|
||||||
_glfw.x11.NET_WM_STATE,
|
_glfw.x11.NET_WM_STATE,
|
||||||
_NET_WM_STATE_ADD,
|
_NET_WM_STATE_ADD,
|
||||||
@ -2381,7 +2453,7 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.NET_ACTIVE_WINDOW)
|
if (_glfw.x11.NET_ACTIVE_WINDOW)
|
||||||
sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
|
sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
|
||||||
else
|
else if (_glfwPlatformWindowVisible(window))
|
||||||
{
|
{
|
||||||
XRaiseWindow(_glfw.x11.display, window->x11.handle);
|
XRaiseWindow(_glfw.x11.display, window->x11.handle);
|
||||||
XSetInputFocus(_glfw.x11.display, window->x11.handle,
|
XSetInputFocus(_glfw.x11.display, window->x11.handle,
|
||||||
@ -2539,33 +2611,24 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
if (enabled)
|
struct
|
||||||
{
|
{
|
||||||
XDeleteProperty(_glfw.x11.display,
|
unsigned long flags;
|
||||||
window->x11.handle,
|
unsigned long functions;
|
||||||
_glfw.x11.MOTIF_WM_HINTS);
|
unsigned long decorations;
|
||||||
}
|
long input_mode;
|
||||||
else
|
unsigned long status;
|
||||||
{
|
} hints = {0};
|
||||||
struct
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long functions;
|
|
||||||
unsigned long decorations;
|
|
||||||
long input_mode;
|
|
||||||
unsigned long status;
|
|
||||||
} hints;
|
|
||||||
|
|
||||||
hints.flags = 2; // Set decorations
|
hints.flags = MWM_HINTS_DECORATIONS;
|
||||||
hints.decorations = 0; // No decorations
|
hints.decorations = enabled ? MWM_DECOR_ALL : 0;
|
||||||
|
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
_glfw.x11.MOTIF_WM_HINTS,
|
_glfw.x11.MOTIF_WM_HINTS,
|
||||||
_glfw.x11.MOTIF_WM_HINTS, 32,
|
_glfw.x11.MOTIF_WM_HINTS, 32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(unsigned char*) &hints,
|
(unsigned char*) &hints,
|
||||||
sizeof(hints) / sizeof(long));
|
sizeof(hints) / sizeof(long));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||||
@ -2575,7 +2638,7 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
|
|
||||||
if (_glfwPlatformWindowVisible(window))
|
if (_glfwPlatformWindowVisible(window))
|
||||||
{
|
{
|
||||||
const Atom action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
const long action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||||
sendEventToWM(window,
|
sendEventToWM(window,
|
||||||
_glfw.x11.NET_WM_STATE,
|
_glfw.x11.NET_WM_STATE,
|
||||||
action,
|
action,
|
||||||
@ -2584,15 +2647,16 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Atom* states;
|
Atom* states = NULL;
|
||||||
unsigned long i, count;
|
unsigned long i, count;
|
||||||
|
|
||||||
count = _glfwGetWindowPropertyX11(window->x11.handle,
|
count = _glfwGetWindowPropertyX11(window->x11.handle,
|
||||||
_glfw.x11.NET_WM_STATE,
|
_glfw.x11.NET_WM_STATE,
|
||||||
XA_ATOM,
|
XA_ATOM,
|
||||||
(unsigned char**) &states);
|
(unsigned char**) &states);
|
||||||
if (!states)
|
|
||||||
return;
|
// NOTE: We don't check for failure as this property may not exist yet
|
||||||
|
// and that's fine (and we'll create it implicitly with append)
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
@ -2602,32 +2666,36 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == count)
|
if (i < count)
|
||||||
{
|
return;
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
|
||||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
PropModeAppend,
|
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||||
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
|
PropModeAppend,
|
||||||
1);
|
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
|
||||||
}
|
1);
|
||||||
}
|
}
|
||||||
else
|
else if (states)
|
||||||
{
|
{
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
||||||
{
|
break;
|
||||||
states[i] = states[count - 1];
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
states[i] = states[count - 1];
|
||||||
|
count--;
|
||||||
|
|
||||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||||
PropModeReplace, (unsigned char*) &states, count);
|
PropModeReplace, (unsigned char*) states, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree(states);
|
if (states)
|
||||||
|
XFree(states);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFlush(_glfw.x11.display);
|
XFlush(_glfw.x11.display);
|
||||||
@ -2692,7 +2760,7 @@ void _glfwPlatformPollEvents(void)
|
|||||||
#endif
|
#endif
|
||||||
XPending(_glfw.x11.display);
|
XPending(_glfw.x11.display);
|
||||||
|
|
||||||
while (XQLength(_glfw.x11.display))
|
while (QLength(_glfw.x11.display))
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
XNextEvent(_glfw.x11.display, &event);
|
XNextEvent(_glfw.x11.display, &event);
|
||||||
@ -2738,10 +2806,7 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
|
|||||||
|
|
||||||
void _glfwPlatformPostEmptyEvent(void)
|
void _glfwPlatformPostEmptyEvent(void)
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event = { ClientMessage };
|
||||||
|
|
||||||
memset(&event, 0, sizeof(event));
|
|
||||||
event.type = ClientMessage;
|
|
||||||
event.xclient.window = _glfw.x11.helperWindowHandle;
|
event.xclient.window = _glfw.x11.helperWindowHandle;
|
||||||
event.xclient.format = 32; // Data is 32-bit longs
|
event.xclient.format = 32; // Data is 32-bit longs
|
||||||
event.xclient.message_type = _glfw.x11.NULL_;
|
event.xclient.message_type = _glfw.x11.NULL_;
|
||||||
@ -2798,7 +2863,16 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
|||||||
if (!_glfw.x11.xkb.available)
|
if (!_glfw.x11.xkb.available)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
|
if (scancode < 0 || scancode > 0xff ||
|
||||||
|
_glfw.x11.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int key = _glfw.x11.keycodes[scancode];
|
||||||
|
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display,
|
||||||
|
scancode, _glfw.x11.xkb.group, 0);
|
||||||
if (keysym == NoSymbol)
|
if (keysym == NoSymbol)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -2806,12 +2880,12 @@ const char* _glfwPlatformGetScancodeName(int scancode)
|
|||||||
if (ch == -1)
|
if (ch == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const size_t count = encodeUTF8(_glfw.x11.keyName, (unsigned int) ch);
|
const size_t count = encodeUTF8(_glfw.x11.keynames[key], (unsigned int) ch);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
_glfw.x11.keyName[count] = '\0';
|
_glfw.x11.keynames[key][count] = '\0';
|
||||||
return _glfw.x11.keyName;
|
return _glfw.x11.keynames[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformGetKeyScancode(int key)
|
int _glfwPlatformGetKeyScancode(int key)
|
||||||
@ -2832,29 +2906,76 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
{
|
{
|
||||||
int native = 0;
|
if (_glfw.x11.xcursor.handle)
|
||||||
|
{
|
||||||
|
char* theme = XcursorGetTheme(_glfw.x11.display);
|
||||||
|
if (theme)
|
||||||
|
{
|
||||||
|
const int size = XcursorGetDefaultSize(_glfw.x11.display);
|
||||||
|
const char* name = NULL;
|
||||||
|
|
||||||
if (shape == GLFW_ARROW_CURSOR)
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
native = XC_left_ptr;
|
name = "default";
|
||||||
else if (shape == GLFW_IBEAM_CURSOR)
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
native = XC_xterm;
|
name = "text";
|
||||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
native = XC_crosshair;
|
name = "crosshair";
|
||||||
else if (shape == GLFW_HAND_CURSOR)
|
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||||
native = XC_hand2;
|
name = "pointer";
|
||||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
native = XC_sb_h_double_arrow;
|
name = "ew-resize";
|
||||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
native = XC_sb_v_double_arrow;
|
name = "ns-resize";
|
||||||
else
|
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||||
return GLFW_FALSE;
|
name = "nwse-resize";
|
||||||
|
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||||
|
name = "nesw-resize";
|
||||||
|
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||||
|
name = "all-scroll";
|
||||||
|
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||||
|
name = "not-allowed";
|
||||||
|
|
||||||
|
XcursorImage* image = XcursorLibraryLoadImage(name, theme, size);
|
||||||
|
if (image)
|
||||||
|
{
|
||||||
|
cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, image);
|
||||||
|
XcursorImageDestroy(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
|
||||||
if (!cursor->x11.handle)
|
if (!cursor->x11.handle)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
unsigned int native = 0;
|
||||||
"X11: Failed to create standard cursor");
|
|
||||||
return GLFW_FALSE;
|
if (shape == GLFW_ARROW_CURSOR)
|
||||||
|
native = XC_left_ptr;
|
||||||
|
else if (shape == GLFW_IBEAM_CURSOR)
|
||||||
|
native = XC_xterm;
|
||||||
|
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||||
|
native = XC_crosshair;
|
||||||
|
else if (shape == GLFW_POINTING_HAND_CURSOR)
|
||||||
|
native = XC_hand2;
|
||||||
|
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||||
|
native = XC_sb_h_double_arrow;
|
||||||
|
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||||
|
native = XC_sb_v_double_arrow;
|
||||||
|
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||||
|
native = XC_fleur;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
|
||||||
|
"X11: Standard cursor shape unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||||
|
if (!cursor->x11.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Failed to create standard cursor");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -2877,8 +2998,9 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||||||
|
|
||||||
void _glfwPlatformSetClipboardString(const char* string)
|
void _glfwPlatformSetClipboardString(const char* string)
|
||||||
{
|
{
|
||||||
|
char* copy = _glfw_strdup(string);
|
||||||
free(_glfw.x11.clipboardString);
|
free(_glfw.x11.clipboardString);
|
||||||
_glfw.x11.clipboardString = _glfw_strdup(string);
|
_glfw.x11.clipboardString = copy;
|
||||||
|
|
||||||
XSetSelectionOwner(_glfw.x11.display,
|
XSetSelectionOwner(_glfw.x11.display,
|
||||||
_glfw.x11.CLIPBOARD,
|
_glfw.x11.CLIPBOARD,
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// distribution.
|
// distribution.
|
||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
link_libraries(glfw)
|
link_libraries(glfw)
|
||||||
|
|
||||||
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
|
include_directories("${GLFW_SOURCE_DIR}/deps")
|
||||||
|
|
||||||
if (MATH_LIBRARY)
|
if (MATH_LIBRARY)
|
||||||
link_libraries("${MATH_LIBRARY}")
|
link_libraries("${MATH_LIBRARY}")
|
||||||
@ -39,27 +39,28 @@ 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(vulkan WIN32 vulkan.c ${ICON} ${GLAD_VULKAN})
|
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
|
||||||
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GETOPT} ${GLAD_GL})
|
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD_GL})
|
||||||
|
|
||||||
target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}")
|
target_link_libraries(empty Threads::Threads)
|
||||||
target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}")
|
target_link_libraries(threads Threads::Threads)
|
||||||
if (RT_LIBRARY)
|
if (RT_LIBRARY)
|
||||||
target_link_libraries(empty "${RT_LIBRARY}")
|
target_link_libraries(empty "${RT_LIBRARY}")
|
||||||
target_link_libraries(threads "${RT_LIBRARY}")
|
target_link_libraries(threads "${RT_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WINDOWS_BINARIES empty gamma icon inputlag joysticks opacity tearing
|
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks opacity tearing
|
||||||
threads timeout title vulkan windows)
|
threads timeout title triangle-vulkan windows)
|
||||||
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
||||||
cursor)
|
cursor)
|
||||||
|
|
||||||
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||||
|
C_STANDARD 99
|
||||||
FOLDER "GLFW3/Tests")
|
FOLDER "GLFW3/Tests")
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
|
||||||
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||||
LINK_FLAGS "/ENTRY:mainCRTStartup")
|
LINK_FLAGS "/ENTRY:mainCRTStartup")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -73,12 +74,11 @@ if (APPLE)
|
|||||||
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 "Vulkan")
|
|
||||||
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
|
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
|
||||||
|
|
||||||
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
|
||||||
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}
|
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in")
|
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/Info.plist.in")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@ -68,7 +69,7 @@ static int swap_interval = 1;
|
|||||||
static int wait_events = GLFW_TRUE;
|
static int wait_events = GLFW_TRUE;
|
||||||
static int animate_cursor = GLFW_FALSE;
|
static int animate_cursor = GLFW_FALSE;
|
||||||
static int track_cursor = GLFW_FALSE;
|
static int track_cursor = GLFW_FALSE;
|
||||||
static GLFWcursor* standard_cursors[6];
|
static GLFWcursor* standard_cursors[10];
|
||||||
static GLFWcursor* tracking_cursor = NULL;
|
static GLFWcursor* tracking_cursor = NULL;
|
||||||
|
|
||||||
static void error_callback(int error, const char* description)
|
static void error_callback(int error, const char* description)
|
||||||
@ -270,28 +271,24 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GLFW_KEY_1:
|
case GLFW_KEY_1:
|
||||||
glfwSetCursor(window, standard_cursors[0]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_KEY_2:
|
case GLFW_KEY_2:
|
||||||
glfwSetCursor(window, standard_cursors[1]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_KEY_3:
|
case GLFW_KEY_3:
|
||||||
glfwSetCursor(window, standard_cursors[2]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_KEY_4:
|
case GLFW_KEY_4:
|
||||||
glfwSetCursor(window, standard_cursors[3]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_KEY_5:
|
case GLFW_KEY_5:
|
||||||
glfwSetCursor(window, standard_cursors[4]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_KEY_6:
|
case GLFW_KEY_6:
|
||||||
glfwSetCursor(window, standard_cursors[5]);
|
case GLFW_KEY_7:
|
||||||
|
case GLFW_KEY_8:
|
||||||
|
case GLFW_KEY_9:
|
||||||
|
{
|
||||||
|
int index = key - GLFW_KEY_1;
|
||||||
|
if (mods & GLFW_MOD_SHIFT)
|
||||||
|
index += 9;
|
||||||
|
|
||||||
|
if (index < sizeof(standard_cursors) / sizeof(standard_cursors[0]))
|
||||||
|
glfwSetCursor(window, standard_cursors[index]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GLFW_KEY_F11:
|
case GLFW_KEY_F11:
|
||||||
case GLFW_KEY_ENTER:
|
case GLFW_KEY_ENTER:
|
||||||
@ -357,17 +354,16 @@ int main(void)
|
|||||||
GLFW_ARROW_CURSOR,
|
GLFW_ARROW_CURSOR,
|
||||||
GLFW_IBEAM_CURSOR,
|
GLFW_IBEAM_CURSOR,
|
||||||
GLFW_CROSSHAIR_CURSOR,
|
GLFW_CROSSHAIR_CURSOR,
|
||||||
GLFW_HAND_CURSOR,
|
GLFW_POINTING_HAND_CURSOR,
|
||||||
GLFW_HRESIZE_CURSOR,
|
GLFW_RESIZE_EW_CURSOR,
|
||||||
GLFW_VRESIZE_CURSOR
|
GLFW_RESIZE_NS_CURSOR,
|
||||||
|
GLFW_RESIZE_NWSE_CURSOR,
|
||||||
|
GLFW_RESIZE_NESW_CURSOR,
|
||||||
|
GLFW_RESIZE_ALL_CURSOR,
|
||||||
|
GLFW_NOT_ALLOWED_CURSOR
|
||||||
};
|
};
|
||||||
|
|
||||||
standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
|
standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
|
||||||
if (!standard_cursors[i])
|
|
||||||
{
|
|
||||||
glfwTerminate();
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "tinycthread.h"
|
#include "tinycthread.h"
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -174,7 +175,7 @@ static const char* get_key_name(int key)
|
|||||||
case GLFW_KEY_KP_8: return "KEYPAD 8";
|
case GLFW_KEY_KP_8: return "KEYPAD 8";
|
||||||
case GLFW_KEY_KP_9: return "KEYPAD 9";
|
case GLFW_KEY_KP_9: return "KEYPAD 9";
|
||||||
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
|
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
|
||||||
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY";
|
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTIPLY";
|
||||||
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
|
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
|
||||||
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
|
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
|
||||||
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
|
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
|
||||||
@ -252,17 +253,32 @@ static const char* get_mods_name(int mods)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* get_character_string(int codepoint)
|
static size_t encode_utf8(char* s, unsigned int ch)
|
||||||
{
|
{
|
||||||
// This assumes UTF-8, which is stupid
|
size_t count = 0;
|
||||||
static char result[6 + 1];
|
|
||||||
|
|
||||||
int length = wctomb(result, codepoint);
|
if (ch < 0x80)
|
||||||
if (length == -1)
|
s[count++] = (char) ch;
|
||||||
length = 0;
|
else if (ch < 0x800)
|
||||||
|
{
|
||||||
|
s[count++] = (ch >> 6) | 0xc0;
|
||||||
|
s[count++] = (ch & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (ch < 0x10000)
|
||||||
|
{
|
||||||
|
s[count++] = (ch >> 12) | 0xe0;
|
||||||
|
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (ch & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (ch < 0x110000)
|
||||||
|
{
|
||||||
|
s[count++] = (ch >> 18) | 0xf0;
|
||||||
|
s[count++] = ((ch >> 12) & 0x3f) | 0x80;
|
||||||
|
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (ch & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
result[length] = '\0';
|
return count;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void error_callback(int error, const char* description)
|
static void error_callback(int error, const char* description)
|
||||||
@ -304,6 +320,12 @@ static void window_close_callback(GLFWwindow* window)
|
|||||||
printf("%08x to %i at %0.3f: Window close\n",
|
printf("%08x to %i at %0.3f: Window close\n",
|
||||||
counter++, slot->number, glfwGetTime());
|
counter++, slot->number, glfwGetTime());
|
||||||
|
|
||||||
|
if (!slot->closeable)
|
||||||
|
{
|
||||||
|
printf("(( closing is disabled, press %s to re-enable )\n",
|
||||||
|
glfwGetKeyName(GLFW_KEY_C, 0));
|
||||||
|
}
|
||||||
|
|
||||||
glfwSetWindowShouldClose(window, slot->closeable);
|
glfwSetWindowShouldClose(window, slot->closeable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,12 +446,14 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
|
|||||||
static void char_callback(GLFWwindow* window, unsigned int codepoint)
|
static void char_callback(GLFWwindow* window, unsigned int codepoint)
|
||||||
{
|
{
|
||||||
Slot* slot = glfwGetWindowUserPointer(window);
|
Slot* slot = glfwGetWindowUserPointer(window);
|
||||||
|
char string[5] = "";
|
||||||
|
|
||||||
|
encode_utf8(string, codepoint);
|
||||||
printf("%08x to %i at %0.3f: Character 0x%08x (%s) input\n",
|
printf("%08x to %i at %0.3f: Character 0x%08x (%s) input\n",
|
||||||
counter++, slot->number, glfwGetTime(), codepoint,
|
counter++, slot->number, glfwGetTime(), codepoint, string);
|
||||||
get_character_string(codepoint));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drop_callback(GLFWwindow* window, int count, const char** paths)
|
static void drop_callback(GLFWwindow* window, int count, const char* paths[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Slot* slot = glfwGetWindowUserPointer(window);
|
Slot* slot = glfwGetWindowUserPointer(window);
|
||||||
@ -485,6 +509,20 @@ static void joystick_callback(int jid, int event)
|
|||||||
axisCount,
|
axisCount,
|
||||||
buttonCount,
|
buttonCount,
|
||||||
hatCount);
|
hatCount);
|
||||||
|
|
||||||
|
if (glfwJoystickIsGamepad(jid))
|
||||||
|
{
|
||||||
|
printf(" Joystick %i (%s) has a gamepad mapping (%s)\n",
|
||||||
|
jid,
|
||||||
|
glfwGetJoystickGUID(jid),
|
||||||
|
glfwGetGamepadName(jid));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" Joystick %i (%s) has no gamepad mapping\n",
|
||||||
|
jid,
|
||||||
|
glfwGetJoystickGUID(jid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -499,8 +537,6 @@ int main(int argc, char** argv)
|
|||||||
GLFWmonitor* monitor = NULL;
|
GLFWmonitor* monitor = NULL;
|
||||||
int ch, i, width, height, count = 1;
|
int ch, i, width, height, count = 1;
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#define NK_IMPLEMENTATION
|
#define NK_IMPLEMENTATION
|
||||||
@ -100,6 +101,7 @@ int main(int argc, char** argv)
|
|||||||
monitor = glfwGetPrimaryMonitor();
|
monitor = glfwGetPrimaryMonitor();
|
||||||
|
|
||||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(800, 400, "Gamma Test", NULL, NULL);
|
window = glfwCreateWindow(800, 400, "Gamma Test", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
|
196
tests/glfwinfo.c
196
tests/glfwinfo.c
@ -25,11 +25,13 @@
|
|||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include <glad/vulkan.h>
|
#include <glad/vulkan.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
|
||||||
@ -175,22 +177,19 @@ static const char* get_strategy_name_glfw(int strategy)
|
|||||||
|
|
||||||
static void list_context_extensions(int client, int major, int minor)
|
static void list_context_extensions(int client, int major, int minor)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
GLint count;
|
|
||||||
const GLubyte* extensions;
|
|
||||||
|
|
||||||
printf("%s context extensions:\n", get_api_name(client));
|
printf("%s context extensions:\n", get_api_name(client));
|
||||||
|
|
||||||
if (client == GLFW_OPENGL_API && major > 2)
|
if (client == GLFW_OPENGL_API && major > 2)
|
||||||
{
|
{
|
||||||
|
GLint count;
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i));
|
printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
extensions = glGetString(GL_EXTENSIONS);
|
const GLubyte* extensions = glGetString(GL_EXTENSIONS);
|
||||||
while (*extensions != '\0')
|
while (*extensions != '\0')
|
||||||
{
|
{
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
@ -211,49 +210,31 @@ static void list_context_extensions(int client, int major, int minor)
|
|||||||
|
|
||||||
static void list_vulkan_instance_extensions(void)
|
static void list_vulkan_instance_extensions(void)
|
||||||
{
|
{
|
||||||
uint32_t i, ep_count = 0;
|
|
||||||
VkExtensionProperties* ep;
|
|
||||||
|
|
||||||
printf("Vulkan instance extensions:\n");
|
printf("Vulkan instance extensions:\n");
|
||||||
|
|
||||||
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS)
|
uint32_t ep_count;
|
||||||
return;
|
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL);
|
||||||
|
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
||||||
|
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep);
|
||||||
|
|
||||||
ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
for (uint32_t i = 0; i < ep_count; i++)
|
||||||
|
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
|
||||||
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
free(ep);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ep_count; i++)
|
|
||||||
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
|
|
||||||
|
|
||||||
free(ep);
|
free(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_vulkan_instance_layers(void)
|
static void list_vulkan_instance_layers(void)
|
||||||
{
|
{
|
||||||
uint32_t i, lp_count = 0;
|
|
||||||
VkLayerProperties* lp;
|
|
||||||
|
|
||||||
printf("Vulkan instance layers:\n");
|
printf("Vulkan instance layers:\n");
|
||||||
|
|
||||||
if (vkEnumerateInstanceLayerProperties(&lp_count, NULL) != VK_SUCCESS)
|
uint32_t lp_count;
|
||||||
return;
|
vkEnumerateInstanceLayerProperties(&lp_count, NULL);
|
||||||
|
VkLayerProperties* lp = calloc(lp_count, sizeof(VkLayerProperties));
|
||||||
|
vkEnumerateInstanceLayerProperties(&lp_count, lp);
|
||||||
|
|
||||||
lp = calloc(lp_count, sizeof(VkLayerProperties));
|
for (uint32_t i = 0; i < lp_count; i++)
|
||||||
|
|
||||||
if (vkEnumerateInstanceLayerProperties(&lp_count, lp) != VK_SUCCESS)
|
|
||||||
{
|
{
|
||||||
free(lp);
|
printf(" %s (spec version %u) \"%s\"\n",
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < lp_count; i++)
|
|
||||||
{
|
|
||||||
printf(" %s (v%u) \"%s\"\n",
|
|
||||||
lp[i].layerName,
|
lp[i].layerName,
|
||||||
lp[i].specVersion >> 22,
|
lp[i].specVersion >> 22,
|
||||||
lp[i].description);
|
lp[i].description);
|
||||||
@ -264,49 +245,31 @@ static void list_vulkan_instance_layers(void)
|
|||||||
|
|
||||||
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
|
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
|
||||||
{
|
{
|
||||||
uint32_t i, ep_count;
|
|
||||||
VkExtensionProperties* ep;
|
|
||||||
|
|
||||||
printf("Vulkan device extensions:\n");
|
printf("Vulkan device extensions:\n");
|
||||||
|
|
||||||
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS)
|
uint32_t ep_count;
|
||||||
return;
|
vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL);
|
||||||
|
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
||||||
|
vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep);
|
||||||
|
|
||||||
ep = calloc(ep_count, sizeof(VkExtensionProperties));
|
for (uint32_t i = 0; i < ep_count; i++)
|
||||||
|
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
|
||||||
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
free(ep);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ep_count; i++)
|
|
||||||
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
|
|
||||||
|
|
||||||
free(ep);
|
free(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device)
|
static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device)
|
||||||
{
|
{
|
||||||
uint32_t i, lp_count;
|
|
||||||
VkLayerProperties* lp;
|
|
||||||
|
|
||||||
printf("Vulkan device layers:\n");
|
printf("Vulkan device layers:\n");
|
||||||
|
|
||||||
if (vkEnumerateDeviceLayerProperties(device, &lp_count, NULL) != VK_SUCCESS)
|
uint32_t lp_count;
|
||||||
return;
|
vkEnumerateDeviceLayerProperties(device, &lp_count, NULL);
|
||||||
|
VkLayerProperties* lp = calloc(lp_count, sizeof(VkLayerProperties));
|
||||||
|
vkEnumerateDeviceLayerProperties(device, &lp_count, lp);
|
||||||
|
|
||||||
lp = calloc(lp_count, sizeof(VkLayerProperties));
|
for (uint32_t i = 0; i < lp_count; i++)
|
||||||
|
|
||||||
if (vkEnumerateDeviceLayerProperties(device, &lp_count, lp) != VK_SUCCESS)
|
|
||||||
{
|
{
|
||||||
free(lp);
|
printf(" %s (spec version %u) \"%s\"\n",
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < lp_count; i++)
|
|
||||||
{
|
|
||||||
printf(" %s (v%u) \"%s\"\n",
|
|
||||||
lp[i].layerName,
|
lp[i].layerName,
|
||||||
lp[i].specVersion >> 22,
|
lp[i].specVersion >> 22,
|
||||||
lp[i].description);
|
lp[i].description);
|
||||||
@ -352,13 +315,11 @@ static GLADapiproc glad_vulkan_callback(const char* name, void* user)
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int ch, client, major, minor, revision, profile;
|
int ch;
|
||||||
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
bool list_extensions = false, list_layers = false;
|
||||||
int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
|
|
||||||
GLenum error;
|
|
||||||
GLFWwindow* window;
|
|
||||||
|
|
||||||
enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP,
|
||||||
|
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,
|
||||||
@ -369,7 +330,7 @@ int main(int argc, char** argv)
|
|||||||
{ "behavior", 1, NULL, BEHAVIOR },
|
{ "behavior", 1, NULL, BEHAVIOR },
|
||||||
{ "client-api", 1, NULL, CLIENT },
|
{ "client-api", 1, NULL, CLIENT },
|
||||||
{ "context-api", 1, NULL, CONTEXT },
|
{ "context-api", 1, NULL, CONTEXT },
|
||||||
{ "debug", 0, NULL, DEBUG },
|
{ "debug", 0, NULL, DEBUG_CONTEXT },
|
||||||
{ "forward", 0, NULL, FORWARD },
|
{ "forward", 0, NULL, FORWARD },
|
||||||
{ "help", 0, NULL, HELP },
|
{ "help", 0, NULL, HELP },
|
||||||
{ "list-extensions", 0, NULL, EXTENSIONS },
|
{ "list-extensions", 0, NULL, EXTENSIONS },
|
||||||
@ -460,7 +421,7 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case DEBUG:
|
case DEBUG_CONTEXT:
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -623,7 +584,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
|
|
||||||
window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@ -633,17 +594,17 @@ int main(int argc, char** argv)
|
|||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
|
|
||||||
error = glGetError();
|
const GLenum error = glGetError();
|
||||||
if (error != GL_NO_ERROR)
|
if (error != GL_NO_ERROR)
|
||||||
printf("*** OpenGL error after make current: 0x%08x ***\n", error);
|
printf("*** OpenGL error after make current: 0x%08x ***\n", error);
|
||||||
|
|
||||||
// Report client API version
|
// Report client API version
|
||||||
|
|
||||||
client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
const int client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
||||||
major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
const int major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
||||||
minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
const int minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
||||||
revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
|
const int revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
|
||||||
profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
const int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
||||||
|
|
||||||
printf("%s context version string: \"%s\"\n",
|
printf("%s context version string: \"%s\"\n",
|
||||||
get_api_name(client),
|
get_api_name(client),
|
||||||
@ -735,6 +696,8 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
printf("%s framebuffer:\n", get_api_name(client));
|
printf("%s framebuffer:\n", get_api_name(client));
|
||||||
|
|
||||||
|
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
||||||
|
|
||||||
if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
{
|
{
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
@ -809,21 +772,28 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (glfwVulkanSupported())
|
if (glfwVulkanSupported())
|
||||||
{
|
{
|
||||||
uint32_t i, re_count, pd_count;
|
|
||||||
const char** re;
|
|
||||||
VkApplicationInfo ai = {0};
|
|
||||||
VkInstanceCreateInfo ici = {0};
|
|
||||||
VkInstance instance;
|
|
||||||
VkPhysicalDevice* pd;
|
|
||||||
|
|
||||||
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL);
|
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL);
|
||||||
|
|
||||||
re = glfwGetRequiredInstanceExtensions(&re_count);
|
uint32_t loader_version = VK_API_VERSION_1_0;
|
||||||
|
|
||||||
|
if (vkEnumerateInstanceVersion)
|
||||||
|
{
|
||||||
|
uint32_t version;
|
||||||
|
if (vkEnumerateInstanceVersion(&version) == VK_SUCCESS)
|
||||||
|
loader_version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Vulkan loader API version: %i.%i\n",
|
||||||
|
VK_VERSION_MAJOR(loader_version),
|
||||||
|
VK_VERSION_MINOR(loader_version));
|
||||||
|
|
||||||
|
uint32_t re_count;
|
||||||
|
const char** re = glfwGetRequiredInstanceExtensions(&re_count);
|
||||||
|
|
||||||
printf("Vulkan required instance extensions:");
|
printf("Vulkan required instance extensions:");
|
||||||
if (re)
|
if (re)
|
||||||
{
|
{
|
||||||
for (i = 0; i < re_count; i++)
|
for (uint32_t i = 0; i < re_count; i++)
|
||||||
printf(" %s", re[i]);
|
printf(" %s", re[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
@ -836,18 +806,24 @@ int main(int argc, char** argv)
|
|||||||
if (list_layers)
|
if (list_layers)
|
||||||
list_vulkan_instance_layers();
|
list_vulkan_instance_layers();
|
||||||
|
|
||||||
ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
VkApplicationInfo ai = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
|
||||||
ai.pApplicationName = "glfwinfo";
|
ai.pApplicationName = "glfwinfo";
|
||||||
ai.applicationVersion = GLFW_VERSION_MAJOR;
|
ai.applicationVersion = VK_MAKE_VERSION(GLFW_VERSION_MAJOR,
|
||||||
ai.pEngineName = "GLFW";
|
GLFW_VERSION_MINOR,
|
||||||
ai.engineVersion = GLFW_VERSION_MAJOR;
|
GLFW_VERSION_REVISION);
|
||||||
ai.apiVersion = VK_API_VERSION_1_0;
|
|
||||||
|
|
||||||
ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
if (loader_version >= VK_API_VERSION_1_1)
|
||||||
|
ai.apiVersion = VK_API_VERSION_1_1;
|
||||||
|
else
|
||||||
|
ai.apiVersion = VK_API_VERSION_1_0;
|
||||||
|
|
||||||
|
VkInstanceCreateInfo ici = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
|
||||||
ici.pApplicationInfo = &ai;
|
ici.pApplicationInfo = &ai;
|
||||||
ici.enabledExtensionCount = re_count;
|
ici.enabledExtensionCount = re_count;
|
||||||
ici.ppEnabledExtensionNames = re;
|
ici.ppEnabledExtensionNames = re;
|
||||||
|
|
||||||
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
|
|
||||||
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
|
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@ -856,32 +832,22 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, instance);
|
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, instance);
|
||||||
|
|
||||||
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
|
uint32_t pd_count;
|
||||||
{
|
vkEnumeratePhysicalDevices(instance, &pd_count, NULL);
|
||||||
vkDestroyInstance(instance, NULL);
|
VkPhysicalDevice* pd = calloc(pd_count, sizeof(VkPhysicalDevice));
|
||||||
glfwTerminate();
|
vkEnumeratePhysicalDevices(instance, &pd_count, pd);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
pd = calloc(pd_count, sizeof(VkPhysicalDevice));
|
for (uint32_t i = 0; i < pd_count; i++)
|
||||||
|
|
||||||
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
free(pd);
|
|
||||||
vkDestroyInstance(instance, NULL);
|
|
||||||
glfwTerminate();
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < pd_count; i++)
|
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceProperties pdp;
|
VkPhysicalDeviceProperties pdp;
|
||||||
|
|
||||||
vkGetPhysicalDeviceProperties(pd[i], &pdp);
|
vkGetPhysicalDeviceProperties(pd[i], &pdp);
|
||||||
|
|
||||||
printf("Vulkan %s device: \"%s\"\n",
|
printf("Vulkan %s device: \"%s\" (API version %i.%i)\n",
|
||||||
get_device_type_name(pdp.deviceType),
|
get_device_type_name(pdp.deviceType),
|
||||||
pdp.deviceName);
|
pdp.deviceName,
|
||||||
|
VK_VERSION_MAJOR(pdp.apiVersion),
|
||||||
|
VK_VERSION_MINOR(pdp.apiVersion));
|
||||||
|
|
||||||
if (list_extensions)
|
if (list_extensions)
|
||||||
list_vulkan_device_extensions(instance, pd[i]);
|
list_vulkan_device_extensions(instance, pd[i]);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#define NK_IMPLEMENTATION
|
#define NK_IMPLEMENTATION
|
||||||
@ -201,6 +202,7 @@ int main(int argc, char** argv)
|
|||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
|
||||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL);
|
window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#define NK_IMPLEMENTATION
|
#define NK_IMPLEMENTATION
|
||||||
@ -85,7 +86,7 @@ static void joystick_callback(int jid, int event)
|
|||||||
glfwRequestWindowAttention(window);
|
glfwRequestWindowAttention(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drop_callback(GLFWwindow* window, int count, const char** paths)
|
static void drop_callback(GLFWwindow* window, int count, const char* paths[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -181,6 +182,7 @@ int main(void)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
glfwWindowHint(GLFW_WIN32_KEYBOARD_MENU, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(800, 600, "Joystick Test", NULL, NULL);
|
window = glfwCreateWindow(800, 600, "Joystick Test", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user