Merge remote-tracking branch 'upstream/master'

This commit is contained in:
robbin.marcus 2022-09-24 13:44:19 +02:00
commit d966c0c3e6
155 changed files with 28153 additions and 15003 deletions

View File

@ -1,20 +1,44 @@
image:
- Visual Studio 2015
branches: branches:
only: only:
- ci - ci
- master - master
- latest
- 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
matrix: matrix:
fast_finish: true fast_finish: true
build_script: for:
- mkdir build -
- cd build matrix:
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% .. only:
- cmake --build . - GENERATOR: MinGW Makefiles
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:

10
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,10 @@
* @elmindreda
src/wl_* @linkmauve
docs/*.css @glfw/webdev
docs/*.scss @glfw/webdev
docs/*.html @glfw/webdev
docs/*.xml @glfw/webdev

93
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,93 @@
name: Build
on:
pull_request:
push:
branches: [ ci, master, latest, 3.3-stable ]
permissions:
statuses: write
contents: read
jobs:
build-linux-x11-clang:
name: X11 (Linux, Clang)
runs-on: ubuntu-latest
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update
sudo apt install libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev
- name: Configure static library
run: cmake -S . -B build-static
- name: Build static library
run: cmake --build build-static --parallel
- name: Configure shared library
run: cmake -S . -B build-shared -D BUILD_SHARED_LIBS=ON
- name: Build shared library
run: cmake --build build-shared --parallel
build-linux-full-clang:
name: X11+Wayland (Linux, Clang)
runs-on: ubuntu-latest
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update
sudo apt install libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev wayland-protocols libwayland-dev libxkbcommon-dev
- name: Configure static library
run: cmake -S . -B build-static -D GLFW_BUILD_WAYLAND=ON
- name: Build static library
run: cmake --build build-static --parallel
- name: Configure shared library
run: cmake -S . -B build-shared -D GLFW_BUILD_WAYLAND=ON -D BUILD_SHARED_LIBS=ON
- name: Build shared library
run: cmake --build build-shared --parallel
build-macos-cocoa-clang:
name: Cocoa (macOS, Clang)
runs-on: macos-latest
env:
CFLAGS: -Werror
MACOSX_DEPLOYMENT_TARGET: 10.8
steps:
- uses: actions/checkout@v2
- name: Configure static library
run: cmake -S . -B build-static
- name: Build static library
run: cmake --build build-static --parallel
- name: Configure shared library
run: cmake -S . -B build-shared -D BUILD_SHARED_LIBS=ON
- name: Build shared library
run: cmake --build build-shared --parallel
build-windows-win32-vs2022:
name: Win32 (Windows, VS2022)
runs-on: windows-latest
env:
CFLAGS: /WX
steps:
- uses: actions/checkout@v2
- name: Configure static library
run: cmake -S . -B build-static -G "Visual Studio 17 2022"
- name: Build static library
run: cmake --build build-static --parallel
- name: Configure shared library
run: cmake -S . -B build-shared -G "Visual Studio 17 2022" -D BUILD_SHARED_LIBS=ON
- name: Build shared library
run: cmake --build build-shared --parallel

42
.gitignore vendored
View File

@ -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
@ -33,10 +52,6 @@ src/glfw_config.h
src/glfw3.pc src/glfw3.pc
src/glfw3Config.cmake src/glfw3Config.cmake
src/glfw3ConfigVersion.cmake src/glfw3ConfigVersion.cmake
src/wayland-pointer-constraints-unstable-v1-client-protocol.h
src/wayland-pointer-constraints-unstable-v1-protocol.c
src/wayland-relative-pointer-unstable-v1-client-protocol.h
src/wayland-relative-pointer-unstable-v1-protocol.c
# Compiled binaries # Compiled binaries
src/libglfw.so src/libglfw.so
@ -60,8 +75,9 @@ examples/offscreen
examples/particles examples/particles
examples/splitview examples/splitview
examples/sharing examples/sharing
examples/simple examples/triangle-opengl
examples/wave examples/wave
examples/windows
tests/*.app tests/*.app
tests/*.exe tests/*.exe
tests/clipboard tests/clipboard
@ -72,6 +88,7 @@ tests/gamma
tests/glfwinfo tests/glfwinfo
tests/icon tests/icon
tests/iconify tests/iconify
tests/inputlag
tests/joysticks tests/joysticks
tests/monitors tests/monitors
tests/msaa tests/msaa
@ -80,6 +97,7 @@ tests/tearing
tests/threads tests/threads
tests/timeout tests/timeout
tests/title tests/title
tests/vulkan tests/triangle-vulkan
tests/window
tests/windows tests/windows

10
.mailmap Normal file
View 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>

View File

@ -1,78 +0,0 @@
language: c
compiler: clang
branches:
only:
- ci
- master
sudo: false
dist: trusty
addons:
apt:
packages:
- cmake
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxi-dev
matrix:
include:
- os: linux
env:
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- os: linux
env:
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
- os: linux
sudo: required
addons:
apt:
packages:
- libwayland-dev
- libxkbcommon-dev
- libegl1-mesa-dev
env:
- USE_WAYLAND=ON
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- os: linux
sudo: required
addons:
apt:
packages:
- libwayland-dev
- libxkbcommon-dev
- libegl1-mesa-dev
env:
- USE_WAYLAND=ON
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
- os: osx
env:
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- os: osx
env:
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
script:
- if grep -Inr '\s$' src include docs tests examples CMake *.md .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
- mkdir build
- cd build
- if test -n "${USE_WAYLAND}";
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;
pushd wayland-protocols;
git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install;
popd;
fi
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} ..
- cmake --build .
notifications:
email:
recipients:
- ci@glfw.org
on_success: never
on_failure: always

View File

@ -23,8 +23,23 @@ endif()
file(STRINGS "${source_path}" lines) file(STRINGS "${source_path}" lines)
foreach(line ${lines}) foreach(line ${lines})
if ("${line}" MATCHES "^[0-9a-fA-F].*$") if (line MATCHES "^[0-9a-fA-F]")
set(GLFW_GAMEPAD_MAPPINGS "${GLFW_GAMEPAD_MAPPINGS}\"${line}\",\n") if (line MATCHES "platform:Windows")
if (GLFW_WIN32_MAPPINGS)
string(APPEND GLFW_WIN32_MAPPINGS "\n")
endif()
string(APPEND GLFW_WIN32_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Mac OS X")
if (GLFW_COCOA_MAPPINGS)
string(APPEND GLFW_COCOA_MAPPINGS "\n")
endif()
string(APPEND GLFW_COCOA_MAPPINGS "\"${line}\",")
elseif (line MATCHES "platform:Linux")
if (GLFW_LINUX_MAPPINGS)
string(APPEND GLFW_LINUX_MAPPINGS "\n")
endif()
string(APPEND GLFW_LINUX_MAPPINGS "\"${line}\",")
endif()
endif() endif()
endforeach() endforeach()

View File

@ -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})

View File

@ -5,9 +5,9 @@ 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_CONFIG_REQUIRES_PRIVATE@
Libs: -L${libdir} -l@GLFW_LIB_NAME@ Libs: -L${libdir} -l@GLFW_LIB_NAME@
Libs.private: @GLFW_PKG_LIBS@ Libs.private: @GLFW_PKG_CONFIG_LIBS_PRIVATE@
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -0,0 +1,3 @@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")

View File

@ -13,5 +13,5 @@ if (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
endif (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES) endif (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(EPOLLSHIM DEFAULT_MSG EPOLLSHIM_LIBRARIES EPOLLSHIM_INCLUDE_DIRS) find_package_handle_standard_args(EpollShim DEFAULT_MSG EPOLLSHIM_LIBRARIES EPOLLSHIM_INCLUDE_DIRS)
mark_as_advanced(EPOLLSHIM_INCLUDE_DIRS EPOLLSHIM_LIBRARIES) mark_as_advanced(EPOLLSHIM_INCLUDE_DIRS EPOLLSHIM_LIBRARIES)

View File

@ -1,26 +0,0 @@
find_package(PkgConfig)
pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION})
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols
OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR
RESULT_VARIABLE _pkgconfig_failed)
if (_pkgconfig_failed)
message(FATAL_ERROR "Missing wayland-protocols pkgdatadir")
endif()
string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}")
find_package_handle_standard_args(WaylandProtocols
FOUND_VAR
WaylandProtocols_FOUND
REQUIRED_VARS
WaylandProtocols_PKGDATADIR
VERSION_VAR
WaylandProtocols_VERSION
HANDLE_COMPONENTS
)
set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND})
set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR})
set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION})

View File

@ -1,34 +0,0 @@
# - Try to find XKBCommon
# Once done, this will define
#
# XKBCOMMON_FOUND - System has XKBCommon
# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories
# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon
# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon
find_package(PkgConfig)
pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon)
set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER})
find_path(XKBCOMMON_INCLUDE_DIR
NAMES xkbcommon/xkbcommon.h
HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS}
)
find_library(XKBCOMMON_LIBRARY
NAMES xkbcommon
HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS}
)
set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY})
set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS})
set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(XKBCommon DEFAULT_MSG
XKBCOMMON_LIBRARY
XKBCOMMON_INCLUDE_DIR
)
mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR)

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.4...3.20 FATAL_ERROR)
project(GLFW C) project(GLFW VERSION 3.4.0 LANGUAGES C)
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF) set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
@ -8,58 +8,55 @@ if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0054 NEW)
endif() endif()
set(GLFW_VERSION_MAJOR "3") if (POLICY CMP0069)
set(GLFW_VERSION_MINOR "4") cmake_policy(SET CMP0069 NEW)
set(GLFW_VERSION_PATCH "0") endif()
set(GLFW_VERSION_EXTRA "")
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") if (POLICY CMP0077)
set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") cmake_policy(SET CMP0077 NEW)
endif()
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)
include(GNUInstallDirs) include(GNUInstallDirs)
include(CMakeDependentOption)
if (UNIX) if (GLFW_USE_OSMESA)
option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF) message(FATAL_ERROR "GLFW_USE_OSMESA has been removed; set the GLFW_PLATFORM init hint")
endif() endif()
if (WIN32) cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF)
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF) cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF)
endif() cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland"
"${GLFW_USE_WAYLAND}" "UNIX;NOT APPLE" OFF)
if (UNIX AND NOT APPLE) cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF) "WIN32" OFF)
endif() cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
"MSVC" OFF)
if (MSVC) set(GLFW_LIBRARY_TYPE "${GLFW_LIBRARY_TYPE}" CACHE STRING
option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON) "Library type override for GLFW (SHARED, STATIC, OBJECT, or empty to follow BUILD_SHARED_LIBS)")
endif()
if (BUILD_SHARED_LIBS) if (GLFW_LIBRARY_TYPE)
set(_GLFW_BUILD_DLL 1) if (GLFW_LIBRARY_TYPE STREQUAL "SHARED")
endif() set(GLFW_BUILD_SHARED_LIBRARY TRUE)
else()
if (BUILD_SHARED_LIBS AND UNIX) set(GLFW_BUILD_SHARED_LIBRARY FALSE)
# On Unix-like systems, shared libraries can use the soname system.
set(GLFW_LIB_NAME glfw)
else()
set(GLFW_LIB_NAME glfw3)
endif()
if (GLFW_VULKAN_STATIC)
if (BUILD_SHARED_LIBS)
# If you absolutely must do this, remove this line and add the Vulkan
# loader static library via the CMAKE_SHARED_LINKER_FLAGS
message(FATAL_ERROR "You are trying to link the Vulkan loader static library into the GLFW shared library")
endif() endif()
set(_GLFW_VULKAN_STATIC 1) else()
set(GLFW_BUILD_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
endif() endif()
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
@ -72,243 +69,46 @@ if (GLFW_BUILD_DOCS)
endif() endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Set compiler specific flags # Report backend selection
#-------------------------------------------------------------------- #--------------------------------------------------------------------
if (MSVC) if (GLFW_BUILD_WIN32)
if (MSVC90) message(STATUS "Including Win32 support")
# Workaround for VS 2008 not shipping with the DirectX 9 SDK endif()
include(CheckIncludeFile) if (GLFW_BUILD_COCOA)
check_include_file(dinput.h DINPUT_H_FOUND) message(STATUS "Including Cocoa support")
if (NOT DINPUT_H_FOUND) endif()
message(FATAL_ERROR "DirectX 9 SDK not found") if (GLFW_BUILD_WAYLAND)
endif() message(STATUS "Including Wayland support")
# Workaround for VS 2008 not shipping with stdint.h endif()
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008") if (GLFW_BUILD_X11)
endif() message(STATUS "Including X11 support")
endif()
if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) #--------------------------------------------------------------------
# Apply Microsoft C runtime library option
# This is here because it also applies to tests and examples
#--------------------------------------------------------------------
if (MSVC AND NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
if (CMAKE_VERSION VERSION_LESS 3.15)
foreach (flag CMAKE_C_FLAGS foreach (flag CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELWITHDEBINFO) CMAKE_C_FLAGS_RELWITHDEBINFO)
if (${flag} MATCHES "/MD") if (flag MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}") string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
endif() endif()
if (${flag} MATCHES "/MDd") if (flag MATCHES "/MDd")
string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}") string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
endif() endif()
endforeach() endforeach()
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif() endif()
endif() endif()
if (MINGW)
# Workaround for legacy MinGW not providing XInput and DirectInput
include(CheckIncludeFile)
check_include_file(dinput.h DINPUT_H_FOUND)
check_include_file(xinput.h XINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw")
endif()
# Enable link-time exploit mitigation features enabled by default on MSVC
include(CheckCCompilerFlag)
# Compatibility with data execution prevention (DEP)
set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
check_c_compiler_flag("" _GLFW_HAS_DEP)
if (_GLFW_HAS_DEP)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}")
endif()
# Compatibility with address space layout randomization (ASLR)
set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
check_c_compiler_flag("" _GLFW_HAS_ASLR)
if (_GLFW_HAS_ASLR)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}")
endif()
# Compatibility with 64-bit address space layout randomization (ASLR)
set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
check_c_compiler_flag("" _GLFW_HAS_64ASLR)
if (_GLFW_HAS_64ASLR)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}")
endif()
endif()
#--------------------------------------------------------------------
# Detect and select backend APIs
#--------------------------------------------------------------------
if (GLFW_USE_WAYLAND)
set(_GLFW_WAYLAND 1)
message(STATUS "Using Wayland for window creation")
elseif (GLFW_USE_OSMESA)
set(_GLFW_OSMESA 1)
message(STATUS "Using OSMesa for headless context creation")
elseif (WIN32)
set(_GLFW_WIN32 1)
message(STATUS "Using Win32 for window creation")
elseif (APPLE)
set(_GLFW_COCOA 1)
message(STATUS "Using Cocoa for window creation")
elseif (UNIX)
set(_GLFW_X11 1)
message(STATUS "Using X11 for window creation")
else()
message(FATAL_ERROR "No supported platform was detected")
endif()
#--------------------------------------------------------------------
# Find and add Unix math and time libraries
#--------------------------------------------------------------------
if (UNIX AND NOT APPLE)
find_library(RT_LIBRARY rt)
mark_as_advanced(RT_LIBRARY)
if (RT_LIBRARY)
list(APPEND glfw_LIBRARIES "${RT_LIBRARY}")
list(APPEND glfw_PKG_LIBS "-lrt")
endif()
find_library(MATH_LIBRARY m)
mark_as_advanced(MATH_LIBRARY)
if (MATH_LIBRARY)
list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}")
list(APPEND glfw_PKG_LIBS "-lm")
endif()
if (CMAKE_DL_LIBS)
list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
endif()
endif()
#--------------------------------------------------------------------
# Use Win32 for window creation
#--------------------------------------------------------------------
if (_GLFW_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32")
if (GLFW_USE_HYBRID_HPG)
set(_GLFW_USE_HYBRID_HPG 1)
endif()
endif()
#--------------------------------------------------------------------
# Use X11 for window creation
#--------------------------------------------------------------------
if (_GLFW_X11)
find_package(X11 REQUIRED)
list(APPEND glfw_PKG_DEPS "x11")
# Set up library and include paths
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)
if (NOT X11_Xrandr_FOUND)
message(FATAL_ERROR "The RandR headers were not found")
endif()
# Check for Xinerama (legacy multi-monitor support)
if (NOT X11_Xinerama_FOUND)
message(FATAL_ERROR "The Xinerama headers were not found")
endif()
# Check for Xkb (X keyboard extension)
if (NOT X11_Xkb_FOUND)
message(FATAL_ERROR "The X keyboard extension headers were not found")
endif()
# Check for Xcursor (cursor creation from RGBA images)
if (NOT X11_Xcursor_FOUND)
message(FATAL_ERROR "The Xcursor headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
"${X11_Xinerama_INCLUDE_PATH}"
"${X11_Xkb_INCLUDE_PATH}"
"${X11_Xcursor_INCLUDE_PATH}")
endif()
#--------------------------------------------------------------------
# Use Wayland for window creation
#--------------------------------------------------------------------
if (_GLFW_WAYLAND)
find_package(ECM REQUIRED NO_MODULE)
list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
find_package(Wayland REQUIRED Client Cursor Egl)
find_package(WaylandScanner REQUIRED)
find_package(WaylandProtocols 1.15 REQUIRED)
list(APPEND glfw_PKG_DEPS "wayland-egl")
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
find_package(XKBCommon REQUIRED)
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
include(CheckIncludeFiles)
include(CheckFunctionExists)
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
find_package(EpollShim)
if (EPOLLSHIM_FOUND)
list(APPEND glfw_INCLUDE_DIRS "${EPOLLSHIM_INCLUDE_DIRS}")
list(APPEND glfw_LIBRARIES "${EPOLLSHIM_LIBRARIES}")
endif()
endif()
endif()
#--------------------------------------------------------------------
# Use OSMesa for offscreen context creation
#--------------------------------------------------------------------
if (_GLFW_OSMESA)
find_package(OSMesa REQUIRED)
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
endif()
#--------------------------------------------------------------------
# Use Cocoa for window creation and NSOpenGL for context creation
#--------------------------------------------------------------------
if (_GLFW_COCOA)
list(APPEND glfw_LIBRARIES
"-framework Cocoa"
"-framework IOKit"
"-framework CoreFoundation"
"-framework CoreVideo")
set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
endif()
#--------------------------------------------------------------------
# Add the Vulkan loader as a dependency if necessary
#--------------------------------------------------------------------
if (GLFW_VULKAN_STATIC)
list(APPEND glfw_PKG_DEPS "vulkan")
endif()
#--------------------------------------------------------------------
# Export GLFW library dependencies
#--------------------------------------------------------------------
foreach(arg ${glfw_PKG_DEPS})
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}")
endforeach()
foreach(arg ${glfw_PKG_LIBS})
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}")
endforeach()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Create generated files # Create generated files
#-------------------------------------------------------------------- #--------------------------------------------------------------------
@ -316,19 +116,15 @@ 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(src/glfw3.pc.in src/glfw3.pc @ONLY)
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Add subdirectories # Add subdirectories
#-------------------------------------------------------------------- #--------------------------------------------------------------------
@ -364,9 +160,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

265
CONTRIBUTORS.md Normal file
View File

@ -0,0 +1,265 @@
# Acknowledgements
GLFW exists because people around the world donated their time and lent their
skills. This list only includes contributions to the main repository and
excludes other invaluable contributions like language bindings and text and
video tutorials.
- Bobyshev Alexander
- Laurent Aphecetche
- Matt Arsenault
- ashishgamedev
- David Avedissian
- Luca Bacci
- Keith Bauer
- John Bartholomew
- Coşku Baş
- Niklas Behrens
- Andrew Belt
- Nevyn Bengtsson
- Niklas Bergström
- Denis Bernard
- BiBi
- Doug Binks
- blanco
- Waris Boonyasiriwat
- Kyle Brenneman
- Rok Breulj
- TheBrokenRail
- Kai Burjack
- Martin Capitanio
- Nicolas Caramelli
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- TheChocolateOre
- Ali Chraghi
- Joseph Chua
- Ian Clarkson
- Michał Cichoń
- Lambert Clara
- Anna Clarke
- Josh Codd
- Yaron Cohen-Tal
- Omar Cornut
- Andrew Corrigan
- Bailey Cosier
- Noel Cower
- CuriouserThing
- Jason Daly
- danhambleton
- Jarrod Davis
- Olivier Delannoy
- Paul R. Deppe
- Michael Dickens
- Роман Донченко
- Mario Dorn
- Wolfgang Draxinger
- Jonathan Dummer
- Ralph Eastwood
- Fredrik Ehnbom
- Robin Eklind
- Jan Ekström
- Siavash Eliasi
- Ahmad Fatoum
- Nikita Fediuchin
- Felipe Ferreira
- Michael Fogleman
- Jason Francis
- Gerald Franz
- Mário Freitas
- GeO4d
- Marcus Geelnard
- ghuser404
- Charles Giessen
- Ryan C. Gordon
- Stephen Gowen
- Kovid Goyal
- Kevin Grandemange
- Eloi Marín Gratacós
- Stefan Gustavson
- Andrew Gutekanst
- Stephen Gutekanst
- Jonathan Hale
- hdf89shfdfs
- Sylvain Hellegouarch
- Björn Hempel
- Matthew Henry
- heromyth
- Lucas Hinderberger
- Paul Holden
- Hajime Hoshi
- Warren Hu
- Charles Huber
- Brent Huisman
- illustris
- InKryption
- IntellectualKitty
- Aaron Jacobs
- JannikGM
- Erik S. V. Jansson
- jjYBdx4IL
- Toni Jovanoski
- Arseny Kapoulkine
- Cem Karan
- Osman Keskin
- Koray Kilinc
- Josh Kilmer
- Byunghoon Kim
- Cameron King
- Peter Knut
- Christoph Kubisch
- Yuri Kunde Schlesner
- Rokas Kupstys
- Konstantin Käfer
- Eric Larson
- Francis Lecavalier
- Jong Won Lee
- Robin Leffmann
- Glenn Lewis
- Shane Liesegang
- Anders Lindqvist
- Leon Linhart
- Marco Lizza
- Eyal Lotem
- Aaron Loucks
- Luflosi
- lukect
- Tristam MacDonald
- Hans Mackowiak
- Ramiro Magno
- Дмитри Малышев
- Zbigniew Mandziejewicz
- Adam Marcus
- Célestin Marot
- Kyle McDonald
- David V. McKay
- David Medlock
- Bryce Mehring
- Jonathan Mercier
- Marcel Metz
- Liam Middlebrook
- Ave Milia
- Jonathan Miller
- Kenneth Miller
- Bruce Mitchener
- Jack Moffitt
- Ravi Mohan
- Jeff Molofee
- Alexander Monakov
- Pierre Morel
- Jon Morton
- Pierre Moulon
- Martins Mozeiko
- Pascal Muetschard
- James Murphy
- Julian Møller
- ndogxj
- F. Nedelec
- n3rdopolis
- Kristian Nielsen
- Joel Niemelä
- Kamil Nowakowski
- onox
- Denis Ovod
- Ozzy
- Andri Pálsson
- luz paz
- Peoro
- Braden Pellett
- Christopher Pelloux
- Michael Pennington
- Arturo J. Pérez
- Vladimir Perminov
- Olivier Perret
- Anthony Pesch
- Orson Peters
- Emmanuel Gil Peyrot
- Cyril Pichard
- Pilzschaf
- Keith Pitt
- Stanislav Podgorskiy
- Konstantin Podsvirov
- Nathan Poirier
- Alexandre Pretyman
- Pablo Prietz
- przemekmirek
- pthom
- Martin Pulec
- Guillaume Racicot
- Christian Rauch
- Philip Rideout
- Eddie Ringle
- Max Risuhin
- Joe Roback
- Jorge Rodriguez
- Jari Ronkainen
- Luca Rood
- Ed Ropple
- Aleksey Rybalkin
- Mikko Rytkönen
- Riku Salminen
- Brandon Schaefer
- Sebastian Schuberth
- Christian Sdunek
- Matt Sealey
- Steve Sexton
- Arkady Shapkin
- Ali Sherief
- Yoshiki Shibukawa
- Dmitri Shuralyov
- Joao da Silva
- Daniel Sieger
- Daniel Skorupski
- Slemmie
- Anthony Smith
- Bradley Smith
- Cliff Smolinsky
- Patrick Snape
- Erlend Sogge Heggen
- Olivier Sohn
- Julian Squires
- Johannes Stein
- Pontus Stenetorp
- Michael Stocker
- Justin Stoecker
- Elviss Strazdins
- Paul Sultana
- Nathan Sweet
- TTK-Bandit
- Jared Tiala
- Sergey Tikhomirov
- Arthur Tombs
- TronicLabs
- Ioannis Tsakpinis
- Samuli Tuomola
- Matthew Turner
- urraka
- Elias Vanderstuyft
- Stef Velzel
- Jari Vetoniemi
- Ricardo Vieira
- Nicholas Vitovitch
- Simon Voordouw
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Xo Wang
- Andre Weissflog
- Jay Weisskopf
- Frank Wille
- Andy Williams
- Joel Winarske
- Richard A. Wilkes
- Tatsuya Yatagawa
- Ryogo Yoshimura
- Lukas Zanner
- Andrey Zholos
- Aihui Zhu
- Santi Zupancic
- Jonas Ådahl
- Lasse Öörni
- Leonard König
- All the unmentioned and anonymous contributors in the GLFW community, for bug
reports, patches, feedback, testing and encouragement

View File

@ -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

676
README.md
View File

@ -1,6 +1,6 @@
# GLFW # GLFW
[![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw) [![Build status](https://github.com/glfw/glfw/actions/workflows/build.yml/badge.svg)](https://github.com/glfw/glfw/actions)
[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw) [![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw)
[![Coverity Scan](https://scan.coverity.com/projects/4884/badge.svg)](https://scan.coverity.com/projects/glfw-glfw) [![Coverity Scan](https://scan.coverity.com/projects/4884/badge.svg)](https://scan.coverity.com/projects/glfw-glfw)
@ -11,21 +11,21 @@ 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](https://www.glfw.org/license.html).
You can [download](http://www.glfw.org/download.html) the latest stable release You can [download](https://www.glfw.org/download.html) the latest stable release
as source or Windows binaries, or fetch the `latest` branch from GitHub. Each as source or Windows binaries, or fetch the `latest` branch from GitHub. Each
release starting with 3.0 also has a corresponding [annotated release starting with 3.0 also has a corresponding [annotated
tag](https://github.com/glfw/glfw/releases) with source and binary archives. tag](https://github.com/glfw/glfw/releases) with source and binary archives.
The [documentation](http://www.glfw.org/docs/latest/) is available online and is The [documentation](https://www.glfw.org/docs/latest/) is available online and is
included in all source and binary archives. See the [release included in all source and binary archives. See the [release
notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and
deprecations in the latest release. For more details see the [version deprecations in the latest release. For more details see the [version
history](http://www.glfw.org/changelog.html). history](https://www.glfw.org/changelog.html).
The `master` branch is the stable integration branch and _should_ always compile The `master` branch is the stable integration branch and _should_ always compile
and run on all supported platforms, although details of newly added features may and run on all supported platforms, although details of newly added features may
@ -34,11 +34,16 @@ fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
they are stable enough to merge. they are stable enough to merge.
If you are new to GLFW, you may find the If you are new to GLFW, you may find the
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If [tutorial](https://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
you have used GLFW 2 in the past, there is a [transition you have used GLFW 2 in the past, there is a [transition
guide](http://www.glfw.org/docs/latest/moving.html) for moving to the GLFW guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
3 API. 3 API.
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
around the world, whether by reporting bugs, providing community support, adding
features, reviewing or testing code, debugging, proofreading docs, suggesting
features or fixing bugs.
## Compiling GLFW ## Compiling GLFW
@ -52,16 +57,16 @@ MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
and Clang. It will likely compile in other environments as well, but this is and Clang. It will likely compile in other environments as well, but this is
not regularly tested. not regularly tested.
There are [pre-compiled Windows binaries](http://www.glfw.org/download.html) There are [pre-compiled Windows binaries](https://www.glfw.org/download.html)
available for all supported compilers. available for all supported compilers.
See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) for See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
more information about how to compile GLFW yourself. more information about how to compile GLFW yourself.
## Using GLFW ## Using GLFW
See the [documentation](http://www.glfw.org/docs/latest/) for tutorials, guides See the [documentation](https://www.glfw.org/docs/latest/) for tutorials, guides
and the API reference. and the API reference.
@ -79,16 +84,14 @@ Unix-like systems running the X Window System are supported even without
a desktop environment or modern extensions, although some features require a desktop environment or modern extensions, although some features require
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3. a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html) See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html)
in the documentation for more information. 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`
package, which is used to generated 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.
@ -101,10 +104,10 @@ located in the `deps/` directory.
functions functions
- [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in - [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
examples examples
- [Nuklear](https://github.com/vurtun/nuklear) for test and example UI - [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk - [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can The documentation is generated with [Doxygen](https://doxygen.org/) if CMake can
find that tool. find that tool.
@ -118,189 +121,295 @@ information on what to include when reporting a bug.
## Changelog ## Changelog
- Added `glfwGetError` function for querying the last error code and its
description (#970)
- Added `glfwUpdateGamepadMappings` function for importing gamepad mappings in
SDL\_GameControllerDB format (#900)
- Added `glfwJoystickIsGamepad` function for querying whether a joystick has
a gamepad mapping (#900)
- Added `glfwGetJoystickGUID` function for querying the SDL compatible GUID of
a joystick (#900)
- Added `glfwGetGamepadName` function for querying the name provided by the
gamepad mapping (#900)
- Added `glfwGetGamepadState` function, `GLFW_GAMEPAD_*` and `GLFWgamepadstate`
for retrieving gamepad input state (#900)
- Added `glfwGetWindowContentScale`, `glfwGetMonitorContentScale` and
`glfwSetWindowContentScaleCallback` for DPI-aware rendering
(#235,#439,#677,#845,#898)
- Added `glfwRequestWindowAttention` function for requesting attention from the
user (#732,#988)
- Added `glfwDragWindow` function for starting a drag operation on a window
(#987)
- Added `glfwResizeWindow` function for starting a resize operation on a window
(#923)
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
scancodes for keys (#830)
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
receiving window maximization events (#778)
- Added `glfwSetWindowAttrib` function for changing window attributes (#537)
- Added `glfwGetJoystickHats` function for querying joystick hats
(#889,#906,#934)
- Added `glfwInitHint` for setting initialization hints
- Added `glfwWindowHintString` for setting string type window hints (#893,#1139)
- Added `glfwGetWindowOpacity` and `glfwSetWindowOpacity` for controlling whole
window transparency (#1089)
- Added `glfwSetMonitorUserPointer` and `glfwGetMonitorUserPointer` for
per-monitor user pointers
- Added `glfwSetJoystickUserPointer` and `glfwGetJoystickUserPointer` for
per-joystick user pointers
- Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString`
functions for accessing X11 primary selection (#894,#1056)
- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
- Added definition of `GLAPIENTRY` to public header
- Added `GLFW_TRANSPARENT_FRAMEBUFFER` window hint and attribute for controlling
per-pixel framebuffer transparency (#197,#663,#715,#723,#1078)
- Added `GLFW_HOVERED` window attribute for polling cursor hover state (#1166)
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
(#749,#842)
- Added `GLFW_FOCUS_ON_SHOW` window hint and attribute to control input focus
on calling show window (#1189)
- Added `GLFW_SCALE_TO_MONITOR` window hint for automatic window resizing
(#676,#1115)
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
- Added macOS specific `GLFW_COCOA_FRAME_NAME` window hint (#195)
- Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935)
- Added macOS specific `GLFW_COCOA_CHDIR_RESOURCES` init hint
- Added macOS specific `GLFW_COCOA_MENUBAR` init hint
- Added X11 specific `GLFW_X11_CLASS_NAME` and `GLFW_X11_INSTANCE_NAME` window
hints (#893,#1139)
- Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
- Added `GenerateMappings.cmake` script for updating gamepad mappings
- Made `glfwCreateWindowSurface` emit an error when the window has a context
(#1194,#1205)
- Deprecated window parameter of clipboard string functions
- Deprecated charmods callback
- Removed `GLFW_USE_RETINA` compile-time option
- Removed `GLFW_USE_CHDIR` compile-time option
- Removed `GLFW_USE_MENUBAR` compile-time option
- Removed requirement of at least one window for `glfwWaitEvents` and
`glfwPostEmptyEvent` (#1317)
- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
OpenGL and OpenGL ES header macros
- Bugfix: `glfwGetInstanceProcAddress` returned `NULL` for
`vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
- Bugfix: The scancode for synthetic key release events was always zero
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor
ramp size (#1387,#1388)
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
- [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861)
- [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910)
- [Win32] Bugfix: Bitness test in `FindVulkan.cmake` was VS specific (#928)
- [Win32] Bugfix: `glfwVulkanSupported` emitted an error on systems with
a loader but no ICD (#916)
- [Win32] Bugfix: Non-iconified full sreeen windows did not prevent screen
blanking or password enabled screensavers (#851)
- [Win32] Bugfix: Mouse capture logic lost secondary release messages (#954)
- [Win32] Bugfix: The 32-bit Vulkan loader library static was not searched for
- [Win32] Bugfix: Vulkan libraries have a new path as of SDK 1.0.42.0 (#956)
- [Win32] Bugfix: Monitors with no display devices were not enumerated (#960)
- [Win32] Bugfix: Monitor events were not emitted (#784)
- [Win32] Bugfix: The Cygwin DLL was installed to the wrong directory (#1035)
- [Win32] Bugfix: Normalization of axis data via XInput was incorrect (#1045)
- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
(#650,#1071)
- [Win32] Bugfix: Returned key names did not match other platforms (#943)
- [Win32] Bugfix: Undecorated windows did not maximize to workarea (#899)
- [Win32] Bugfix: Window was resized twice when entering full screen (#1085)
- [Win32] Bugfix: The HID device notification was not unregistered (#1170)
- [Win32] Bugfix: `glfwCreateWindow` activated window even with `GLFW_FOCUSED`
hint set to false (#1179,#1180)
- [Win32] Bugfix: The keypad equals key was reported as `GLFW_KEY_UNKNOWN`
(#1315,#1316)
- [Win32] Bugfix: A title bar would be drawn over undecorated windows in some
circumstances (#1383)
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
- [X11] Bugfix: Dynamic X11 library loading did not use full sonames (#941)
- [X11] Bugfix: Window creation on 64-bit would read past top of stack (#951)
- [X11] Bugfix: XDND support had multiple non-conformance issues (#968)
- [X11] Bugfix: The RandR monitor path was disabled despite working RandR (#972)
- [X11] Bugfix: IM-duplicated key events would leak at low polling rates (#747)
- [X11] Bugfix: Gamma ramp setting via RandR did not validate ramp size
- [X11] Bugfix: Key name string encoding depended on current locale (#981,#983)
- [X11] Bugfix: Incremental reading of selections was not supported (#275)
- [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT`
- [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8
- [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display
- [X11] Bugfix: Checking window maximized attrib could crash some WMs (#1356)
- [X11] Bugfix: Update cursor position on enter event (#1366)
- [X11] Bugfix: `glfwSetWindowMonitor` did not update hints when resizing
non-user-resizable windows
- [X11] Bugfix: `glfwSetWindowMonitor` did not flush output buffer in some cases
- [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel
headers (#1196)
- [Linux] Moved to evdev for joystick input (#906,#1005)
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
- [Linux] Bugfix: `glfwInit` would fail if inotify creation failed (#833)
- [Linux] Bugfix: `strdup` was used without any required feature macro (#1055)
- [Cocoa] Added support for Vulkan window surface creation via
[MoltenVK](https://moltengl.com/moltenvk/) (#870)
- [Cocoa] Added support for loading a `MainMenu.nib` when available
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
- [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function
(#165,#192,#508,#511)
- [Cocoa] Bugfix: Disabled use of deprecated `CGDisplayModeCopyPixelEncoding`
function on macOS 10.12+
- [Cocoa] Bugfix: Running in AppSandbox would emit warnings (#816,#882)
- [Cocoa] Bugfix: Windows created after the first were not cascaded (#195)
- [Cocoa] Bugfix: Leaving video mode with `glfwSetWindowMonitor` would set
incorrect position and size (#748)
- [Cocoa] Bugfix: Iconified full screen windows could not be restored (#848)
- [Cocoa] Bugfix: Value range was ignored for joystick hats and buttons (#888)
- [Cocoa] Bugfix: Full screen framebuffer was incorrectly sized for some video
modes (#682)
- [Cocoa] Bugfix: A string object for IME was updated non-idiomatically (#1050)
- [Cocoa] Bugfix: A hidden or disabled cursor would become visible when a user
notification was shown (#971,#1028)
- [Cocoa] Bugfix: Some characters did not repeat due to Press and Hold (#1010)
- [Cocoa] Bugfix: Window title was lost when full screen or undecorated (#1082)
- [Cocoa] Bugfix: Window was resized twice when entering full screen (#1085)
- [Cocoa] Bugfix: Duplicate size events were not filtered (#1085)
- [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218)
- [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14
(#1334,#1346)
- [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373)
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
- [WGL] Added support for `WGL_ARB_create_context_no_error`
- [GLX] Added support for `GLX_ARB_create_context_no_error`
- [GLX] Bugfix: Context creation could segfault if no GLXFBConfigs were
available (#1040)
- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
- [EGL] Added support for `EGL_KHR_context_flush_control`
- [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid
User-visible changes since the last release. User-visible changes since the last release.
- Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958)
- Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
`GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to
specify the desired platform (#1958)
- Added `glfwGetPlatform` function to query what platform was selected (#1655,#1958)
- Added `glfwPlatformSupported` function to query if a platform is supported
(#1655,#1958)
- Added `glfwInitAllocator` for setting a custom memory allocator (#544,#1628,#1947)
- Added `GLFWallocator` struct and `GLFWallocatefun`, `GLFWreallocatefun` and
`GLFWdeallocatefun` types (#544,#1628,#1947)
- Added `glfwInitVulkanLoader` for using a non-default Vulkan loader (#1374,#1890)
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427)
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
- Added `GLFW_MOUSE_PASSTHROUGH` window hint for letting mouse input pass
through the window (#1236,#1568)
- Added `GLFW_CURSOR_CAPTURED` cursor mode to confine the cursor to the window
content area (#58)
- Added `GLFW_POSITION_X` and `GLFW_POSITION_Y` window hints for initial position
(#1603,#1747)
- Added `GLFW_ANY_POSITION` hint value for letting the window manager choose (#1603,#1747)
- Added `GLFW_PLATFORM_UNAVAILABLE` error for platform detection failures (#1958)
- Added `GLFW_FEATURE_UNAVAILABLE` error for platform limitations (#1692)
- Added `GLFW_FEATURE_UNIMPLEMENTED` error for incomplete backends (#1692)
- Added `GLFW_WAYLAND_APP_ID` window hint string for Wayland app\_id selection
(#2121,#2122)
- Added `GLFW_ANGLE_PLATFORM_TYPE` init hint and `GLFW_ANGLE_PLATFORM_TYPE_*`
values to select ANGLE backend (#1380)
- Added `GLFW_X11_XCB_VULKAN_SURFACE` init hint for selecting X11 Vulkan
surface extension (#1793)
- Added `GLFW_NATIVE_INCLUDE_NONE` for disabling inclusion of native headers (#1348)
- Added `GLFW_BUILD_WIN32` CMake option for enabling Win32 support (#1958)
- Added `GLFW_BUILD_COCOA` CMake option for enabling Cocoa support (#1958)
- Added `GLFW_BUILD_X11` CMake option for enabling X11 support (#1958)
- Added `GLFW_LIBRARY_TYPE` CMake variable for overriding the library type
(#279,#1307,#1497,#1574,#1928)
- Added `GLFW_PKG_CONFIG_REQUIRES_PRIVATE` and `GLFW_PKG_CONFIG_LIBS_PRIVATE` CMake
variables exposing pkg-config dependencies (#1307)
- Made joystick subsystem initialize at first use (#1284,#1646)
- Made `GLFW_DOUBLEBUFFER` a read-only window attribute
- Updated the minimum required CMake version to 3.1
- Updated gamepad mappings from upstream
- Disabled tests and examples by default when built as a CMake subdirectory
- Renamed `GLFW_USE_WAYLAND` CMake option to `GLFW_BUILD_WAYLAND` (#1958)
- Removed `GLFW_USE_OSMESA` CMake option enabling the Null platform (#1958)
- Removed CMake generated configuration header
- 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)
- Bugfix: Some extension loader headers did not prevent default OpenGL header
inclusion (#1695)
- Bugfix: Buffers were swapped at creation on single-buffered windows (#1873)
- Bugfix: Gamepad mapping updates could spam `GLFW_INVALID_VALUE` due to
incompatible controllers sharing hardware ID (#1763)
- Bugfix: Native access functions for context handles did not check that the API matched
- Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization
- Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization
- Bugfix: `glfwGetJoystickUserPointer` returned `NULL` during disconnection (#2092)
- [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] Made hidden helper window use its own window class
- [Win32] Disabled framebuffer transparency on Windows 7 when DWM windows are
opaque (#1512)
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
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)
- [Win32] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
- [Win32] Bugfix: Monitor functions could return invalid values after
configuration change (#1761)
- [Win32] Bugfix: Initialization would segfault on Windows 8 (not 8.1) (#1775)
- [Win32] Bugfix: Duplicate size events were not filtered (#1610)
- [Win32] Bugfix: Full screen windows were incorrectly resized by DPI changes
(#1582)
- [Win32] Bugfix: `GLFW_SCALE_TO_MONITOR` had no effect on systems older than
Windows 10 version 1703 (#1511)
- [Win32] Bugfix: `USE_MSVC_RUNTIME_LIBRARY_DLL` had no effect on CMake 3.15 or
later (#1783,#1796)
- [Win32] Bugfix: Compilation with LLVM for Windows failed (#1807,#1824,#1874)
- [Win32] Bugfix: The foreground lock timeout was overridden, ignoring the user
- [Win32] Bugfix: Content scale queries could fail silently (#1615)
- [Win32] Bugfix: Content scales could have garbage values if monitor was recently
disconnected (#1615)
- [Win32] Bugfix: A window created maximized and undecorated would cover the whole
monitor (#1806)
- [Win32] Bugfix: The default restored window position was lost when creating a maximized
window
- [Win32] Bugfix: `glfwMaximizeWindow` would make a hidden window visible
- [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different
scancode than `PrtSc` (#1993)
- [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not
match event scancode (#1993)
- [Win32] Bugfix: Instance-local operations used executable instance (#469,#1296,#1395)
- [Win32] Bugfix: The OSMesa library was not unloaded on termination
- [Win32] Bugfix: Right shift emitted `GLFW_KEY_UNKNOWN` when using a CJK IME (#2050)
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
- [Cocoa] Changed `EGLNativeWindowType` from `NSView` to `CALayer` (#1169)
- [Cocoa] Changed F13 key to report Print Screen for cross-platform consistency
(#1786)
- [Cocoa] Disabled macOS fullscreen when `GLFW_RESIZABLE` is false
- [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
- [Cocoa] Bugfix: Touching event queue from secondary thread before main thread
would abort (#1649)
- [Cocoa] Bugfix: Non-BMP Unicode codepoint input was reported as UTF-16
(#1635)
- [Cocoa] Bugfix: Failing to retrieve the refresh rate of built-in displays
could leak memory
- [Cocoa] Bugfix: Objective-C files were compiled as C with CMake 3.19 (#1787)
- [Cocoa] Bugfix: Duplicate video modes were not filtered out (#1830)
- [Cocoa] Bugfix: Menu bar was not clickable on macOS 10.15+ until it lost and
regained focus (#1648,#1802)
- [Cocoa] Bugfix: Monitor name query could segfault on macOS 11 (#1809,#1833)
- [Cocoa] Bugfix: The install name of the installed dylib was relative (#1504)
- [Cocoa] Bugfix: The MoltenVK layer contents scale was updated only after
related events were emitted
- [Cocoa] Bugfix: Moving the cursor programmatically would freeze it for
a fraction of a second (#1962)
- [Cocoa] Bugfix: `kIOMasterPortDefault` was deprecated in macOS 12.0 (#1980)
- [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003)
- [Cocoa] Bugfix: A connected Apple AirPlay would emit a useless error (#1791)
- [Cocoa] Bugfix: The EGL and OSMesa libraries were not unloaded on termination
- [Cocoa] Bugfix: `GLFW_MAXIMIZED` was always true when `GLFW_RESIZABLE` was false
- [Cocoa] Bugfix: Changing `GLFW_DECORATED` in macOS fullscreen would abort
application (#1886)
- [Cocoa] Bugfix: Setting a monitor from macOS fullscreen would abort
application (#2110)
- [Cocoa] Bugfix: The Vulkan loader was not loaded from the `Frameworks` bundle
subdirectory (#2113,#2120)
- [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)
- [X11] Bugfix: Termination would segfault if the IM had been destroyed
- [X11] Bugfix: Any IM started after initialization would not be detected
- [X11] Bugfix: Xlib errors caused by other parts of the application could be
reported as GLFW errors
- [X11] Bugfix: A handle race condition could cause a `BadWindow` error (#1633)
- [X11] Bugfix: XKB path used keysyms instead of physical locations for
non-printable keys (#1598)
- [X11] Bugfix: Function keys were mapped to `GLFW_KEY_UNKNOWN` for some layout
combinations (#1598)
- [X11] Bugfix: Keys pressed simultaneously with others were not always
reported (#1112,#1415,#1472,#1616)
- [X11] Bugfix: Some window attributes were not applied on leaving fullscreen
(#1863)
- [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory
- [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on
undefined behavior (#1986)
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
- [X11] Bugfix: Waiting for events would fail if file descriptor was too large
(#2024)
- [X11] Bugfix: Joystick events could lead to busy-waiting (#1872)
- [X11] Bugfix: `glfwWaitEvents*` did not continue for joystick events
- [X11] Bugfix: `glfwPostEmptyEvent` could be ignored due to race condition
(#379,#1281,#1285,#2033)
- [X11] Bugfix: Dynamic loading on NetBSD failed due to soname differences
- [X11] Bugfix: Left shift of int constant relied on undefined behavior (#1951)
- [X11] Bugfix: The OSMesa libray was not unloaded on termination
- [X11] Bugfix: A malformed response during selection transfer could cause a segfault
- [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108)
- [Wayland] Added dynamic loading of all Wayland libraries
- [Wayland] Added support for key names via xkbcommon
- [Wayland] Added support for file path drop events (#2040)
- [Wayland] Added support for more human-readable monitor names where available
- [Wayland] Disabled alpha channel for opaque windows on systems lacking
`EGL_EXT_present_opaque` (#1895)
- [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
- [Wayland] Bugfix: Repeated keys could be reported with `NULL` window (#1704)
- [Wayland] Bugfix: Retrieving partial framebuffer size would segfault
- [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms
(#1463)
- [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong order
(#1798)
- [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792)
- [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908)
- [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899)
- [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
- [Wayland] Bugfix: Activating a window would emit two input focus events
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
- [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731)
- [Wayland] Bugfix: A key being repeated was not released when window lost focus
- [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE`
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN`
- [Wayland] Bugfix: Text input did not repeat along with key repeat
- [Wayland] Bugfix: `glfwPostEmptyEvent` sometimes had no effect (#1520,#1521)
- [Wayland] Bugfix: `glfwSetClipboardString` would fail if set to result of
`glfwGetClipboardString`
- [Wayland] Bugfix: Data source creation error would cause double free at termination
- [Wayland] Bugfix: Partial writes of clipboard string would cause beginning to repeat
- [Wayland] Bugfix: Some errors would cause clipboard string transfer to hang
- [Wayland] Bugfix: Drag and drop data was misinterpreted as clipboard string
- [Wayland] Bugfix: MIME type matching was not performed for clipboard string
- [Wayland] Bugfix: The OSMesa library was not unloaded on termination
- [Wayland] Bugfix: `glfwCreateWindow` could emit `GLFW_FEATURE_UNAVAILABLE`
- [Wayland] Bugfix: Lock key modifier bits were only set when lock keys were pressed
- [Wayland] Bugfix: A window leaving full screen mode would be iconified (#1995)
- [Wayland] Bugfix: A window leaving full screen mode ignored its desired size
- [Wayland] Bugfix: `glfwSetWindowMonitor` did not update windowed mode size
- [Wayland] Bugfix: `glfwRestoreWindow` would make a full screen window windowed
- [Wayland] Bugfix: A window maximized or restored by the user would enter an
inconsistent state
- [Wayland] Bugfix: Window maximization events were not emitted
- [Wayland] Bugfix: `glfwRestoreWindow` assumed it was always in windowed mode
- [Wayland] Bugfix: `glfwSetWindowSize` would resize a full screen window
- [Wayland] Bugfix: A window content scale event would be emitted every time
the window resized
- [Wayland] Bugfix: If `glfwInit` failed it would close stdin
- [Wayland] Bugfix: Manual resizing with fallback decorations behaved erratically
(#1991,#2115,#2127)
- [Wayland] Bugfix: Size limits included frame size for fallback decorations
- [Wayland] Bugfix: Updating `GLFW_DECORATED` had no effect on server-side
decorations
- [Wayland] Bugfix: A monitor would be reported as connected again if its scale
changed
- [Wayland] Bugfix: `glfwTerminate` would segfault if any monitor had changed
scale
- [Wayland] Bugfix: Window content scale events were not emitted when monitor
scale changed
- [Wayland] Bugfix: `glfwSetWindowAspectRatio` reported an error instead of
applying the specified ratio
- [Wayland] Bugfix: `GLFW_MAXIMIZED` window hint had no effect
- [Wayland] Bugfix: `glfwRestoreWindow` had no effect before first show
- [Wayland] Bugfix: Hiding and then showing a window caused program abort on
wlroots compositors (#1268)
- [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG
decorations
- [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450)
- [POSIX] Removed use of deprecated function `gettimeofday`
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
- [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043)
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
macOS versions (#1442)
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
- [NSGL] Bugfix: Defining `GL_SILENCE_DEPRECATION` externally caused
a duplicate definition warning (#1840)
- [EGL] Added platform selection via the `EGL_EXT_platform_base` extension
(#442)
- [EGL] Added ANGLE backend selection via `EGL_ANGLE_platform_angle` extension
(#1380)
[EGL] Added loading of glvnd `libOpenGL.so.0` where available for OpenGL
- [EGL] Bugfix: The `GLFW_DOUBLEBUFFER` context attribute was ignored (#1843)
- [GLX] Added loading of glvnd `libGLX.so.0` where available
- [GLX] Bugfix: Context creation failed if GLX 1.4 was not exported by GLX library
## Contact ## Contact
On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as On [glfw.org](https://www.glfw.org/) you can find the latest version of GLFW, as
well as news, documentation and other information about the project. 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/). [Libera.Chat](https://libera.chat/).
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
request, please file it in the request, please file it in the
@ -309,182 +418,3 @@ request, please file it in the
Finally, if you're interested in helping out with the development of GLFW or Finally, if you're interested in helping out with the development of GLFW or
porting it to your favorite platform, join us on the forum, GitHub or IRC. porting it to your favorite platform, join us on the forum, GitHub or IRC.
## Acknowledgements
GLFW exists because people around the world donated their time and lent their
skills.
- Bobyshev Alexander
- Matt Arsenault
- David Avedissian
- Keith Bauer
- John Bartholomew
- Coşku Baş
- Niklas Behrens
- Andrew Belt
- Niklas Bergström
- Denis Bernard
- Doug Binks
- blanco
- Kyle Brenneman
- Rok Breulj
- Martin Capitanio
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- Ian Clarkson
- Michał Cichoń
- Lambert Clara
- Anna Clarke
- Yaron Cohen-Tal
- Omar Cornut
- Andrew Corrigan
- Bailey Cosier
- Noel Cower
- Jason Daly
- Jarrod Davis
- Olivier Delannoy
- Paul R. Deppe
- Michael Dickens
- Роман Донченко
- Mario Dorn
- Wolfgang Draxinger
- Jonathan Dummer
- Ralph Eastwood
- Fredrik Ehnbom
- Robin Eklind
- Siavash Eliasi
- Felipe Ferreira
- Michael Fogleman
- Gerald Franz
- Mário Freitas
- GeO4d
- Marcus Geelnard
- Stephen Gowen
- Kovid Goyal
- Eloi Marín Gratacós
- Stefan Gustavson
- Jonathan Hale
- Sylvain Hellegouarch
- Matthew Henry
- heromyth
- Lucas Hinderberger
- Paul Holden
- Warren Hu
- IntellectualKitty
- Aaron Jacobs
- Erik S. V. Jansson
- Toni Jovanoski
- Arseny Kapoulkine
- Cem Karan
- Osman Keskin
- Josh Kilmer
- Cameron King
- Peter Knut
- Christoph Kubisch
- Yuri Kunde Schlesner
- Konstantin Käfer
- Eric Larson
- Robin Leffmann
- Glenn Lewis
- Shane Liesegang
- Eyal Lotem
- Aaron Loucks
- Tristam MacDonald
- Hans Mackowiak
- Дмитри Малышев
- Zbigniew Mandziejewicz
- Adam Marcus
- Célestin Marot
- Kyle McDonald
- David Medlock
- Bryce Mehring
- Jonathan Mercier
- Marcel Metz
- Liam Middlebrook
- Jonathan Miller
- Kenneth Miller
- Bruce Mitchener
- Jack Moffitt
- Jeff Molofee
- Alexander Monakov
- Pierre Morel
- Jon Morton
- Pierre Moulon
- Martins Mozeiko
- Julian Møller
- ndogxj
- Kristian Nielsen
- Kamil Nowakowski
- Denis Ovod
- Ozzy
- Andri Pálsson
- Peoro
- Braden Pellett
- Christopher Pelloux
- Arturo J. Pérez
- Anthony Pesch
- Orson Peters
- Emmanuel Gil Peyrot
- Cyril Pichard
- Keith Pitt
- Stanislav Podgorskiy
- Nathan Poirier
- Alexandre Pretyman
- przemekmirek
- Philip Rideout
- Eddie Ringle
- Max Risuhin
- Jorge Rodriguez
- Ed Ropple
- Aleksey Rybalkin
- Riku Salminen
- Brandon Schaefer
- Sebastian Schuberth
- Christian Sdunek
- Matt Sealey
- Steve Sexton
- Arkady Shapkin
- Yoshiki Shibukawa
- Dmitri Shuralyov
- Daniel Skorupski
- Bradley Smith
- Cliff Smolinsky
- Patrick Snape
- Erlend Sogge Heggen
- Julian Squires
- Johannes Stein
- Pontus Stenetorp
- Michael Stocker
- Justin Stoecker
- Elviss Strazdins
- Paul Sultana
- Nathan Sweet
- TTK-Bandit
- Sergey Tikhomirov
- Arthur Tombs
- Ioannis Tsakpinis
- Samuli Tuomola
- Matthew Turner
- urraka
- Elias Vanderstuyft
- Stef Velzel
- Jari Vetoniemi
- Ricardo Vieira
- Nicholas Vitovitch
- Simon Voordouw
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Xo Wang
- Jay Weisskopf
- Frank Wille
- Ryogo Yoshimura
- Andrey Zholos
- Santi Zupancic
- Jonas Ådahl
- Lasse Öörni
- All the unmentioned and anonymous contributors in the GLFW community, for bug
reports, patches, feedback, testing and encouragement

3672
deps/glad/gl.h vendored

File diff suppressed because it is too large Load Diff

1805
deps/glad/gles2.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,282 +0,0 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

View File

@ -1,92 +0,0 @@
/* */
/* File: vk_platform.h */
/* */
/*
** Copyright (c) 2014-2017 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
/* On Windows, Vulkan commands use the stdcall convention */
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
/* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
/* calling convention, i.e. float parameters are passed in registers. This */
/* is true even if the rest of the application passes floats on the stack, */
/* as it does by default when compiling for the armeabi-v7a NDK ABI. */
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
/* On other platforms, use the default calling convention */
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#include <stddef.h>
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif /* !defined(VK_NO_STDINT_H) */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif

3554
deps/glad/vulkan.h vendored

File diff suppressed because it is too large Load Diff

1791
deps/glad_gl.c vendored

File diff suppressed because it is too large Load Diff

593
deps/glad_vulkan.c vendored
View File

@ -1,593 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glad/vulkan.h>
#ifndef GLAD_IMPL_UTIL_C_
#define GLAD_IMPL_UTIL_C_
#ifdef _MSC_VER
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
#else
#define GLAD_IMPL_UTIL_SSCANF sscanf
#endif
#endif /* GLAD_IMPL_UTIL_C_ */
int GLAD_VK_VERSION_1_0 = 0;
int GLAD_VK_VERSION_1_1 = 0;
int GLAD_VK_EXT_debug_report = 0;
int GLAD_VK_KHR_surface = 0;
int GLAD_VK_KHR_swapchain = 0;
PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR = NULL;
PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR = NULL;
PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers = NULL;
PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets = NULL;
PFN_vkAllocateMemory glad_vkAllocateMemory = NULL;
PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer = NULL;
PFN_vkBindBufferMemory glad_vkBindBufferMemory = NULL;
PFN_vkBindBufferMemory2 glad_vkBindBufferMemory2 = NULL;
PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL;
PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL;
PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
PFN_vkCmdDraw glad_vkCmdDraw = NULL;
PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL;
PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL;
PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL;
PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL;
PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
PFN_vkCreateComputePipelines glad_vkCreateComputePipelines = NULL;
PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT = NULL;
PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool = NULL;
PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout = NULL;
PFN_vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate = NULL;
PFN_vkCreateDevice glad_vkCreateDevice = NULL;
PFN_vkCreateEvent glad_vkCreateEvent = NULL;
PFN_vkCreateFence glad_vkCreateFence = NULL;
PFN_vkCreateFramebuffer glad_vkCreateFramebuffer = NULL;
PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines = NULL;
PFN_vkCreateImage glad_vkCreateImage = NULL;
PFN_vkCreateImageView glad_vkCreateImageView = NULL;
PFN_vkCreateInstance glad_vkCreateInstance = NULL;
PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
PFN_vkCreateSampler glad_vkCreateSampler = NULL;
PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL;
PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
PFN_vkCreateShaderModule glad_vkCreateShaderModule = NULL;
PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR = NULL;
PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT = NULL;
PFN_vkDestroyBuffer glad_vkDestroyBuffer = NULL;
PFN_vkDestroyBufferView glad_vkDestroyBufferView = NULL;
PFN_vkDestroyCommandPool glad_vkDestroyCommandPool = NULL;
PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT = NULL;
PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool = NULL;
PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout = NULL;
PFN_vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate = NULL;
PFN_vkDestroyDevice glad_vkDestroyDevice = NULL;
PFN_vkDestroyEvent glad_vkDestroyEvent = NULL;
PFN_vkDestroyFence glad_vkDestroyFence = NULL;
PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer = NULL;
PFN_vkDestroyImage glad_vkDestroyImage = NULL;
PFN_vkDestroyImageView glad_vkDestroyImageView = NULL;
PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
PFN_vkDestroySampler glad_vkDestroySampler = NULL;
PFN_vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion = NULL;
PFN_vkDestroySemaphore glad_vkDestroySemaphore = NULL;
PFN_vkDestroyShaderModule glad_vkDestroyShaderModule = NULL;
PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR = NULL;
PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR = NULL;
PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle = NULL;
PFN_vkEndCommandBuffer glad_vkEndCommandBuffer = NULL;
PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties = NULL;
PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties = NULL;
PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties = NULL;
PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties = NULL;
PFN_vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion = NULL;
PFN_vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups = NULL;
PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices = NULL;
PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
PFN_vkFreeMemory glad_vkFreeMemory = NULL;
PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL;
PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL;
PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL;
PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL;
PFN_vkGetEventStatus glad_vkGetEventStatus = NULL;
PFN_vkGetFenceStatus glad_vkGetFenceStatus = NULL;
PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements = NULL;
PFN_vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2 = NULL;
PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements = NULL;
PFN_vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2 = NULL;
PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout = NULL;
PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr = NULL;
PFN_vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties = NULL;
PFN_vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties = NULL;
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties = NULL;
PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures = NULL;
PFN_vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2 = NULL;
PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties = NULL;
PFN_vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties = NULL;
PFN_vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2 = NULL;
PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR = NULL;
PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties = NULL;
PFN_vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2 = NULL;
PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties = NULL;
PFN_vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2 = NULL;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties = NULL;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
PFN_vkMapMemory glad_vkMapMemory = NULL;
PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
PFN_vkResetEvent glad_vkResetEvent = NULL;
PFN_vkResetFences glad_vkResetFences = NULL;
PFN_vkSetEvent glad_vkSetEvent = NULL;
PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL;
PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL;
PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
PFN_vkWaitForFences glad_vkWaitForFences = NULL;
static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_0) return;
vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load("vkAllocateCommandBuffers", userptr);
vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load("vkAllocateDescriptorSets", userptr);
vkAllocateMemory = (PFN_vkAllocateMemory) load("vkAllocateMemory", userptr);
vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load("vkBeginCommandBuffer", userptr);
vkBindBufferMemory = (PFN_vkBindBufferMemory) load("vkBindBufferMemory", userptr);
vkBindImageMemory = (PFN_vkBindImageMemory) load("vkBindImageMemory", userptr);
vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load("vkCmdBeginQuery", userptr);
vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load("vkCmdBeginRenderPass", userptr);
vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load("vkCmdBindDescriptorSets", userptr);
vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load("vkCmdBindIndexBuffer", userptr);
vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load("vkCmdBindPipeline", userptr);
vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load("vkCmdBindVertexBuffers", userptr);
vkCmdBlitImage = (PFN_vkCmdBlitImage) load("vkCmdBlitImage", userptr);
vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load("vkCmdClearAttachments", userptr);
vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load("vkCmdClearColorImage", userptr);
vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load("vkCmdClearDepthStencilImage", userptr);
vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load("vkCmdCopyBuffer", userptr);
vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load("vkCmdCopyBufferToImage", userptr);
vkCmdCopyImage = (PFN_vkCmdCopyImage) load("vkCmdCopyImage", userptr);
vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load("vkCmdCopyImageToBuffer", userptr);
vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load("vkCmdCopyQueryPoolResults", userptr);
vkCmdDispatch = (PFN_vkCmdDispatch) load("vkCmdDispatch", userptr);
vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load("vkCmdDispatchIndirect", userptr);
vkCmdDraw = (PFN_vkCmdDraw) load("vkCmdDraw", userptr);
vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load("vkCmdDrawIndexed", userptr);
vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load("vkCmdDrawIndexedIndirect", userptr);
vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load("vkCmdDrawIndirect", userptr);
vkCmdEndQuery = (PFN_vkCmdEndQuery) load("vkCmdEndQuery", userptr);
vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load("vkCmdEndRenderPass", userptr);
vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load("vkCmdExecuteCommands", userptr);
vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load("vkCmdFillBuffer", userptr);
vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load("vkCmdNextSubpass", userptr);
vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load("vkCmdPipelineBarrier", userptr);
vkCmdPushConstants = (PFN_vkCmdPushConstants) load("vkCmdPushConstants", userptr);
vkCmdResetEvent = (PFN_vkCmdResetEvent) load("vkCmdResetEvent", userptr);
vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load("vkCmdResetQueryPool", userptr);
vkCmdResolveImage = (PFN_vkCmdResolveImage) load("vkCmdResolveImage", userptr);
vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load("vkCmdSetBlendConstants", userptr);
vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load("vkCmdSetDepthBias", userptr);
vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load("vkCmdSetDepthBounds", userptr);
vkCmdSetEvent = (PFN_vkCmdSetEvent) load("vkCmdSetEvent", userptr);
vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load("vkCmdSetLineWidth", userptr);
vkCmdSetScissor = (PFN_vkCmdSetScissor) load("vkCmdSetScissor", userptr);
vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load("vkCmdSetStencilCompareMask", userptr);
vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load("vkCmdSetStencilReference", userptr);
vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load("vkCmdSetStencilWriteMask", userptr);
vkCmdSetViewport = (PFN_vkCmdSetViewport) load("vkCmdSetViewport", userptr);
vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load("vkCmdUpdateBuffer", userptr);
vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load("vkCmdWaitEvents", userptr);
vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load("vkCmdWriteTimestamp", userptr);
vkCreateBuffer = (PFN_vkCreateBuffer) load("vkCreateBuffer", userptr);
vkCreateBufferView = (PFN_vkCreateBufferView) load("vkCreateBufferView", userptr);
vkCreateCommandPool = (PFN_vkCreateCommandPool) load("vkCreateCommandPool", userptr);
vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load("vkCreateComputePipelines", userptr);
vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load("vkCreateDescriptorPool", userptr);
vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load("vkCreateDescriptorSetLayout", userptr);
vkCreateDevice = (PFN_vkCreateDevice) load("vkCreateDevice", userptr);
vkCreateEvent = (PFN_vkCreateEvent) load("vkCreateEvent", userptr);
vkCreateFence = (PFN_vkCreateFence) load("vkCreateFence", userptr);
vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load("vkCreateFramebuffer", userptr);
vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load("vkCreateGraphicsPipelines", userptr);
vkCreateImage = (PFN_vkCreateImage) load("vkCreateImage", userptr);
vkCreateImageView = (PFN_vkCreateImageView) load("vkCreateImageView", userptr);
vkCreateInstance = (PFN_vkCreateInstance) load("vkCreateInstance", userptr);
vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load("vkCreatePipelineCache", userptr);
vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load("vkCreatePipelineLayout", userptr);
vkCreateQueryPool = (PFN_vkCreateQueryPool) load("vkCreateQueryPool", userptr);
vkCreateRenderPass = (PFN_vkCreateRenderPass) load("vkCreateRenderPass", userptr);
vkCreateSampler = (PFN_vkCreateSampler) load("vkCreateSampler", userptr);
vkCreateSemaphore = (PFN_vkCreateSemaphore) load("vkCreateSemaphore", userptr);
vkCreateShaderModule = (PFN_vkCreateShaderModule) load("vkCreateShaderModule", userptr);
vkDestroyBuffer = (PFN_vkDestroyBuffer) load("vkDestroyBuffer", userptr);
vkDestroyBufferView = (PFN_vkDestroyBufferView) load("vkDestroyBufferView", userptr);
vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load("vkDestroyCommandPool", userptr);
vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load("vkDestroyDescriptorPool", userptr);
vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load("vkDestroyDescriptorSetLayout", userptr);
vkDestroyDevice = (PFN_vkDestroyDevice) load("vkDestroyDevice", userptr);
vkDestroyEvent = (PFN_vkDestroyEvent) load("vkDestroyEvent", userptr);
vkDestroyFence = (PFN_vkDestroyFence) load("vkDestroyFence", userptr);
vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load("vkDestroyFramebuffer", userptr);
vkDestroyImage = (PFN_vkDestroyImage) load("vkDestroyImage", userptr);
vkDestroyImageView = (PFN_vkDestroyImageView) load("vkDestroyImageView", userptr);
vkDestroyInstance = (PFN_vkDestroyInstance) load("vkDestroyInstance", userptr);
vkDestroyPipeline = (PFN_vkDestroyPipeline) load("vkDestroyPipeline", userptr);
vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load("vkDestroyPipelineCache", userptr);
vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load("vkDestroyPipelineLayout", userptr);
vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load("vkDestroyQueryPool", userptr);
vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load("vkDestroyRenderPass", userptr);
vkDestroySampler = (PFN_vkDestroySampler) load("vkDestroySampler", userptr);
vkDestroySemaphore = (PFN_vkDestroySemaphore) load("vkDestroySemaphore", userptr);
vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load("vkDestroyShaderModule", userptr);
vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load("vkDeviceWaitIdle", userptr);
vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load("vkEndCommandBuffer", userptr);
vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load("vkEnumerateDeviceExtensionProperties", userptr);
vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load("vkEnumerateDeviceLayerProperties", userptr);
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load("vkEnumerateInstanceExtensionProperties", userptr);
vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load("vkEnumerateInstanceLayerProperties", userptr);
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load("vkEnumeratePhysicalDevices", userptr);
vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load("vkFlushMappedMemoryRanges", userptr);
vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load("vkFreeCommandBuffers", userptr);
vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load("vkFreeDescriptorSets", userptr);
vkFreeMemory = (PFN_vkFreeMemory) load("vkFreeMemory", userptr);
vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load("vkGetBufferMemoryRequirements", userptr);
vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load("vkGetDeviceMemoryCommitment", userptr);
vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load("vkGetDeviceProcAddr", userptr);
vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load("vkGetDeviceQueue", userptr);
vkGetEventStatus = (PFN_vkGetEventStatus) load("vkGetEventStatus", userptr);
vkGetFenceStatus = (PFN_vkGetFenceStatus) load("vkGetFenceStatus", userptr);
vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load("vkGetImageMemoryRequirements", userptr);
vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load("vkGetImageSparseMemoryRequirements", userptr);
vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load("vkGetImageSubresourceLayout", userptr);
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load("vkGetInstanceProcAddr", userptr);
vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load("vkGetPhysicalDeviceFeatures", userptr);
vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load("vkGetPhysicalDeviceFormatProperties", userptr);
vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load("vkGetPhysicalDeviceImageFormatProperties", userptr);
vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load("vkGetPhysicalDeviceMemoryProperties", userptr);
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load("vkGetPhysicalDeviceProperties", userptr);
vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load("vkGetPhysicalDeviceQueueFamilyProperties", userptr);
vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr);
vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load("vkGetPipelineCacheData", userptr);
vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load("vkGetQueryPoolResults", userptr);
vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load("vkGetRenderAreaGranularity", userptr);
vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load("vkInvalidateMappedMemoryRanges", userptr);
vkMapMemory = (PFN_vkMapMemory) load("vkMapMemory", userptr);
vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load("vkMergePipelineCaches", userptr);
vkQueueBindSparse = (PFN_vkQueueBindSparse) load("vkQueueBindSparse", userptr);
vkQueueSubmit = (PFN_vkQueueSubmit) load("vkQueueSubmit", userptr);
vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load("vkQueueWaitIdle", userptr);
vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load("vkResetCommandBuffer", userptr);
vkResetCommandPool = (PFN_vkResetCommandPool) load("vkResetCommandPool", userptr);
vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load("vkResetDescriptorPool", userptr);
vkResetEvent = (PFN_vkResetEvent) load("vkResetEvent", userptr);
vkResetFences = (PFN_vkResetFences) load("vkResetFences", userptr);
vkSetEvent = (PFN_vkSetEvent) load("vkSetEvent", userptr);
vkUnmapMemory = (PFN_vkUnmapMemory) load("vkUnmapMemory", userptr);
vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load("vkUpdateDescriptorSets", userptr);
vkWaitForFences = (PFN_vkWaitForFences) load("vkWaitForFences", userptr);
}
static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_1) return;
vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load("vkBindBufferMemory2", userptr);
vkBindImageMemory2 = (PFN_vkBindImageMemory2) load("vkBindImageMemory2", userptr);
vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load("vkCmdDispatchBase", userptr);
vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load("vkCmdSetDeviceMask", userptr);
vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load("vkCreateDescriptorUpdateTemplate", userptr);
vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load("vkCreateSamplerYcbcrConversion", userptr);
vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load("vkDestroyDescriptorUpdateTemplate", userptr);
vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load("vkDestroySamplerYcbcrConversion", userptr);
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load("vkEnumeratePhysicalDeviceGroups", userptr);
vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load("vkGetBufferMemoryRequirements2", userptr);
vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load("vkGetDescriptorSetLayoutSupport", userptr);
vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load("vkGetDeviceGroupPeerMemoryFeatures", userptr);
vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load("vkGetDeviceQueue2", userptr);
vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load("vkGetImageMemoryRequirements2", userptr);
vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load("vkGetImageSparseMemoryRequirements2", userptr);
vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load("vkGetPhysicalDeviceExternalBufferProperties", userptr);
vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load("vkGetPhysicalDeviceExternalFenceProperties", userptr);
vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load("vkGetPhysicalDeviceExternalSemaphoreProperties", userptr);
vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load("vkGetPhysicalDeviceFeatures2", userptr);
vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load("vkGetPhysicalDeviceFormatProperties2", userptr);
vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load("vkGetPhysicalDeviceImageFormatProperties2", userptr);
vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load("vkGetPhysicalDeviceMemoryProperties2", userptr);
vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load("vkGetPhysicalDeviceProperties2", userptr);
vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load("vkGetPhysicalDeviceQueueFamilyProperties2", userptr);
vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load("vkGetPhysicalDeviceSparseImageFormatProperties2", userptr);
vkTrimCommandPool = (PFN_vkTrimCommandPool) load("vkTrimCommandPool", userptr);
vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load("vkUpdateDescriptorSetWithTemplate", userptr);
}
static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_EXT_debug_report) return;
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load("vkCreateDebugReportCallbackEXT", userptr);
vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load("vkDebugReportMessageEXT", userptr);
vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load("vkDestroyDebugReportCallbackEXT", userptr);
}
static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_surface) return;
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load("vkDestroySurfaceKHR", userptr);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr);
vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr);
vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr);
vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr);
}
static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_swapchain) return;
vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load("vkAcquireNextImage2KHR", userptr);
vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load("vkAcquireNextImageKHR", userptr);
vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load("vkCreateSwapchainKHR", userptr);
vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load("vkDestroySwapchainKHR", userptr);
vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr);
vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load("vkGetDeviceGroupSurfacePresentModesKHR", userptr);
vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load("vkGetPhysicalDevicePresentRectanglesKHR", userptr);
vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load("vkGetSwapchainImagesKHR", userptr);
vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load("vkQueuePresentKHR", userptr);
}
static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *out_extension_count, char ***out_extensions) {
uint32_t i;
uint32_t instance_extension_count = 0;
uint32_t device_extension_count = 0;
uint32_t max_extension_count;
uint32_t total_extension_count;
char **extensions;
VkExtensionProperties *ext_properties;
VkResult result;
if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) {
return 0;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
if (result != VK_SUCCESS) {
return 0;
}
if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL);
if (result != VK_SUCCESS) {
return 0;
}
}
total_extension_count = instance_extension_count + device_extension_count;
max_extension_count = instance_extension_count > device_extension_count
? instance_extension_count : device_extension_count;
ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties));
if (ext_properties == NULL) {
return 0;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties);
if (result != VK_SUCCESS) {
free((void*) ext_properties);
return 0;
}
extensions = (char**) calloc(total_extension_count, sizeof(char*));
if (extensions == NULL) {
free((void*) ext_properties);
return 0;
}
for (i = 0; i < instance_extension_count; ++i) {
VkExtensionProperties ext = ext_properties[i];
size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[i] = (char*) malloc(extension_name_length * sizeof(char));
memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char));
}
if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties);
if (result != VK_SUCCESS) {
for (i = 0; i < instance_extension_count; ++i) {
free((void*) extensions[i]);
}
free(extensions);
return 0;
}
for (i = 0; i < device_extension_count; ++i) {
VkExtensionProperties ext = ext_properties[i];
size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char));
memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char));
}
}
free((void*) ext_properties);
*out_extension_count = total_extension_count;
*out_extensions = extensions;
return 1;
}
static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) {
uint32_t i;
for(i = 0; i < extension_count ; ++i) {
free((void*) (extensions[i]));
}
free((void*) extensions);
}
static int glad_vk_has_extension(const char *name, uint32_t extension_count, char **extensions) {
uint32_t i;
for (i = 0; i < extension_count; ++i) {
if(strcmp(name, extensions[i]) == 0) {
return 1;
}
}
return 0;
}
static GLADapiproc glad_vk_get_proc_from_userptr(const char* name, void *userptr) {
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
}
static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) {
uint32_t extension_count = 0;
char **extensions = NULL;
if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0;
GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions);
GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions);
GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
glad_vk_free_extensions(extension_count, extensions);
return 1;
}
static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
int major = 1;
int minor = 0;
#ifdef VK_VERSION_1_1
if (vkEnumerateInstanceVersion != NULL) {
uint32_t version;
VkResult result;
result = vkEnumerateInstanceVersion(&version);
if (result == VK_SUCCESS) {
major = (int) VK_VERSION_MAJOR(version);
minor = (int) VK_VERSION_MINOR(version);
}
}
#endif
if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) {
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(physical_device, &properties);
major = (int) VK_VERSION_MAJOR(properties.apiVersion);
minor = (int) VK_VERSION_MINOR(properties.apiVersion);
}
GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
return GLAD_MAKE_VERSION(major, minor);
}
int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr) {
int version;
#ifdef VK_VERSION_1_1
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
#endif
version = glad_vk_find_core_vulkan( physical_device);
if (!version) {
return 0;
}
glad_vk_load_VK_VERSION_1_0(load, userptr);
glad_vk_load_VK_VERSION_1_1(load, userptr);
if (!glad_vk_find_extensions_vulkan( physical_device)) return 0;
glad_vk_load_VK_EXT_debug_report(load, userptr);
glad_vk_load_VK_KHR_surface(load, userptr);
glad_vk_load_VK_KHR_swapchain(load, userptr);
return version;
}
int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) {
return gladLoadVulkanUserPtr( physical_device, glad_vk_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
}

268
deps/linmath.h vendored
View File

@ -1,70 +1,96 @@
#ifndef LINMATH_H #ifndef LINMATH_H
#define LINMATH_H #define LINMATH_H
#include <string.h>
#include <math.h> #include <math.h>
#include <string.h>
#ifdef _MSC_VER /* 2021-03-21 Camilla Löwy <elmindreda@elmindreda.org>
#define inline __inline * - Replaced double constants with float equivalents
*/
#ifdef LINMATH_NO_INLINE
#define LINMATH_H_FUNC static
#else
#define LINMATH_H_FUNC static inline
#endif #endif
#define LINMATH_H_DEFINE_VEC(n) \ #define LINMATH_H_DEFINE_VEC(n) \
typedef float vec##n[n]; \ typedef float vec##n[n]; \
static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \ LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
{ \ { \
int i; \ int i; \
for(i=0; i<n; ++i) \ for(i=0; i<n; ++i) \
r[i] = a[i] + b[i]; \ r[i] = a[i] + b[i]; \
} \ } \
static inline void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \ LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
{ \ { \
int i; \ int i; \
for(i=0; i<n; ++i) \ for(i=0; i<n; ++i) \
r[i] = a[i] - b[i]; \ r[i] = a[i] - b[i]; \
} \ } \
static inline void vec##n##_scale(vec##n r, vec##n const v, float const s) \ LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \
{ \ { \
int i; \ int i; \
for(i=0; i<n; ++i) \ for(i=0; i<n; ++i) \
r[i] = v[i] * s; \ r[i] = v[i] * s; \
} \ } \
static inline float vec##n##_mul_inner(vec##n const a, vec##n const b) \ LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \
{ \ { \
float p = 0.; \ float p = 0.f; \
int i; \ int i; \
for(i=0; i<n; ++i) \ for(i=0; i<n; ++i) \
p += b[i]*a[i]; \ p += b[i]*a[i]; \
return p; \ return p; \
} \ } \
static inline float vec##n##_len(vec##n const v) \ LINMATH_H_FUNC float vec##n##_len(vec##n const v) \
{ \ { \
return (float) sqrt(vec##n##_mul_inner(v,v)); \ return sqrtf(vec##n##_mul_inner(v,v)); \
} \ } \
static inline void vec##n##_norm(vec##n r, vec##n const v) \ LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) \
{ \ { \
float k = 1.f / vec##n##_len(v); \ float k = 1.f / vec##n##_len(v); \
vec##n##_scale(r, v, k); \ vec##n##_scale(r, v, k); \
} \
LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = a[i]<b[i] ? a[i] : b[i]; \
} \
LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = a[i]>b[i] ? a[i] : b[i]; \
} \
LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = src[i]; \
} }
LINMATH_H_DEFINE_VEC(2) LINMATH_H_DEFINE_VEC(2)
LINMATH_H_DEFINE_VEC(3) LINMATH_H_DEFINE_VEC(3)
LINMATH_H_DEFINE_VEC(4) LINMATH_H_DEFINE_VEC(4)
static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b) LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
{ {
r[0] = a[1]*b[2] - a[2]*b[1]; r[0] = a[1]*b[2] - a[2]*b[1];
r[1] = a[2]*b[0] - a[0]*b[2]; r[1] = a[2]*b[0] - a[0]*b[2];
r[2] = a[0]*b[1] - a[1]*b[0]; r[2] = a[0]*b[1] - a[1]*b[0];
} }
static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n) LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
{ {
float p = 2.f*vec3_mul_inner(v, n); float p = 2.f * vec3_mul_inner(v, n);
int i; int i;
for(i=0;i<3;++i) for(i=0;i<3;++i)
r[i] = v[i] - p*n[i]; r[i] = v[i] - p*n[i];
} }
static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b) LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b)
{ {
r[0] = a[1]*b[2] - a[2]*b[1]; r[0] = a[1]*b[2] - a[2]*b[1];
r[1] = a[2]*b[0] - a[0]*b[2]; r[1] = a[2]*b[0] - a[0]*b[2];
@ -72,7 +98,7 @@ static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
r[3] = 1.f; r[3] = 1.f;
} }
static inline void vec4_reflect(vec4 r, vec4 v, vec4 n) LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n)
{ {
float p = 2.f*vec4_mul_inner(v, n); float p = 2.f*vec4_mul_inner(v, n);
int i; int i;
@ -81,68 +107,66 @@ static inline void vec4_reflect(vec4 r, vec4 v, vec4 n)
} }
typedef vec4 mat4x4[4]; typedef vec4 mat4x4[4];
static inline void mat4x4_identity(mat4x4 M) LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
{ {
int i, j; int i, j;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
for(j=0; j<4; ++j) for(j=0; j<4; ++j)
M[i][j] = i==j ? 1.f : 0.f; M[i][j] = i==j ? 1.f : 0.f;
} }
static inline void mat4x4_dup(mat4x4 M, mat4x4 N) LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N)
{ {
int i, j; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
for(j=0; j<4; ++j) vec4_dup(M[i], N[i]);
M[i][j] = N[i][j];
} }
static inline void mat4x4_row(vec4 r, mat4x4 M, int i) LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i)
{ {
int k; int k;
for(k=0; k<4; ++k) for(k=0; k<4; ++k)
r[k] = M[k][i]; r[k] = M[k][i];
} }
static inline void mat4x4_col(vec4 r, mat4x4 M, int i) LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i)
{ {
int k; int k;
for(k=0; k<4; ++k) for(k=0; k<4; ++k)
r[k] = M[i][k]; r[k] = M[i][k];
} }
static inline void mat4x4_transpose(mat4x4 M, mat4x4 N) LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N)
{ {
// Note: if M and N are the same, the user has to
// explicitly make a copy of M and set it to N.
int i, j; int i, j;
for(j=0; j<4; ++j) for(j=0; j<4; ++j)
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
M[i][j] = N[j][i]; M[i][j] = N[j][i];
} }
static inline void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b) LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b)
{ {
int i; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
vec4_add(M[i], a[i], b[i]); vec4_add(M[i], a[i], b[i]);
} }
static inline void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b) LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b)
{ {
int i; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
vec4_sub(M[i], a[i], b[i]); vec4_sub(M[i], a[i], b[i]);
} }
static inline void mat4x4_scale(mat4x4 M, mat4x4 a, float k) LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k)
{ {
int i; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
vec4_scale(M[i], a[i], k); vec4_scale(M[i], a[i], k);
} }
static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z) LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x, float y, float z)
{ {
int i;
vec4_scale(M[0], a[0], x); vec4_scale(M[0], a[0], x);
vec4_scale(M[1], a[1], y); vec4_scale(M[1], a[1], y);
vec4_scale(M[2], a[2], z); vec4_scale(M[2], a[2], z);
for(i = 0; i < 4; ++i) { vec4_dup(M[3], a[3]);
M[3][i] = a[3][i];
}
} }
static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b) LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b)
{ {
mat4x4 temp; mat4x4 temp;
int k, r, c; int k, r, c;
@ -153,7 +177,7 @@ static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
} }
mat4x4_dup(M, temp); mat4x4_dup(M, temp);
} }
static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v) LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v)
{ {
int i, j; int i, j;
for(j=0; j<4; ++j) { for(j=0; j<4; ++j) {
@ -162,14 +186,14 @@ static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
r[j] += M[i][j] * v[i]; r[j] += M[i][j] * v[i];
} }
} }
static inline void mat4x4_translate(mat4x4 T, float x, float y, float z) LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z)
{ {
mat4x4_identity(T); mat4x4_identity(T);
T[3][0] = x; T[3][0] = x;
T[3][1] = y; T[3][1] = y;
T[3][2] = z; T[3][2] = z;
} }
static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z) LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
{ {
vec4 t = {x, y, z, 0}; vec4 t = {x, y, z, 0};
vec4 r; vec4 r;
@ -179,33 +203,32 @@ static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z
M[3][i] += vec4_mul_inner(r, t); M[3][i] += vec4_mul_inner(r, t);
} }
} }
static inline void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b) LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a, vec3 const b)
{ {
int i, j; int i, j;
for(i=0; i<4; ++i) for(j=0; j<4; ++j) for(i=0; i<4; ++i) for(j=0; j<4; ++j)
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f; M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
} }
static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle) LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y, float z, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
vec3 u = {x, y, z}; vec3 u = {x, y, z};
if(vec3_len(u) > 1e-4) { if(vec3_len(u) > 1e-4) {
mat4x4 T, C, S = {{0}};
vec3_norm(u, u); vec3_norm(u, u);
mat4x4 T;
mat4x4_from_vec3_mul_outer(T, u, u); mat4x4_from_vec3_mul_outer(T, u, u);
S[1][2] = u[0]; mat4x4 S = {
S[2][1] = -u[0]; { 0, u[2], -u[1], 0},
S[2][0] = u[1]; {-u[2], 0, u[0], 0},
S[0][2] = -u[1]; { u[1], -u[0], 0, 0},
S[0][1] = u[2]; { 0, 0, 0, 0}
S[1][0] = -u[2]; };
mat4x4_scale(S, S, s); mat4x4_scale(S, S, s);
mat4x4 C;
mat4x4_identity(C); mat4x4_identity(C);
mat4x4_sub(C, C, T); mat4x4_sub(C, C, T);
@ -214,13 +237,13 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
mat4x4_add(T, T, C); mat4x4_add(T, T, C);
mat4x4_add(T, T, S); mat4x4_add(T, T, S);
T[3][3] = 1.; T[3][3] = 1.f;
mat4x4_mul(R, M, T); mat4x4_mul(R, M, T);
} else { } else {
mat4x4_dup(R, M); mat4x4_dup(R, M);
} }
} }
static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle) LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
@ -232,19 +255,19 @@ static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
}; };
mat4x4_mul(Q, M, R); mat4x4_mul(Q, M, R);
} }
static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
mat4x4 R = { mat4x4 R = {
{ c, 0.f, s, 0.f}, { c, 0.f, -s, 0.f},
{ 0.f, 1.f, 0.f, 0.f}, { 0.f, 1.f, 0.f, 0.f},
{ -s, 0.f, c, 0.f}, { s, 0.f, c, 0.f},
{ 0.f, 0.f, 0.f, 1.f} { 0.f, 0.f, 0.f, 1.f}
}; };
mat4x4_mul(Q, M, R); mat4x4_mul(Q, M, R);
} }
static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle) LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
@ -256,9 +279,8 @@ static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
}; };
mat4x4_mul(Q, M, R); mat4x4_mul(Q, M, R);
} }
static inline void mat4x4_invert(mat4x4 T, mat4x4 M) LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M)
{ {
float idet;
float s[6]; float s[6];
float c[6]; float c[6];
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
@ -276,7 +298,7 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
/* Assumes it is invertible */ /* Assumes it is invertible */
idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
@ -298,17 +320,12 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
} }
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M)
{ {
float s = 1.; mat4x4_dup(R, M);
float s = 1.f;
vec3 h; vec3 h;
mat4x4_dup(R, M);
vec3_norm(R[2], R[2]);
s = vec3_mul_inner(R[1], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[1], R[1], h);
vec3_norm(R[2], R[2]); vec3_norm(R[2], R[2]);
s = vec3_mul_inner(R[1], R[2]); s = vec3_mul_inner(R[1], R[2]);
@ -316,13 +333,17 @@ static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
vec3_sub(R[1], R[1], h); vec3_sub(R[1], R[1], h);
vec3_norm(R[1], R[1]); vec3_norm(R[1], R[1]);
s = vec3_mul_inner(R[0], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[0], R[0], h);
s = vec3_mul_inner(R[0], R[1]); s = vec3_mul_inner(R[0], R[1]);
vec3_scale(h, R[1], s); vec3_scale(h, R[1], s);
vec3_sub(R[0], R[0], h); vec3_sub(R[0], R[0], h);
vec3_norm(R[0], R[0]); vec3_norm(R[0], R[0]);
} }
static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f) LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
{ {
M[0][0] = 2.f*n/(r-l); M[0][0] = 2.f*n/(r-l);
M[0][1] = M[0][2] = M[0][3] = 0.f; M[0][1] = M[0][2] = M[0][3] = 0.f;
@ -338,7 +359,7 @@ static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t,
M[3][2] = -2.f*(f*n)/(f-n); M[3][2] = -2.f*(f*n)/(f-n);
M[3][0] = M[3][1] = M[3][3] = 0.f; M[3][0] = M[3][1] = M[3][3] = 0.f;
} }
static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f) LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
{ {
M[0][0] = 2.f/(r-l); M[0][0] = 2.f/(r-l);
M[0][1] = M[0][2] = M[0][3] = 0.f; M[0][1] = M[0][2] = M[0][3] = 0.f;
@ -354,11 +375,11 @@ static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, fl
M[3][2] = -(f+n)/(f-n); M[3][2] = -(f+n)/(f-n);
M[3][3] = 1.f; M[3][3] = 1.f;
} }
static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f) LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
{ {
/* NOTE: Degrees are an unhandy unit to work with. /* NOTE: Degrees are an unhandy unit to work with.
* linmath.h uses radians for everything! */ * linmath.h uses radians for everything! */
float const a = 1.f / (float) tan(y_fov / 2.f); float const a = 1.f / tanf(y_fov / 2.f);
m[0][0] = a / aspect; m[0][0] = a / aspect;
m[0][1] = 0.f; m[0][1] = 0.f;
@ -380,7 +401,7 @@ static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float
m[3][2] = -((2.f * f * n) / (f - n)); m[3][2] = -((2.f * f * n) / (f - n));
m[3][3] = 0.f; m[3][3] = 0.f;
} }
static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up) LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center, vec3 const up)
{ {
/* Adapted from Android's OpenGL Matrix.java. */ /* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */ /* See the OpenGL GLUT documentation for gluLookAt for a description */
@ -389,15 +410,14 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
/* TODO: The negation of of can be spared by swapping the order of /* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */ * operands in the following cross products in the right way. */
vec3 f; vec3 f;
vec3 s;
vec3 t;
vec3_sub(f, center, eye); vec3_sub(f, center, eye);
vec3_norm(f, f); vec3_norm(f, f);
vec3 s;
vec3_mul_cross(s, f, up); vec3_mul_cross(s, f, up);
vec3_norm(s, s); vec3_norm(s, s);
vec3 t;
vec3_mul_cross(t, s, f); vec3_mul_cross(t, s, f);
m[0][0] = s[0]; m[0][0] = s[0];
@ -424,24 +444,18 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
} }
typedef float quat[4]; typedef float quat[4];
static inline void quat_identity(quat q) #define quat_add vec4_add
#define quat_sub vec4_sub
#define quat_norm vec4_norm
#define quat_scale vec4_scale
#define quat_mul_inner vec4_mul_inner
LINMATH_H_FUNC void quat_identity(quat q)
{ {
q[0] = q[1] = q[2] = 0.f; q[0] = q[1] = q[2] = 0.f;
q[3] = 1.f; q[3] = 1.f;
} }
static inline void quat_add(quat r, quat a, quat b) LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] + b[i];
}
static inline void quat_sub(quat r, quat a, quat b)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] - b[i];
}
static inline void quat_mul(quat r, quat p, quat q)
{ {
vec3 w; vec3 w;
vec3_mul_cross(r, p, q); vec3_mul_cross(r, p, q);
@ -451,56 +465,42 @@ static inline void quat_mul(quat r, quat p, quat q)
vec3_add(r, r, w); vec3_add(r, r, w);
r[3] = p[3]*q[3] - vec3_mul_inner(p, q); r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
} }
static inline void quat_scale(quat r, quat v, float s) LINMATH_H_FUNC void quat_conj(quat r, quat const q)
{
int i;
for(i=0; i<4; ++i)
r[i] = v[i] * s;
}
static inline float quat_inner_product(quat a, quat b)
{
float p = 0.f;
int i;
for(i=0; i<4; ++i)
p += b[i]*a[i];
return p;
}
static inline void quat_conj(quat r, quat q)
{ {
int i; int i;
for(i=0; i<3; ++i) for(i=0; i<3; ++i)
r[i] = -q[i]; r[i] = -q[i];
r[3] = q[3]; r[3] = q[3];
} }
static inline void quat_rotate(quat r, float angle, vec3 axis) { LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
int i; vec3 axis_norm;
vec3 v; vec3_norm(axis_norm, axis);
vec3_scale(v, axis, sinf(angle / 2)); float s = sinf(angle / 2);
for(i=0; i<3; ++i) float c = cosf(angle / 2);
r[i] = v[i]; vec3_scale(r, axis_norm, s);
r[3] = cosf(angle / 2); r[3] = c;
} }
#define quat_norm vec4_norm LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v)
static inline void quat_mul_vec3(vec3 r, quat q, vec3 v)
{ {
/* /*
* Method by Fabian 'ryg' Giessen (of Farbrausch) * Method by Fabian 'ryg' Giessen (of Farbrausch)
t = 2 * cross(q.xyz, v) t = 2 * cross(q.xyz, v)
v' = v + q.w * t + cross(q.xyz, t) v' = v + q.w * t + cross(q.xyz, t)
*/ */
vec3 t = {q[0], q[1], q[2]}; vec3 t;
vec3 q_xyz = {q[0], q[1], q[2]};
vec3 u = {q[0], q[1], q[2]}; vec3 u = {q[0], q[1], q[2]};
vec3_mul_cross(t, t, v); vec3_mul_cross(t, q_xyz, v);
vec3_scale(t, t, 2); vec3_scale(t, t, 2);
vec3_mul_cross(u, u, t); vec3_mul_cross(u, q_xyz, t);
vec3_scale(t, t, q[3]); vec3_scale(t, t, q[3]);
vec3_add(r, v, t); vec3_add(r, v, t);
vec3_add(r, r, u); vec3_add(r, r, u);
} }
static inline void mat4x4_from_quat(mat4x4 M, quat q) LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q)
{ {
float a = q[3]; float a = q[3];
float b = q[0]; float b = q[0];
@ -530,18 +530,21 @@ static inline void mat4x4_from_quat(mat4x4 M, quat q)
M[3][3] = 1.f; M[3][3] = 1.f;
} }
static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q) LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q)
{ {
/* XXX: The way this is written only works for othogonal matrices. */ /* XXX: The way this is written only works for orthogonal matrices. */
/* TODO: Take care of non-orthogonal case. */ /* TODO: Take care of non-orthogonal case. */
quat_mul_vec3(R[0], q, M[0]); quat_mul_vec3(R[0], q, M[0]);
quat_mul_vec3(R[1], q, M[1]); quat_mul_vec3(R[1], q, M[1]);
quat_mul_vec3(R[2], q, M[2]); quat_mul_vec3(R[2], q, M[2]);
R[3][0] = R[3][1] = R[3][2] = 0.f; R[3][0] = R[3][1] = R[3][2] = 0.f;
R[3][3] = 1.f; R[0][3] = M[0][3];
R[1][3] = M[1][3];
R[2][3] = M[2][3];
R[3][3] = M[3][3]; // typically 1.0, but here we make it general
} }
static inline void quat_from_mat4x4(quat q, mat4x4 M) LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M)
{ {
float r=0.f; float r=0.f;
int i; int i;
@ -557,7 +560,7 @@ static inline void quat_from_mat4x4(quat q, mat4x4 M)
p = &perm[i]; p = &perm[i];
} }
r = (float) sqrt(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] ); r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
if(r < 1e-6) { if(r < 1e-6) {
q[0] = 1.f; q[0] = 1.f;
@ -571,4 +574,33 @@ static inline void quat_from_mat4x4(quat q, mat4x4 M)
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
} }
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a, vec2 const _b, float s)
{
vec2 a; memcpy(a, _a, sizeof(a));
vec2 b; memcpy(b, _b, sizeof(b));
float z_a = 0.f;
float z_b = 0.f;
if(vec2_len(a) < 1.f) {
z_a = sqrtf(1.f - vec2_mul_inner(a, a));
} else {
vec2_norm(a, a);
}
if(vec2_len(b) < 1.f) {
z_b = sqrtf(1.f - vec2_mul_inner(b, b));
} else {
vec2_norm(b, b);
}
vec3 a_ = {a[0], a[1], z_a};
vec3 b_ = {b[0], b[1], z_b};
vec3 c_;
vec3_mul_cross(c_, a_, b_);
float const angle = acos(vec3_mul_inner(a_, b_)) * s;
mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
}
#endif #endif

621
deps/nuklear.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -230,7 +230,7 @@ nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int m
} }
NK_INTERN void NK_INTERN void
nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) nk_glfw3_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
{ {
const char *text = glfwGetClipboardString(glfw.win); const char *text = glfwGetClipboardString(glfw.win);
if (text) nk_textedit_paste(edit, text, nk_strlen(text)); if (text) nk_textedit_paste(edit, text, nk_strlen(text));
@ -238,7 +238,7 @@ nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
} }
NK_INTERN void NK_INTERN void
nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len) nk_glfw3_clipboard_copy(nk_handle usr, const char *text, int len)
{ {
char *str = 0; char *str = 0;
(void)usr; (void)usr;
@ -261,8 +261,8 @@ nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback); glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
} }
nk_init_default(&glfw.ctx, 0); nk_init_default(&glfw.ctx, 0);
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy; glfw.ctx.clip.copy = nk_glfw3_clipboard_copy;
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste; glfw.ctx.clip.paste = nk_glfw3_clipboard_paste;
glfw.ctx.clip.userdata = nk_handle_ptr(0); glfw.ctx.clip.userdata = nk_handle_ptr(0);
nk_buffer_init_default(&glfw.ogl.cmds); nk_buffer_init_default(&glfw.ogl.cmds);

928
deps/stb_image_write.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +1,46 @@
set(glfw_DOCS_SOURCES # NOTE: The order of this list determines the order of items in the Guides
# (i.e. Pages) list in the generated documentation
set(source_files
main.dox
news.dox
quick.dox
moving.dox
compile.dox
build.dox
intro.dox
context.dox
monitor.dox
window.dox
input.dox
vulkan.dox
compat.dox
internal.dox)
set(extra_files DoxygenLayout.xml header.html footer.html extra.css spaces.svg)
set(header_paths
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
"${GLFW_SOURCE_DIR}/docs/main.dox"
"${GLFW_SOURCE_DIR}/docs/news.dox"
"${GLFW_SOURCE_DIR}/docs/quick.dox"
"${GLFW_SOURCE_DIR}/docs/moving.dox"
"${GLFW_SOURCE_DIR}/docs/compile.dox"
"${GLFW_SOURCE_DIR}/docs/build.dox"
"${GLFW_SOURCE_DIR}/docs/intro.dox"
"${GLFW_SOURCE_DIR}/docs/context.dox"
"${GLFW_SOURCE_DIR}/docs/monitor.dox"
"${GLFW_SOURCE_DIR}/docs/window.dox"
"${GLFW_SOURCE_DIR}/docs/input.dox"
"${GLFW_SOURCE_DIR}/docs/vulkan.dox"
"${GLFW_SOURCE_DIR}/docs/compat.dox"
"${GLFW_SOURCE_DIR}/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 header_paths)
string(APPEND GLFW_DOXYGEN_INPUT " \\\n\"${path}\"")
endforeach()
foreach(file IN LISTS source_files)
string(APPEND GLFW_DOXYGEN_INPUT " \\\n\"${CMAKE_CURRENT_SOURCE_DIR}/${file}\"")
endforeach() endforeach()
configure_file(Doxyfile.in Doxyfile @ONLY) configure_file(Doxyfile.in Doxyfile @ONLY)
add_custom_target(docs ALL "${DOXYGEN_EXECUTABLE}" add_custom_command(OUTPUT "html/index.html"
WORKING_DIRECTORY "${GLFW_BINARY_DIR}/docs" COMMAND "${DOXYGEN_EXECUTABLE}"
COMMENT "Generating HTML documentation" VERBATIM) WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
MAIN_DEPENDENCY Doxyfile
DEPENDS ${header_paths} ${source_files} ${extra_files}
COMMENT "Generating HTML documentation"
VERBATIM)
add_custom_target(docs ALL SOURCES "html/index.html")
set_target_properties(docs PROPERTIES FOLDER "GLFW3")

View File

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

File diff suppressed because it is too large Load Diff

14
docs/SUPPORT.md Normal file
View File

@ -0,0 +1,14 @@
# Support resources
See the [latest documentation](https://www.glfw.org/docs/latest/) for tutorials,
guides and the API reference.
If you have questions about using GLFW, we have a
[forum](https://discourse.glfw.org/), and the `#glfw` IRC channel on
[Libera.Chat](https://libera.chat/).
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.

View File

@ -25,39 +25,41 @@ GLFW.
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
This header declares the GLFW API and by default also includes the OpenGL header This header defines all the constants and declares all the types and function
from your development environment. See below for how to control this. prototypes of the GLFW API. By default, it also includes the OpenGL header from
your development environment. See [option macros](@ref build_macros) below for
how to select OpenGL ES headers and more.
The GLFW header also defines any platform-specific macros needed by your OpenGL The GLFW header also defines any platform-specific macros needed by your OpenGL
header, so it can be included without needing any window system headers. header, so that it can be included without needing any window system headers.
For example, under Windows you are normally required to include `windows.h` It does this only when needed, so if window system headers are included, the
before the OpenGL header, which would bring in the whole Win32 API. The GLFW GLFW header does not try to redefine those symbols. The reverse is not true,
header duplicates the small number of macros needed. i.e. `windows.h` cannot cope if any Win32 symbols have already been defined.
It does this only when needed, so if `windows.h` _is_ included, the GLFW header
does not try to redefine those symbols. The reverse is not true, i.e.
`windows.h` cannot cope if any of its symbols have already been defined.
In other words: In other words:
- Do _not_ include the OpenGL headers yourself, as GLFW does this for you - Use the GLFW header to include OpenGL or OpenGL ES headers portably
- Do _not_ include `windows.h` or other platform-specific headers unless you - Do not include window system headers unless you will use those APIs directly
plan on using those APIs directly - If you do need such headers, include them before the GLFW header
- If you _do_ need to include such headers, do it _before_ including
the GLFW header and it will handle this
If you are using an OpenGL extension loading library such as If you are using an OpenGL extension loading library such as
[glad](https://github.com/Dav1dde/glad), the extension loader header should [glad](https://github.com/Dav1dde/glad), the extension loader header should
be included _before_ the GLFW one. be included before the GLFW one. GLFW attempts to detect any OpenGL or OpenGL
ES header or extension loader header included before it and will then disable
the inclusion of the default OpenGL header. Most extension loaders also define
macros that disable similar headers below it.
@code @code
#include <glad/gl.h> #include <glad/gl.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
Alternatively the @ref GLFW_INCLUDE_NONE macro (described below) can be used to Both of these mechanisms depend on the extension loader header defining a known
prevent the GLFW header from including the OpenGL header. macro. If yours doesn't or you don't know which one your users will pick, the
@ref GLFW_INCLUDE_NONE macro will explicitly prevent the GLFW header from
including the OpenGL header. This will also allow you to include the two
headers in any order.
@code @code
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
@ -78,6 +80,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
@ -100,7 +107,7 @@ __GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.1
`GLES3/gl31.h` header instead of the regular OpenGL header. `GLES3/gl31.h` header instead of the regular OpenGL header.
@anchor GLFW_INCLUDE_ES32 @anchor GLFW_INCLUDE_ES32
__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.2 __GLFW_INCLUDE_ES32__ makes the GLFW header include the OpenGL ES 3.2
`GLES3/gl32.h` header instead of the regular OpenGL header. `GLES3/gl32.h` header instead of the regular OpenGL header.
@anchor GLFW_INCLUDE_NONE @anchor GLFW_INCLUDE_NONE
@ -108,7 +115,8 @@ __GLFW_INCLUDE_NONE__ makes the GLFW header not include any OpenGL or OpenGL ES
API header. This is useful in combination with an extension loading library. API header. This is useful in combination with an extension loading library.
If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h` If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h`
header (`OpenGL/gl.h` on macOS) is included. header (`OpenGL/gl.h` on macOS) is included, unless GLFW detects the inclusion
guards of any OpenGL, OpenGL ES or extension loader header it knows about.
The following macros control the inclusion of additional API headers. Any The following macros control the inclusion of additional API headers. Any
number of these may be defined simultaneously, and/or together with one of the number of these may be defined simultaneously, and/or together with one of the
@ -129,10 +137,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 +170,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,61 +185,41 @@ 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 any other library.
@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 For a minimal example of a program and GLFW sources built with CMake, see the
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and [GLFW CMake Starter](https://github.com/juliettef/GLFW-CMake-starter) on GitHub.
`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 +236,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 any other library.
@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 +274,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 +308,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 +323,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 +332,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.
*/ */

View File

@ -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
@ -97,14 +104,13 @@ integration by libwayland-egl, and keyboard handling by
from wayland-protocols to provide additional features if the compositor from wayland-protocols to provide additional features if the compositor
supports them. supports them.
GLFW uses xkbcommon 0.5.0 to provide compose key support. When it has been GLFW uses xkbcommon 0.5.0 to provide key and text input support. Earlier
built against an older xkbcommon, the compose key will be disabled even if it versions are not supported.
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)
@ -146,7 +152,7 @@ formats. If GLX 1.3 is not supported, @ref glfwInit will fail.
GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and
`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization `GLX_SGI_swap_control` extensions to provide vertical retrace synchronization
(or _vsync_), in that order of preference. Where none of these extension are (or _vsync_), in that order of preference. When none of these extensions are
available, calling @ref glfwSwapInterval will have no effect. available, calling @ref glfwSwapInterval will have no effect.
GLFW uses the `GLX_ARB_multisample` extension to create contexts with GLFW uses the `GLX_ARB_multisample` extension to create contexts with
@ -156,10 +162,9 @@ multisampling anti-aliasing. Where this extension is unavailable, the
GLFW uses the `GLX_ARB_create_context` extension when available, even when GLFW uses the `GLX_ARB_create_context` extension when available, even when
creating OpenGL contexts of version 2.1 and below. Where this extension is creating OpenGL contexts of version 2.1 and below. Where this extension is
unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint hints will only be partially supported, the `GLFW_CONTEXT_DEBUG` hint will have
will have no effect, and setting the `GLFW_OPENGL_PROFILE` or no effect, and setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT`
`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref hints to `GLFW_TRUE` will cause @ref glfwCreateWindow to fail.
glfwCreateWindow to fail.
GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for
context profiles. Where this extension is unavailable, setting the context profiles. Where this extension is unavailable, setting the
@ -199,10 +204,9 @@ unavailable, the `GLFW_SAMPLES` hint will have no effect.
GLFW uses the `WGL_ARB_create_context` extension when available, even when GLFW uses the `WGL_ARB_create_context` extension when available, even when
creating OpenGL contexts of version 2.1 and below. Where this extension is creating OpenGL contexts of version 2.1 and below. Where this extension is
unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR`
hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint hints will only be partially supported, the `GLFW_CONTEXT_DEBUG` hint will have
will have no effect, and setting the `GLFW_OPENGL_PROFILE` or no effect, and setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT`
`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref hints to `GLFW_TRUE` will cause @ref glfwCreateWindow to fail.
glfwCreateWindow to fail.
GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for
context profiles. Where this extension is unavailable, setting the context profiles. Where this extension is unavailable, setting the
@ -215,8 +219,8 @@ extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no
effect and the context will always be flushed when released. effect and the context will always be flushed when released.
GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB` GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB`
extensions to provide support for sRGB framebuffers. Where both of these extensions to provide support for sRGB framebuffers. When both of these
extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
@section compat_osx OpenGL on macOS @section compat_osx OpenGL on macOS
@ -230,16 +234,15 @@ 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_CONTEXT_DEBUG` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, `GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to
a non-default value will cause @ref glfwCreateWindow to fail and the a non-default value will cause @ref glfwCreateWindow to fail and the
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. `GLFW_CONTEXT_DEBUG` hint is ignored.
@section compat_vulkan Vulkan loader and API @section compat_vulkan Vulkan loader and API
@ -262,10 +265,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`

View File

@ -10,165 +10,179 @@ build applications that use GLFW, see @ref build_guide.
@section compile_cmake Using CMake @section compile_cmake Using CMake
GLFW behaves like most other libraries that use CMake so this guide mostly
describes the standard configure, generate and compile sequence. If you are already
familiar with this from other projects, you may want to focus on the @ref
compile_deps and @ref compile_options sections for GLFW-specific information.
GLFW uses [CMake](https://cmake.org/) to generate project files or makefiles GLFW uses [CMake](https://cmake.org/) to generate project files or makefiles
for a particular development environment. If you are on a Unix-like system such for your chosen development environment. To compile GLFW, first generate these
as Linux or FreeBSD or have a package system like Fink, MacPorts, Cygwin or files with CMake and then use them to compile the GLFW library.
Homebrew, you can install its CMake package. If not, you can download
installers for Windows and macOS from the
[CMake website](https://cmake.org/).
@note CMake only generates project files or makefiles. It does not compile the If you are on Windows and macOS you can
actual GLFW library. To compile GLFW, first generate these files for your [download CMake](https://cmake.org/download/) from their site.
chosen development environment and then use them to compile the actual GLFW
library. If you are on a Unix-like system such as Linux, FreeBSD or Cygwin or have
a package system like Fink, MacPorts or Homebrew, you can install its CMake
package.
CMake is a complex tool and this guide will only show a few of the possible ways
to set up and compile GLFW. The CMake project has their own much more detailed
[CMake user guide](https://cmake.org/cmake/help/latest/guide/user-interaction/)
that includes everything in this guide not specific to GLFW. It may be a useful
companion to this one.
@subsection compile_deps Dependencies @subsection compile_deps Installing dependencies
Once you have installed CMake, make sure that all other dependencies are The C/C++ development environments in Visual Studio, Xcode and MinGW come with
available. On some platforms, GLFW needs a few additional packages to be all necessary dependencies for compiling GLFW, but on Unix-like systems like
installed. See the section for your chosen platform and development environment Linux and FreeBSD you will need a few extra packages.
below.
@subsubsection compile_deps_msvc Dependencies for Visual C++ on Windows @subsubsection compile_deps_x11 Dependencies for X11
The Windows SDK bundled with Visual C++ already contains all the necessary To compile GLFW for X11, you need to have the X11 development packages
headers, link libraries and tools except for CMake. Move on to @ref installed. They are not needed to build or run programs that use GLFW.
compile_generate.
On Debian and derivatives like Ubuntu and Linux Mint the `xorg-dev` meta-package
@subsubsection compile_deps_mingw Dependencies for MinGW or MinGW-w64 on Windows pulls in the development packages for all of X11.
Both the MinGW and the MinGW-w64 packages already contain all the necessary
headers, link libraries and tools except for CMake. Move on to @ref
compile_generate.
@subsubsection compile_deps_mingw_cross Dependencies for MinGW or MinGW-w64 cross-compilation
Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For
example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages
for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives
like Ubuntu have the `mingw-w64` package for both.
GLFW has CMake toolchain files in the `CMake/` directory that set up
cross-compilation of Windows binaries. To use these files you add an option
when running `cmake` to generate the project files or makefiles:
@code{.sh} @code{.sh}
cmake -DCMAKE_TOOLCHAIN_FILE=<toolchain-file> . sudo apt install xorg-dev
@endcode @endcode
The exact toolchain file to use depends on the prefix used by the MinGW or On Fedora and derivatives like Red Hat the X11 extension packages
MinGW-w64 binaries on your system. You can usually see this in the /usr `libXcursor-devel`, `libXi-devel`, `libXinerama-devel` and `libXrandr-devel`
directory. For example, both the Debian/Ubuntu and Cygwin MinGW-w64 packages required by GLFW pull in all its other dependencies.
have `/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct
invocation would be:
@code{.sh} @code{.sh}
cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake . sudo dnf install libXcursor-devel libXi-devel libXinerama-devel libXrandr-devel
@endcode @endcode
For more details see the article On FreeBSD the X11 headers are installed along the end-user X11 packages, so if
[CMake Cross Compiling](https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling) on you have an X server running you should have the headers as well. If not,
the CMake wiki. install the `xorgproto` package.
Once you have this set up, move on to @ref compile_generate. @code{.sh}
pkg install xorgproto
@endcode
On Cygwin the `libXcursor-devel`, `libXi-devel`, `libXinerama-devel`,
`libXrandr-devel` and `libXrender-devel` packages in the Libs section of the GUI
installer will install all the headers and other development related files GLFW
requires for X11.
Once you have the required dependencies, move on to @ref compile_generate.
@subsubsection compile_deps_xcode Dependencies for Xcode on macOS @subsubsection compile_deps_wayland Dependencies for Wayland and X11
Xcode comes with all necessary tools except for CMake. The required headers To compile GLFW for both Wayland and X11, you need to have the X11, Wayland and xkbcommon
and libraries are included in the core macOS frameworks. Xcode can be development packages installed. They are not needed to build or run programs that use
downloaded from the Mac App Store or from the ADC Member Center. GLFW. You will also need to set the @ref GLFW_BUILD_WAYLAND CMake option in the next
step when generating build files.
Once you have Xcode installed, move on to @ref compile_generate. On Debian and derivatives like Ubuntu and Linux Mint you will need the `libwayland-dev`,
`libxkbcommon-dev` and `wayland-protocols` packages and the `xorg-dev` meta-package.
These will pull in all other dependencies.
@code{.sh}
sudo apt install libwayland-dev libxkbcommon-dev wayland-protocols xorg-dev
@endcode
@subsubsection compile_deps_x11 Dependencies for Linux and X11 On Fedora and derivatives like Red Hat you will need the `wayland-devel`,
`libxkbcommon-devel`, `wayland-protocols-devel`, `libXcursor-devel`, `libXi-devel`,
`libXinerama-devel` and `libXrandr-devel` packages. These will pull in all other
dependencies.
To compile GLFW for X11, you need to have the X11 packages installed, as well as @code{.sh}
the basic development tools like GCC and make. For example, on Ubuntu and other sudo dnf install wayland-devel libxkbcommon-devel wayland-protocols-devel libXcursor-devel libXi-devel libXinerama-devel libXrandr-devel
distributions based on Debian GNU/Linux, you need to install the `xorg-dev` @endcode
package, which pulls in all X.org header packages.
Once you have installed the necessary packages, move on to @ref On FreeBSD you will need the `wayland`, `libxkbcommon` and `wayland-protocols` packages.
compile_generate. The X11 headers are installed along the end-user X11 packages, so if you have an X server
running you should have the headers as well. If not, install the `xorgproto` package.
@code{.sh}
pkg install wayland libxkbcommon wayland-protocols xorgproto
@endcode
@subsubsection compile_deps_wayland Dependencies for Linux and Wayland Once you have the required dependencies, move on to @ref compile_generate.
To compile GLFW for Wayland, you need to have the Wayland packages installed,
as well as the basic development tools like GCC and make. For example, on
Ubuntu and other distributions based on Debian GNU/Linux, you need to install
the `libwayland-dev` package, which contains all Wayland headers and pulls in
wayland-scanner, as well as the `wayland-protocols` and `extra-cmake-modules`
packages.
Once you have installed the necessary packages, move on to @ref
compile_generate.
@subsection compile_deps_osmesa Dependencies for Linux and OSMesa
To compile GLFW for OSMesa, you need to install the OSMesa library and header
packages. For example, on Ubuntu and other distributions based on Debian
GNU/Linux, you need to install the `libosmesa6-dev` package. The OSMesa library
is required at runtime for context creation and is loaded on demand.
Once you have installed the necessary packages, move on to @ref
compile_generate.
@subsection compile_generate Generating build files with CMake @subsection compile_generate Generating build files with CMake
Once you have all necessary dependencies it is time to generate the project Once you have all necessary dependencies it is time to generate the project
files or makefiles for your development environment. CMake needs to know two files or makefiles for your development environment. CMake needs two paths for
paths for this: the path to the _root_ directory of the GLFW source tree (i.e. this:
_not_ the `src` subdirectory) and the target path for the generated files and
compiled binaries. If these are the same, it is called an in-tree build,
otherwise it is called an out-of-tree build.
One of several advantages of out-of-tree builds is that you can generate files - the path to the root directory of the GLFW source tree (not its `src`
and compile for different development environments using a single source tree. subdirectory)
- the path to the directory where the generated build files and compiled
binaries will be placed
@note This section is about generating the project files or makefiles necessary If these are the same, it is called an in-tree build, otherwise it is called an
to compile the GLFW library, not about compiling the actual library. out-of-tree build.
Out-of-tree builds are recommended as they avoid cluttering up the source tree.
They also allow you to have several build directories for different
configurations all using the same source tree.
A common pattern when building a single configuration is to have a build
directory named `build` in the root of the source tree.
@subsubsection compile_generate_cli Generating files with the CMake command-line tool @subsubsection compile_generate_gui Generating with the CMake GUI
To make an in-tree build, enter the _root_ directory of the GLFW source tree Start the CMake GUI and set the paths to the source and build directories
(i.e. _not_ the `src` subdirectory) and run CMake. The current directory is described above. Then press _Configure_ and _Generate_.
used as target path, while the path provided as an argument is used to find the
source tree.
@code{.sh} If you wish change any CMake variables in the list, press _Configure_ and then
cd <glfw-root-dir> _Generate_ to have the new values take effect. The variable list will be
cmake . populated after the first configure step.
@endcode
To make an out-of-tree build, make a directory outside of the source tree, enter By default, GLFW will use X11 on Linux and other Unix-like systems other than macOS. To
it and run CMake with the (relative or absolute) path to the root of the source include support for Wayland as well, set the @ref GLFW_BUILD_WAYLAND option in the GLFW
tree as an argument. section of the variable list, then apply the new value as described above.
@code{.sh}
mkdir glfw-build
cd glfw-build
cmake <glfw-root-dir>
@endcode
Once you have generated the project files or makefiles for your chosen Once you have generated the project files or makefiles for your chosen
development environment, move on to @ref compile_compile. development environment, move on to @ref compile_compile.
@subsubsection compile_generate_gui Generating files with the CMake GUI @subsubsection compile_generate_cli Generating with command-line CMake
If you are using the GUI version, choose the root of the GLFW source tree as To make a build directory, pass the source and build directories to the `cmake`
source location and the same directory or another, empty directory as the command. These can be relative or absolute paths. The build directory is
destination for binaries. Choose _Configure_, change any options you wish to, created if it doesn't already exist.
_Configure_ again to let the changes take effect and then _Generate_.
@code{.sh}
cmake -S path/to/glfw -B path/to/build
@endcode
It is common to name the build directory `build` and place it in the root of the
source tree when only planning to build a single configuration.
@code{.sh}
cd path/to/glfw
cmake -S . -B build
@endcode
Without other flags these will generate Visual Studio project files on Windows
and makefiles on other platforms. You can choose other targets using the `-G`
flag.
@code{.sh}
cmake -S path/to/glfw -B path/to/build -G Xcode
@endcode
By default, GLFW will use X11 on Linux and other Unix-like systems other
than macOS. To also include support for Wayland, set the @ref GLFW_BUILD_WAYLAND CMake
option.
@code{.sh}
cmake -S path/to/glfw -B path/to/build -D GLFW_BUILD_WAYLAND=1
@endcode
Once you have generated the project files or makefiles for your chosen Once you have generated the project files or makefiles for your chosen
development environment, move on to @ref compile_compile. development environment, move on to @ref compile_compile.
@ -178,13 +192,39 @@ development environment, move on to @ref compile_compile.
You should now have all required dependencies and the project files or makefiles You should now have all required dependencies and the project files or makefiles
necessary to compile GLFW. Go ahead and compile the actual GLFW library with necessary to compile GLFW. Go ahead and compile the actual GLFW library with
these files, as you would with any other project. these files as you would with any other project.
Once the GLFW library is compiled, you are ready to build your applications, With Visual Studio open `GLFW.sln` and use the Build menu. With Xcode open
`GLFW.xcodeproj` and use the Project menu.
With Linux, macOS and other forms of Unix, run `make`.
@code{.sh}
cd path/to/build
make
@endcode
With MinGW, it is `mingw32-make`.
@code{.sh}
cd path/to/build
mingw32-make
@endcode
Any CMake build directory can also be built with the `cmake` command and the
`--build` flag.
@code{.sh}
cmake --build path/to/build
@endcode
This will run the platform specific build tool the directory was generated for.
Once the GLFW library is compiled you are ready to build your application,
linking it to the GLFW library. See @ref build_guide for more information. linking it to the GLFW library. See @ref build_guide for more information.
@subsection compile_options CMake options @section compile_options CMake options
The CMake files for GLFW provide a number of options, although not all are The CMake files for GLFW provide a number of options, although not all are
available on all supported platforms. Some of these are de facto standards available on all supported platforms. Some of these are de facto standards
@ -200,89 +240,153 @@ Finally, if you don't want to use any GUI, you can set options from the `cmake`
command-line with the `-D` flag. command-line with the `-D` flag.
@code{.sh} @code{.sh}
cmake -DBUILD_SHARED_LIBS=ON . cmake -S path/to/glfw -B path/to/build -D BUILD_SHARED_LIBS=ON
@endcode @endcode
@subsubsection compile_options_shared Shared CMake options @subsection compile_options_shared Shared CMake options
@anchor BUILD_SHARED_LIBS @anchor BUILD_SHARED_LIBS
__BUILD_SHARED_LIBS__ determines whether GLFW is built as a static __BUILD_SHARED_LIBS__ determines whether GLFW is built as a static library or as
library or as a DLL / shared library / dynamic library. a DLL / shared library / dynamic library. This is disabled by default,
producing a static GLFW library. This variable has no `GLFW_` prefix because it
is defined by CMake. If you want to change the library only for GLFW when it is
part of a larger project, see @ref GLFW_LIBRARY_TYPE.
@anchor GLFW_LIBRARY_TYPE
__GLFW_LIBRARY_TYPE__ allows you to override @ref BUILD_SHARED_LIBS only for
GLFW, without affecting other libraries in a larger project. When set, the
value of this option must be a valid CMake library type. Set it to `STATIC` to
build GLFW as a static library, `SHARED` to build it as a shared library
/ dynamic library / DLL, or `OBJECT` to make GLFW a CMake object 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 subproject of a larger CMake 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 subproject of a larger CMake 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
with the library. with the library. This is enabled by default if
[Doxygen](https://www.doxygen.nl/) is found by CMake during configuration.
@anchor GLFW_VULKAN_STATIC
__GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
directly with the application.
@subsubsection compile_options_win32 Windows specific CMake options @subsection compile_options_win32 Win32 specific CMake options
@anchor GLFW_BUILD_WIN32
__GLFW_BUILD_WIN32__ determines whether to include support for Win32 when compiling the
library. This option is only available when compiling for Windows. This is enabled by
default.
@anchor USE_MSVC_RUNTIME_LIBRARY_DLL @anchor USE_MSVC_RUNTIME_LIBRARY_DLL
__USE_MSVC_RUNTIME_LIBRARY_DLL__ determines whether to use the DLL version or the __USE_MSVC_RUNTIME_LIBRARY_DLL__ determines whether to use the DLL version or the
static library version of the Visual C++ runtime library. If set to `ON`, the static library version of the Visual C++ runtime library. When enabled, the
DLL version of the Visual C++ library is used. DLL version of the Visual C++ library is used. This is enabled by default.
On CMake 3.15 and later you can set the standard CMake
[CMAKE_MSVC_RUNTIME_LIBRARY](https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html)
variable instead of this GLFW-specific option.
@anchor GLFW_USE_HYBRID_HPG @anchor GLFW_USE_HYBRID_HPG
__GLFW_USE_HYBRID_HPG__ determines whether to export the `NvOptimusEnablement` and __GLFW_USE_HYBRID_HPG__ determines whether to export the `NvOptimusEnablement` and
`AmdPowerXpressRequestHighPerformance` symbols, which force the use of the `AmdPowerXpressRequestHighPerformance` symbols, which force the use of the
high-performance GPU on Nvidia Optimus and AMD PowerXpress systems. These symbols high-performance GPU on Nvidia Optimus and AMD PowerXpress systems. These symbols
need to be exported by the EXE to be detected by the driver, so the override need to be exported by the EXE to be detected by the driver, so the override
will not work if GLFW is built as a DLL. will not work if GLFW is built as a DLL. This is disabled by default, letting
the operating system and driver decide.
@subsection compile_options_macos macOS specific CMake options
@anchor GLFW_BUILD_COCOA
__GLFW_BUILD_COCOA__ determines whether to include support for Cocoa when compiling the
library. This option is only available when compiling for macOS. This is enabled by
default.
@subsection compile_options_unix Unix-like system specific CMake options
@anchor GLFW_BUILD_WAYLAND
__GLFW_BUILD_WAYLAND__ determines whether to include support for Wayland when compiling
the library. This option is only available when compiling for Linux and other Unix-like
systems other than macOS. This is disabled by default.
@anchor GLFW_BUILD_X11
__GLFW_BUILD_X11__ determines whether to include support for X11 when compiling the
library. This option is only available when compiling for Linux and other Unix-like
systems other than macOS. This is enabled by default.
@section compile_mingw_cross Cross-compilation with CMake and MinGW
Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For
example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages
for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives
like Ubuntu have the `mingw-w64` package for both.
GLFW has CMake toolchain files in the `CMake` subdirectory that set up
cross-compilation of Windows binaries. To use these files you set the
`CMAKE_TOOLCHAIN_FILE` CMake variable with the `-D` flag add an option when
configuring and generating the build files.
@code{.sh}
cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=path/to/file
@endcode
The exact toolchain file to use depends on the prefix used by the MinGW or
MinGW-w64 binaries on your system. You can usually see this in the /usr
directory. For example, both the Ubuntu and Cygwin MinGW-w64 packages have
`/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct invocation
would be:
@code{.sh}
cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake
@endcode
The path to the toolchain file is relative to the path to the GLFW source tree
passed to the `-S` flag, not to the current directory.
For more details see the
[CMake toolchain guide](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html).
@section compile_manual Compiling GLFW manually @section compile_manual Compiling GLFW manually
If you wish to compile GLFW without its CMake build environment then you will If you wish to compile GLFW without its CMake build environment then you will have to do
have to do at least some of the platform detection yourself. GLFW needs at least some platform-detection yourself. There are preprocessor macros for
a configuration macro to be defined in order to know what window system it's enabling support for the platforms (window systems) available. There are also optional,
being compiled for and also has optional, platform-specific ones for various platform-specific macros for various features.
features.
When building with CMake, the `glfw_config.h` configuration header is generated When building, GLFW will expect the necessary configuration macros to be defined
based on the current platform and CMake options. The GLFW CMake environment on the command-line. The GLFW CMake files set these as private compile
defines @b GLFW_USE_CONFIG_H, which causes this header to be included by definitions on the GLFW target but if you compile the GLFW sources manually you
`internal.h`. Without this macro, GLFW will expect the necessary configuration will need to define them yourself.
macros to be defined on the command-line.
The window creation API is used to create windows, handle input, monitors, gamma The window system is used to create windows, handle input, monitors, gamma ramps and
ramps and clipboard. The options are: clipboard. The options are:
- @b _GLFW_COCOA to use the Cocoa frameworks - @b _GLFW_COCOA to use the Cocoa frameworks
- @b _GLFW_WIN32 to use the Win32 API - @b _GLFW_WIN32 to use the Win32 API
- @b _GLFW_X11 to use the X Window System - @b _GLFW_X11 to use the X Window System
- @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete) - @b _GLFW_WAYLAND to use the Wayland API (incomplete)
- @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)
The @b _GLFW_WAYLAND and @b _GLFW_X11 macros may be combined and produces a library that
attempts to detect the appropriate platform at initialization.
If you are building GLFW as a shared library / dynamic library / DLL then you If you are building GLFW as a shared library / dynamic library / DLL then you
must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it. must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it.
If you are linking the Vulkan loader directly with your application then you
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
external version.
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1 If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
or GLESv2 library, you can override the default names by defining those you need or GLESv2 library, you can override the default names by defining those you need
of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
_GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b _GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b
_GLFW_GLESV2_LIBRARY. Otherwise, GLFW will use the built-in default names. _GLFW_GLESV2_LIBRARY. Otherwise, GLFW will use the built-in default names.
For the EGL context creation API, the following options are available:
- @b _GLFW_USE_EGLPLATFORM_H to use an existing `EGL/eglplatform.h` header file
for native handle types (fallback)
@note None of the @ref build_macros may be defined during the compilation of @note None of the @ref build_macros may be defined during the compilation of
GLFW. If you define any of these in your build files, make sure they are not GLFW. If you define any of these in your build files, make sure they are not
applied to the GLFW sources. applied to the GLFW sources.

View File

@ -61,7 +61,7 @@ information. The name and number of this chapter unfortunately varies between
versions and APIs, but has at times been named _Shared Objects and Multiple versions and APIs, but has at times been named _Shared Objects and Multiple
Contexts_. Contexts_.
GLFW comes with a barebones object sharing example program called `sharing`. GLFW comes with a bare-bones object sharing example program called `sharing`.
@subsection context_offscreen Offscreen contexts @subsection context_offscreen Offscreen contexts
@ -84,10 +84,6 @@ objects are recommended for rendering with such contexts.
You should still [process events](@ref events) as long as you have at least one You should still [process events](@ref events) as long as you have at least one
window, even if none of them are visible. window, even if none of them are visible.
@macos The first time a window is created the menu bar is created. This is not
desirable for example when writing a command-line only application. Menu bar
creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
@subsection context_less Windows without contexts @subsection context_less Windows without contexts
@ -142,9 +138,9 @@ as extensions until they become obsolete.
An extension is defined by: An extension is defined by:
- An extension name (e.g. `GL_ARB_debug_output`) - An extension name (e.g. `GL_ARB_gl_spirv`)
- New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`) - New OpenGL tokens (e.g. `GL_SPIR_V_BINARY_ARB`)
- New OpenGL functions (e.g. `glGetDebugMessageLogARB`) - New OpenGL functions (e.g. `glSpecializeShaderARB`)
Note the `ARB` affix, which stands for Architecture Review Board and is used Note the `ARB` affix, which stands for Architecture Review Board and is used
for official extensions. The extension above was created by the ARB, but there for official extensions. The extension above was created by the ARB, but there
@ -193,7 +189,7 @@ it suppresses the development environment's OpenGL or OpenGL ES header.
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
Finally you need to initialize glad once you have a suitable current context. Finally, you need to initialize glad once you have a suitable current context.
@code @code
window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
@ -209,7 +205,7 @@ gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
Once glad has been loaded, you have access to all OpenGL core and extension Once glad has been loaded, you have access to all OpenGL core and extension
functions supported by both the context you created and the glad loader you functions supported by both the context you created and the glad loader you
generated and you are ready to start rendering. generated. After that, you are ready to start rendering.
You can specify a minimum required OpenGL or OpenGL ES version with You can specify a minimum required OpenGL or OpenGL ES version with
[context hints](@ref window_hints_ctx). If your needs are more complex, you can [context hints](@ref window_hints_ctx). If your needs are more complex, you can
@ -229,9 +225,9 @@ To check whether a specific extension is supported, use the `GLAD_GL_xxx`
booleans. booleans.
@code @code
if (GLAD_GL_ARB_debug_output) if (GLAD_GL_ARB_gl_spirv)
{ {
// Use GL_ARB_debug_output // Use GL_ARB_gl_spirv
} }
@endcode @endcode
@ -263,8 +259,8 @@ included in your development environment may be several years out of date and
may not include the extensions you wish to use. may not include the extensions you wish to use.
The header defines function pointer types for all functions of all extensions it The header defines function pointer types for all functions of all extensions it
supports. These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for supports. These have names like `PFNGLSPECIALIZESHADERARBPROC` (for
`glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer `glSpecializeShaderARB`), i.e. the name is made uppercase and `PFN` (pointer
to function) and `PROC` (procedure) are added to the ends. to function) and `PROC` (procedure) are added to the ends.
To include the extension header, define @ref GLFW_INCLUDE_GLEXT before including To include the extension header, define @ref GLFW_INCLUDE_GLEXT before including
@ -284,7 +280,7 @@ is necessary to check at run-time whether the context supports the extension.
This is done with @ref glfwExtensionSupported. This is done with @ref glfwExtensionSupported.
@code @code
if (glfwExtensionSupported("GL_ARB_debug_output")) if (glfwExtensionSupported("GL_ARB_gl_spirv"))
{ {
// The extension is supported by the current context // The extension is supported by the current context
} }
@ -303,7 +299,7 @@ your operating system, making it necessary to fetch them at run time. You can
retrieve pointers to these functions with @ref glfwGetProcAddress. retrieve pointers to these functions with @ref glfwGetProcAddress.
@code @code
PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB"); PFNGLSPECIALIZESHADERARBPROC pfnSpecializeShaderARB = glfwGetProcAddress("glSpecializeShaderARB");
@endcode @endcode
In general, you should avoid giving the function pointer variables the (exact) In general, you should avoid giving the function pointer variables the (exact)
@ -317,28 +313,28 @@ when used together.
#define GLFW_INCLUDE_GLEXT #define GLFW_INCLUDE_GLEXT
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#define glGetDebugMessageLogARB pfnGetDebugMessageLog #define glSpecializeShaderARB pfnSpecializeShaderARB
PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog; PFNGLSPECIALIZESHADERARBPROC pfnSpecializeShaderARB;
// Flag indicating whether the extension is supported // Flag indicating whether the extension is supported
int has_ARB_debug_output = 0; int has_ARB_gl_spirv = 0;
void load_extensions(void) void load_extensions(void)
{ {
if (glfwExtensionSupported("GL_ARB_debug_output")) if (glfwExtensionSupported("GL_ARB_gl_spirv"))
{ {
pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC) pfnSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC)
glfwGetProcAddress("glGetDebugMessageLogARB"); glfwGetProcAddress("glSpecializeShaderARB");
has_ARB_debug_output = 1; has_ARB_gl_spirv = 1;
} }
} }
void some_function(void) void some_function(void)
{ {
if (has_ARB_debug_output) if (has_ARB_gl_spirv)
{ {
// Now the extension function can be called as usual // Now the extension function can be called as usual
glGetDebugMessageLogARB(...); glSpecializeShaderARB(...);
} }
} }
@endcode @endcode

File diff suppressed because one or more lines are too long

7
docs/extra.css.map Normal file
View File

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AA8EA,2GAA4G,CAC3G,UAAU,CAAC,IAAI,CACf,WAAW,CAAC,IAAI,CAGjB,wBAAyB,CACxB,YAAY,CAAC,2CAAsD,CAGpE,4HAA6H,CAC5H,YAAY,CAAC,wCAAuD,CAGrE,wIAAyI,CACxI,YAAY,CAAC,wCAAuD,CAGrE,kBAAmB,CAClB,UAAU,CA9EgB,IAAa,CA+EvC,WAAW,CAAC,IAAI,CAGjB,sBAAuB,CACtB,KAAK,CAzFe,OAAa,CA0FjC,WAAW,CAAC,IAAI,CAGjB,4UAA6U,CAC5U,UAAU,CAAC,IAAI,CAGhB,kJAAmJ,CAClJ,MAAM,CAAC,IAAI,CAGZ,wHAAyH,CACxH,WAAW,CAAC,IAAI,CAGjB,qBAAsB,CACrB,UAAU,CAAC,IAAI,CAGhB,2LAA4L,CAC3L,OAAO,CAAC,CAAC,CAGV,wCAAyC,CACxC,OAAO,CAAC,IAAI,CAGb,iMAAkM,CACjM,UAAU,CApGW,OAA+B,CAuGrD,IAAK,CACJ,KAAK,CA1He,OAAa,CA6HlC,SAAU,CACN,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,aAAa,CAGzB,qDAAsD,CACrD,KAAK,CApHU,OAAa,CAqH5B,aAAa,CAAC,IAAI,CAGnB,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,SAAS,CAAC,IAAI,CAGf,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,aAAa,CAAC,CAAC,CACf,SAAS,CAAC,IAAI,CAGf,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,aAAa,CAAC,CAAC,CACf,SAAS,CAAC,IAAI,CAGf,WAAY,CACX,SAAS,CAAC,IAAI,CACd,UAAU,CAAC,IAAI,CACf,SAAS,CAAC,KAAK,CACf,OAAO,CAAC,MAAM,CACd,MAAM,CAAC,MAAM,CAEb,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,CACnB,SAAS,CAAE,IAAI,CACf,eAAe,CAAE,UAAU,CAC3B,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,OAAO,CAGvB,SAAU,CACT,WAAW,CAAC,IAAI,CAChB,aAAa,CAAC,IAAI,CAClB,KAAK,CApKqB,IAAa,CAqKvC,SAAS,CAAC,KAAK,CACf,UAAU,CAAC,yDAAyD,CAGrE,WAAY,CACX,eAAe,CAAC,IAAI,CACpB,MAAM,CAAC,UAAU,CACjB,KAAK,CAAC,KAAK,CAGZ,wBAAyB,CACxB,KAAK,CAAC,IAAI,CAGX,mCAAoC,CACnC,WAAW,CAAC,IAAI,CAChB,WAAW,CAAC,GAAG,CACf,OAAO,CAAC,KAAK,CACb,KAAK,CAvLqB,IAAa,CA0LxC,WAAY,CACX,YAAY,CAAE,CAAC,CAGhB,6CAA8C,CAC7C,UAAU,CAAC,SAAS,CAGrB,kBAAmB,CAClB,KAAK,CAnMqB,IAAa,CAsMxC,cAAe,CACd,UAAU,CAAC,MAAM,CACjB,OAAO,CAAC,GAAG,CACX,UAAU,CAAC,GAAG,CAGf,IAAK,CACJ,UAAU,CA7MgB,IAAa,CAgNxC,SAAU,CACT,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,SAAS,CAAC,IAAI,CAGf,UAAW,CACV,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,SAAS,CAAC,IAAI,CAGf,SAAU,CACT,OAAO,CAAC,IAAI,CAGb,kBAAmB,CAClB,WAAW,CAAC,IAAI,CAChB,WAAW,CAAC,IAAI,CAGjB,UAAW,CACV,UAAU,CAAC,IAAI,CACf,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,CACnB,SAAS,CAAE,IAAI,CACf,eAAe,CAAE,UAAU,CAC3B,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,OAAO,CAGvB,kEAAmE,CAClE,KAAK,CApOgB,OAA+B,CAuOrD,+BAAgC,CAC/B,KAAK,CA1Pe,OAAa,CA6PlC,qCAAsC,CACrC,KAAK,CA1NoB,IAAsB,CA6NhD,wBAA2B,CAC1B,MAAM,CAAE,UAAU,CAGnB,SAAU,CACT,UAAU,CAAC,KAAK,CAGjB,uBAAwB,CACvB,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,OAAO,CAAC,MAAM,CACd,UAAU,CAAC,SAA8B,CAG1C,sDAAuD,CACtD,UAAU,CAAC,iDAAoF,CAC/F,UAAU,CAAC,mBAAuC,CAClD,WAAW,CAAC,kBAAgD,CAC5D,UAAU,CAAC,IAAI,CACf,KAAK,CAlPa,IAAe,CAqPlC,kBAAmB,CAClB,KAAK,CArPoB,IAAsB,CAsP/C,OAAO,CAAC,IAAI,CACZ,aAAa,CAAC,GAAG,CACjB,gBAAgB,CAAC,OAAiC,CAGnD,OAAQ,CACP,KAAK,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAGV,oCAAoC,CACnC,OAAQ,CACP,KAAK,CAAC,IAAI,CACV,KAAK,CAAC,OAAO,CACb,MAAM,CAAC,CAAC,EAIV,UAAW,CACV,SAAS,CAAC,MAAM,CAGjB,UAAW,CACV,YAAY,CAAC,KAAK,CAGnB,UAAW,CACV,SAAS,CAAC,GAAG,CACb,YAAY,CAAC,CAAC,CACd,eAAe,CAAC,IAAI,CAIjB,mCAAqB,CACjB,WAAW,CAAC,KAAK,CAIzB,mCAAoC,CACnC,UAAU,CAAC,oDAAgF,CAC3F,UAAU,CAAC,sBAAqC,CAChD,WAAW,CAAC,cAA8C,CAC1D,KAAK,CArTU,OAAa,CAsT5B,MAAM,CAAC,iBAAgC,CACvC,aAAa,CAAC,GAAG,CAGlB,UAAW,CACV,KAAK,CA9RkB,OAAgC,CAiSxD,aAAc,CACb,MAAM,CAAC,cAA+B,CACtC,sBAAsB,CAAC,GAAG,CAC1B,uBAAuB,CAAC,GAAG,CAC3B,aAAa,CAAC,IAAI,CAGnB,aAAc,CACb,MAAM,CAAC,cAA+B,CACtC,0BAA0B,CAAC,GAAG,CAC9B,yBAAyB,CAAC,GAAG,CAC7B,UAAU,CAAC,IAAI,CAGhB,kCAAmC,CAClC,eAAe,CAAC,OAAO,CACvB,cAAc,CAAC,CAAC,CAChB,MAAM,CAAC,cAA+B,CACtC,aAAa,CAAC,GAAG,CAGlB,+HAAgI,CAC/H,KAAK,CA/ToB,IAAsB,CAgU/C,eAAe,CAAC,IAAI,CAGrB,aAAc,CACb,eAAe,CAAC,OAAO,CACvB,cAAc,CAAC,CAAC,CAChB,MAAM,CAAC,cAA+B,CACtC,aAAa,CAAC,GAAG,CAGlB,gBAAiB,CAChB,MAAM,CAAC,GAAG,CACV,UAAU,CAAC,gEAAiH,CAG7H,mCAAoC,CAvTnC,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAwT3D,uBAAwB,CA3TvB,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CA4T3D,oBAAqB,CA/TpB,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAgU3D,eAAgB,CAnUf,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAoU3D,gGAAiG,CAChG,aAAa,CAAC,GAAG,CACjB,OAAO,CAAC,GAAG,CACX,WAAW,CAAC,cAAwB,CACpC,MAAM,CAAC,KAAK,CAGb,iRAAkR,CACjR,KAAK,CAAC,OAAO,CAGd,QAAS,CACR,WAAW,CAAC,OAAO,CAGpB,yBAA0B,CACzB,UAAU,CAAC,OAAa,CACxB,aAAa,CAAC,GAAG,CACjB,MAAM,CAAC,IAAI,CACX,OAAO,CAAC,GAAG,CACX,QAAQ,CAAC,IAAI,CACb,WAAW,CAAC,cAAuB,CACnC,MAAM,CAAC,KAAK,CAGb,8CAA+C,CAC9C,KAAK,CA7Ze,OAAa,CAgalC,8BAA+B,CAC9B,KAAK,CAAC,OAAiB,CAGxB,qBAAsB,CACrB,KAAK,CAAC,OAAgB,CAGvB,8CAA+C,CAC9C,KAAK,CAAC,OAA+B,CACrC,WAAW,CAAC,IAAI,CAGjB,kBAAmB,CAClB,KAAK,CAAC,OAAiB,CAGxB,IAAK,CACJ,OAAO,CAAC,IAAI,CACZ,aAAa,CAAC,GAAG",
"sources": ["extra.scss"],
"names": [],
"file": "extra.css"
}

View File

@ -1,106 +1,106 @@
// NOTE: Please use this file to perform modifications on default style sheets. // NOTE: Please use this file to perform modifications on default style sheets.
// //
// You need to install a few Ruby gems to generate extra.css from this file: // You need to install the official Sass CLI tool:
// gem install less therubyracer // npm install -g sass
// //
// Run this command to regenerate extra.css after you're finished with changes: // Run this command to regenerate extra.css after you're finished with changes:
// lessc --compress extra.less > extra.css // sass --style=compressed extra.scss extra.css
// //
// Alternatively you can use online services to regenerate extra.css. // Alternatively you can use online services to regenerate extra.css.
// Default text color for page contents // Default text color for page contents
@default-text-color: hsl(0,0%,30%); $default-text-color: hsl(0,0%,30%);
// Page header, footer, table rows, inline codes and definition lists // Page header, footer, table rows, inline codes and definition lists
@header-footer-background-color: hsl(0,0%,95%); $header-footer-background-color: hsl(0,0%,95%);
// Page header, footer links and navigation bar background // Page header, footer links and navigation bar background
@header-footer-link-color: hsl(0,0%,40%); $header-footer-link-color: hsl(0,0%,40%);
// Doxygen navigation bar links // Doxygen navigation bar links
@navbar-link-color: @header-footer-background-color; $navbar-link-color: $header-footer-background-color;
// Page content background color // Page content background color
@content-background-color: hsl(0,0%,100%); $content-background-color: hsl(0,0%,100%);
// Bold, italic, h1, h2, ... and table of contents // Bold, italic, h1, h2, ... and table of contents
@heading-color: hsl(0,0%,10%); $heading-color: hsl(0,0%,10%);
// Function, enum and macro definition separator // Function, enum and macro definition separator
@def-separator-color: @header-footer-background-color; $def-separator-color: $header-footer-background-color;
// Base color hue // Base color hue
@base-hue: 24; $base-hue: 24;
// Default color used for links // Default color used for links
@default-link-color: hsl(@base-hue,100%,50%); $default-link-color: hsl($base-hue,100%,50%);
// Doxygen navigation bar active tab // Doxygen navigation bar active tab
@tab-text-color: hsl(0,0%,100%); $tab-text-color: hsl(0,0%,100%);
@tab-background-color1: @default-link-color; $tab-background-color1: $default-link-color;
@tab-background-color2: lighten(spin(@tab-background-color1, 10), 10%); $tab-background-color2: lighten(adjust-hue($tab-background-color1, 10), 10%);
// Table borders // Table borders
@default-border-color: @default-link-color; $default-border-color: $default-link-color;
// Table header // Table header
@table-text-color: @tab-text-color; $table-text-color: $tab-text-color;
@table-background-color1: @tab-background-color1; $table-background-color1: $tab-background-color1;
@table-background-color2: @tab-background-color2; $table-background-color2: $tab-background-color2;
// Table of contents, data structure index and prototypes // Table of contents, data structure index and prototypes
@toc-background-color1: hsl(0,0%,90%); $toc-background-color1: hsl(0,0%,90%);
@toc-background-color2: lighten(@toc-background-color1, 5%); $toc-background-color2: lighten($toc-background-color1, 5%);
// Function prototype parameters color // Function prototype parameters color
@prototype-param-color: darken(@default-link-color, 25%); $prototype-param-color: darken($default-link-color, 25%);
// Message box color: note, pre, post and invariant // Message box color: note, pre, post and invariant
@box-note-color: hsl(103,80%,85%); $box-note-color: hsl(103,80%,85%);
// Message box color: warning and attention // Message box color: warning and attention
@box-warning-color: hsl(34,80%,85%); $box-warning-color: hsl(34,80%,85%);
// Message box color: deprecated and bug // Message box color: deprecated and bug
@box-bug-color: hsl(333,80%,85%); $box-bug-color: hsl(333,80%,85%);
// Message box color: todo and test // Message box color: todo and test
@box-todo-color: hsl(200,80%,85%); $box-todo-color: hsl(200,80%,85%);
// Message box helper function // Message box helper function
.message-box(@base-color) { @mixin message-box($base-color){
background:linear-gradient(to bottom,lighten(@base-color, 5%) 0%,@base-color 100%); background:linear-gradient(to bottom,lighten($base-color, 5%) 0%,$base-color 100%);
box-shadow:inset 0 0 32px darken(@base-color, 5%); box-shadow:inset 0 0 32px darken($base-color, 5%);
color:darken(@base-color, 67%); color:darken($base-color, 67%);
border:2px solid desaturate(darken(@base-color, 10%), 20%); border:2px solid desaturate(darken($base-color, 10%), 20%);
} }
.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover { .sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover {
background:none; background:none;
text-shadow:none; text-shadow:none;
} }
.sm-dox a span.sub-arrow { .sm-dox a span.sub-arrow {
border-color:@navbar-link-color transparent transparent transparent; border-color:$navbar-link-color transparent transparent transparent;
} }
.sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow { .sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow {
border-color:@default-link-color transparent transparent transparent; border-color:$default-link-color transparent transparent transparent;
} }
.sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow { .sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow {
border-color:transparent transparent transparent @default-link-color; border-color:transparent transparent transparent $default-link-color;
} }
.sm-dox ul a:hover { .sm-dox ul a:hover {
background:@header-footer-link-color; background:$header-footer-link-color;
text-shadow:none; text-shadow:none;
} }
.sm-dox ul.sm-nowrap a { .sm-dox ul.sm-nowrap a {
color:@default-text-color; color:$default-text-color;
text-shadow:none; text-shadow:none;
} }
#main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code { #main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code {
@ -128,55 +128,66 @@ div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.a
} }
html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven { html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven {
background:@header-footer-background-color; background:$header-footer-background-color;
} }
body { body {
color:@default-text-color; color:$default-text-color;
}
div.title {
font-size: 170%;
margin: 1em 0 0.5em 0;
} }
h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em { h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em {
color:@heading-color; color:$heading-color;
border-bottom:none; border-bottom:none;
} }
h1 { h1 {
padding-top:0.5em; padding-top:0.5em;
font-size:180%; font-size:150%;
} }
h2 { h2 {
padding-top:0.5em; padding-top:0.5em;
margin-bottom:0; margin-bottom:0;
font-size:140%; font-size:130%;
} }
h3 { h3 {
padding-top:0.5em; padding-top:0.5em;
margin-bottom:0; margin-bottom:0;
font-size:110%; font-size:110%;
} }
.glfwheader { .glfwheader {
font-size:16px; font-size:16px;
height:64px; min-height:64px;
max-width:920px; max-width:920px;
min-width:800px;
padding:0 32px; padding:0 32px;
margin:0 auto; margin:0 auto;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: stretch;
} }
#glfwhome { #glfwhome {
line-height:64px; line-height:64px;
padding-right:48px; padding-right:48px;
color:@header-footer-link-color; color:$header-footer-link-color;
font-size:2.5em; font-size:2.5em;
background:url("https://www.glfw.org/css/arrow.png") no-repeat right; background:url("https://www.glfw.org/css/arrow.png") no-repeat right;
} }
.glfwnavbar { .glfwnavbar {
list-style-type:none; list-style-type:none;
margin:0 auto; margin:0 0 0 auto;
float:right; float:right;
} }
@ -188,7 +199,11 @@ h3 {
line-height:64px; line-height:64px;
margin-left:2em; margin-left:2em;
display:block; display:block;
color:@header-footer-link-color; color:$header-footer-link-color;
}
.glfwnavbar {
padding-left: 0;
} }
#glfwhome,.glfwnavbar a,.glfwnavbar a:visited { #glfwhome,.glfwnavbar a,.glfwnavbar a:visited {
@ -196,7 +211,7 @@ h3 {
} }
#titlearea,.footer { #titlearea,.footer {
color:@header-footer-link-color; color:$header-footer-link-color;
} }
address.footer { address.footer {
@ -206,48 +221,54 @@ address.footer {
} }
#top { #top {
background:@header-footer-link-color; background:$header-footer-link-color;
} }
#main-nav { #main-nav {
max-width:960px; max-width:960px;
min-width:800px;
margin:0 auto; margin:0 auto;
font-size:13px; font-size:13px;
} }
#main-menu { #main-menu {
max-width:920px; max-width:920px;
min-width:800px;
margin:0 auto; margin:0 auto;
font-size:13px; font-size:13px;
} }
.memtitle { .memtitle {
display:none; display:none;
} }
.memproto,.memname { .memproto,.memname {
font-weight:bold; font-weight:bold;
text-shadow:none; text-shadow:none;
} }
#main-menu { #main-menu {
height:36px; min-height:36px;
display:block; display: flex;
position:relative; flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: stretch;
} }
#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li { #main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li {
color:@navbar-link-color; color:$navbar-link-color;
} }
#main-menu li ul.sm-nowrap li a { #main-menu li ul.sm-nowrap li a {
color:@default-text-color; color:$default-text-color;
} }
#main-menu li ul.sm-nowrap li a:hover { #main-menu li ul.sm-nowrap li a:hover {
color:@default-link-color; color:$default-link-color;
}
#main-menu > li:last-child {
margin: 0 0 0 auto;
} }
.contents { .contents {
@ -258,27 +279,35 @@ div.contents,div.header {
max-width:920px; max-width:920px;
margin:0 auto; margin:0 auto;
padding:0 32px; padding:0 32px;
background:@content-background-color none; background:$content-background-color none;
} }
table.doxtable th,table.markdownTable th,dl.reflist dt { table.doxtable th,table.markdownTable th,dl.reflist dt {
background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%); background:linear-gradient(to bottom,$table-background-color2 0%,$table-background-color1 100%);
box-shadow:inset 0 0 32px @table-background-color1; box-shadow:inset 0 0 32px $table-background-color1;
text-shadow:0 -1px 1px darken(@table-background-color1, 15%); text-shadow:0 -1px 1px darken($table-background-color1, 15%);
text-align:left; text-align:left;
color:@table-text-color; color:$table-text-color;
} }
dl.reflist dt a.el { dl.reflist dt a.el {
color:@default-link-color; color:$default-link-color;
padding:.2em; padding:.2em;
border-radius:4px; border-radius:4px;
background-color:lighten(@default-link-color, 40%); background-color:lighten($default-link-color, 40%);
} }
div.toc { div.toc {
float:none; float:right;
width:auto; width:35%;
}
@media screen and (max-width:600px) {
div.toc {
float:none;
width:inherit;
margin:0;
}
} }
div.toc h3 { div.toc h3 {
@ -295,28 +324,34 @@ div.toc li {
list-style-type:disc; list-style-type:disc;
} }
div.toc {
li.level2, li.level3 {
margin-left:0.5em;
}
}
div.toc,.memproto,div.qindex,div.ah { div.toc,.memproto,div.qindex,div.ah {
background:linear-gradient(to bottom,@toc-background-color2 0%,@toc-background-color1 100%); background:linear-gradient(to bottom,$toc-background-color2 0%,$toc-background-color1 100%);
box-shadow:inset 0 0 32px @toc-background-color1; box-shadow:inset 0 0 32px $toc-background-color1;
text-shadow:0 1px 1px lighten(@toc-background-color2, 10%); text-shadow:0 1px 1px lighten($toc-background-color2, 10%);
color:@heading-color; color:$heading-color;
border:2px solid @toc-background-color1; border:2px solid $toc-background-color1;
border-radius:4px; border-radius:4px;
} }
.paramname { .paramname {
color:@prototype-param-color; color:$prototype-param-color;
} }
dl.reflist dt { dl.reflist dt {
border:2px solid @default-border-color; border:2px solid $default-border-color;
border-top-left-radius:4px; border-top-left-radius:4px;
border-top-right-radius:4px; border-top-right-radius:4px;
border-bottom:none; border-bottom:none;
} }
dl.reflist dd { dl.reflist dd {
border:2px solid @default-border-color; border:2px solid $default-border-color;
border-bottom-right-radius:4px; border-bottom-right-radius:4px;
border-bottom-left-radius:4px; border-bottom-left-radius:4px;
border-top:none; border-top:none;
@ -325,41 +360,41 @@ dl.reflist dd {
table.doxtable,table.markdownTable { table.doxtable,table.markdownTable {
border-collapse:inherit; border-collapse:inherit;
border-spacing:0; border-spacing:0;
border:2px solid @default-border-color; border:2px solid $default-border-color;
border-radius:4px; border-radius:4px;
} }
a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,#main-menu a:hover,span.lineno a:hover { a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,#main-menu a:hover,span.lineno a:hover {
color:@default-link-color; color:$default-link-color;
text-decoration:none; text-decoration:none;
} }
div.directory { div.directory {
border-collapse:inherit; border-collapse:inherit;
border-spacing:0; border-spacing:0;
border:2px solid @default-border-color; border:2px solid $default-border-color;
border-radius:4px; border-radius:4px;
} }
hr,.memSeparator { hr,.memSeparator {
height:2px; height:2px;
background:linear-gradient(to right,@def-separator-color 0%,darken(@def-separator-color, 10%) 50%,@def-separator-color 100%); background:linear-gradient(to right,$def-separator-color 0%,darken($def-separator-color, 10%) 50%,$def-separator-color 100%);
} }
dl.note,dl.pre,dl.post,dl.invariant { dl.note,dl.pre,dl.post,dl.invariant {
.message-box(@box-note-color); @include message-box($box-note-color);
} }
dl.warning,dl.attention { dl.warning,dl.attention {
.message-box(@box-warning-color); @include message-box($box-warning-color);
} }
dl.deprecated,dl.bug { dl.deprecated,dl.bug {
.message-box(@box-bug-color); @include message-box($box-bug-color);
} }
dl.todo,dl.test { dl.todo,dl.test {
.message-box(@box-todo-color); @include message-box($box-todo-color);
} }
dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test { dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test {
@ -388,7 +423,7 @@ div.fragment,pre.fragment {
} }
.lineno a,.lineno a:visited,.line,pre.fragment { .lineno a,.lineno a:visited,.line,pre.fragment {
color:@default-text-color; color:$default-text-color;
} }
span.preprocessor,span.comment { span.preprocessor,span.comment {
@ -400,7 +435,7 @@ a.code,a.code:visited {
} }
span.keyword,span.keywordtype,span.keywordflow { span.keyword,span.keywordtype,span.keywordflow {
color:darken(@default-text-color, 5%); color:darken($default-text-color, 5%);
font-weight:bold; font-weight:bold;
} }

View File

@ -1,7 +1,8 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"> <html lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=9"/> <meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/> <meta name="generator" content="Doxygen $doxygenversion"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME--> <!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->

View File

@ -24,7 +24,7 @@ All input callbacks receive a window handle. By using the
or objects from your callbacks. or objects from your callbacks.
To get a better feel for how the various events callbacks behave, run the To get a better feel for how the various events callbacks behave, run the
`events` test program. It register every callback supported by GLFW and prints `events` test program. It registers every callback supported by GLFW and prints
out all arguments provided for every event, along with time and sequence out all arguments provided for every event, along with time and sequence
information. information.
@ -123,9 +123,21 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
} }
@endcode @endcode
The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. Events with
will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example `GLFW_PRESS` and `GLFW_RELEASE` actions are emitted for every key press. Most
_E-mail_ and _Play_ keys. keys will also emit events with `GLFW_REPEAT` actions while a key is held down.
Key events with `GLFW_REPEAT` actions are intended for text input. They are
emitted at the rate set in the user's keyboard settings. At most one key is
repeated even if several keys are held down. `GLFW_REPEAT` actions should not
be relied on to know which keys are being held down or to drive animation.
Instead you should either save the state of relevant keys based on `GLFW_PRESS`
and `GLFW_RELEASE` actions, or call @ref glfwGetKey, which provides basic cached
key state.
The key will be one of the existing [key tokens](@ref keys), or
`GLFW_KEY_UNKNOWN` if GLFW lacks a token for it, for example _E-mail_ and _Play_
keys.
The scancode is unique for every key, regardless of whether it has a key token. The scancode is unique for every key, regardless of whether it has a key token.
Scancodes are platform-specific but consistent over time, so keys will have Scancodes are platform-specific but consistent over time, so keys will have
@ -300,6 +312,16 @@ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
This mode puts no limit on the motion of the cursor. This mode puts no limit on the motion of the cursor.
If you wish the cursor to be visible but confined to the content area of the
window, set the cursor mode to `GLFW_CURSOR_CAPTURED`.
@code
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED);
@endcode
The cursor will behave normally inside the content area but will not be able to
leave unless the window loses focus.
To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL`
cursor mode. cursor mode.
@ -307,6 +329,8 @@ cursor mode.
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@endcode @endcode
If the cursor was disabled, this will move it back to its last visible position.
@anchor GLFW_RAW_MOUSE_MOTION @anchor GLFW_RAW_MOUSE_MOTION
@subsection raw_mouse_motion Raw mouse motion @subsection raw_mouse_motion Raw mouse motion
@ -370,15 +394,18 @@ sequential rows, starting from the top-left corner.
@subsubsection cursor_standard Standard cursor creation @subsubsection cursor_standard Standard cursor creation
A cursor with a [standard shape](@ref shapes) from the current system cursor A cursor with a [standard shape](@ref shapes) from the current system cursor
theme can be can be created with @ref glfwCreateStandardCursor. theme can be created with @ref glfwCreateStandardCursor.
@code @code
GLFWcursor* 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
@ -547,10 +574,10 @@ int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
Each joystick has zero or more axes, zero or more buttons, zero or more hats, Each joystick has zero or more axes, zero or more buttons, zero or more hats,
a human-readable name, a user pointer and an SDL compatible GUID. a human-readable name, a user pointer and an SDL compatible GUID.
When GLFW is initialized, detected joysticks are added to the beginning of Detected joysticks are added to the beginning of the array. Once a joystick is
the array. Once a joystick is detected, it keeps its assigned ID until it is detected, it keeps its assigned ID until it is disconnected or the library is
disconnected or the library is terminated, so as joysticks are connected and terminated, so as joysticks are connected and disconnected, there may appear
disconnected, there may appear gaps in the IDs. gaps in the IDs.
Joystick axis, button and hat state is updated when polled and does not require Joystick axis, button and hat state is updated when polled and does not require
a window to be created or events to be processed. However, if you want joystick a window to be created or events to be processed. However, if you want joystick
@ -645,7 +672,7 @@ const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
@endcode @endcode
Joystick names are not guaranteed to be unique. Two joysticks of the same model Joystick names are not guaranteed to be unique. Two joysticks of the same model
and make may have the same name. Only the [joystick token](@ref joysticks) is and make may have the same name. Only the [joystick ID](@ref joysticks) is
guaranteed to be unique, and only until that joystick is disconnected. guaranteed to be unique, and only until that joystick is disconnected.
@ -794,6 +821,11 @@ glfwUpdateGamepadMappings(mappings);
This function supports everything from single lines up to and including the This function supports everything from single lines up to and including the
unmodified contents of the whole `gamecontrollerdb.txt` file. unmodified contents of the whole `gamecontrollerdb.txt` file.
If you are compiling GLFW from source with CMake you can update the built-in mappings by
building the _update_mappings_ target. This runs the `GenerateMappings.cmake` CMake
script, which downloads `gamecontrollerdb.txt` and regenerates the `mappings.h` header
file.
Below is a description of the mapping format. Please keep in mind that __this Below is a description of the mapping format. Please keep in mind that __this
description is not authoritative__. The format is defined by the SDL and description is not authoritative__. The format is defined by the SDL and
SDL_GameControllerDB projects and their documentation and code takes precedence. SDL_GameControllerDB projects and their documentation and code takes precedence.
@ -813,7 +845,7 @@ The second value is always the human-readable name of the gamepad.
All subsequent values are in the form `<field>:<value>` and describe the layout All subsequent values are in the form `<field>:<value>` and describe the layout
of the mapping. These fields may not all be present and may occur in any order. of the mapping. These fields may not all be present and may occur in any order.
The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`, The button fields are `a`, `b`, `x`, `y`, `back`, `start`, `guide`, `dpup`,
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and `dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
`rightstick`. `rightstick`.
@ -864,31 +896,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&nbsp;/&nbsp;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&nbsp;/&nbsp;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

View File

@ -61,12 +61,21 @@ application-provided callbacks. It is also prohibited from modifying the
platform-independent part of the internal structs. Instead, it calls the event platform-independent part of the internal structs. Instead, it calls the event
interface when events interesting to GLFW are received. interface when events interesting to GLFW are received.
The platform interface mirrors those parts of the public interface that needs to The platform interface mostly mirrors those parts of the public interface that needs to
perform platform-specific operations on some or all platforms. The are also perform platform-specific operations on some or all platforms.
named the same except that the glfw function prefix is replaced by
_glfwPlatform.
Examples: `_glfwPlatformCreateWindow` The window system bits of the platform API is called through the `_GLFWplatform` struct of
function pointers, to allow runtime selection of platform. This includes the window and
context creation, input and event processing, monitor and Vulkan surface creation parts of
GLFW. This is located in the global `_glfw` struct.
Examples: `_glfw.platform.createWindow`
The timer, threading and module loading bits of the platform API are plain functions with
a `_glfwPlatform` prefix, as these things are independent of what window system is being
used.
Examples: `_glfwPlatformGetTimerValue`
The platform interface also defines structs that contain platform-specific The platform interface also defines structs that contain platform-specific
global and per-object state. Their names mirror those of the internal global and per-object state. Their names mirror those of the internal
@ -104,8 +113,7 @@ Examples: `isValidElementForJoystick`
@section internals_config Configuration macros @section internals_config Configuration macros
GLFW uses a number of configuration macros to select at compile time which GLFW uses a number of configuration macros to select at compile time which
interfaces and code paths to use. They are defined in the glfw_config.h header file, interfaces and code paths to use. They are defined in the GLFW CMake target.
which is generated from the `glfw_config.h.in` file by CMake.
Configuration macros the same style as tokens in the public interface, except Configuration macros the same style as tokens in the public interface, except
with a leading underscore. with a leading underscore.

View File

@ -22,17 +22,20 @@ There are also guides for the other areas of GLFW.
Before most GLFW functions may be called, the library must be initialized. Before most GLFW functions may be called, the library must be initialized.
This initialization checks what features are available on the machine, This initialization checks what features are available on the machine,
enumerates monitors and joysticks, initializes the timer and performs any enumerates monitors, initializes the timer and performs any required
required platform-specific initialization. platform-specific initialization.
Only the following functions may be called before the library has been Only the following functions may be called before the library has been
successfully initialized, and only from the main thread. successfully initialized, and only from the main thread.
- @ref glfwGetVersion - @ref glfwGetVersion
- @ref glfwGetVersionString - @ref glfwGetVersionString
- @ref glfwPlatformSupported
- @ref glfwGetError - @ref glfwGetError
- @ref glfwSetErrorCallback - @ref glfwSetErrorCallback
- @ref glfwInitHint - @ref glfwInitHint
- @ref glfwInitAllocator
- @ref glfwInitVulkanLoader
- @ref glfwInit - @ref glfwInit
- @ref glfwTerminate - @ref glfwTerminate
@ -62,6 +65,11 @@ before the application exits. Modern systems are very good at freeing resources
allocated by programs that exit, but GLFW sometimes has to change global system allocated by programs that exit, but GLFW sometimes has to change global system
settings and these might not be restored without termination. settings and these might not be restored without termination.
@macos When the library is initialized the main menu and dock icon are created.
These are not desirable for a command-line only program. The creation of the
main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init
hint.
@subsection init_hints Initialization hints @subsection init_hints Initialization hints
@ -83,10 +91,33 @@ Setting these hints requires no platform specific headers or functions.
@subsubsection init_hints_shared Shared init hints @subsubsection init_hints_shared Shared init hints
@anchor GLFW_PLATFORM
__GLFW_PLATFORM__ specifies the platform to use for windowing and input.
Possible values are `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`,
`GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_X11`, `GLFW_PLATFORM_WAYLAND` and
`GLFW_PLATFORM_NULL`. The default value is `GLFW_ANY_PLATFORM`, which will
choose any platform the library includes support for except for the Null
backend.
@anchor GLFW_JOYSTICK_HAT_BUTTONS @anchor GLFW_JOYSTICK_HAT_BUTTONS
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as __GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
buttons, for compatibility with earlier versions of GLFW that did not have @ref buttons, for compatibility with earlier versions of GLFW that did not have @ref
glfwGetJoystickHats. Set this with @ref glfwInitHint. glfwGetJoystickHats. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
@anchor GLFW_ANGLE_PLATFORM_TYPE_hint
__GLFW_ANGLE_PLATFORM_TYPE__ specifies the platform type (rendering backend) to
request when using OpenGL ES and EGL via
[ANGLE](https://chromium.googlesource.com/angle/angle/). If the requested
platform type is unavailable, ANGLE will use its default. Possible values are
one of `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`,
`GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`,
`GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` and
`GLFW_ANGLE_PLATFORM_TYPE_METAL`.
The ANGLE platform type is specified via the `EGL_ANGLE_platform_angle`
extension. This extension is not used if this hint is
`GLFW_ANGLE_PLATFORM_TYPE_NONE`, which is the default value.
@subsubsection init_hints_osx macOS specific init hints @subsubsection init_hints_osx macOS specific init hints
@ -94,21 +125,135 @@ glfwGetJoystickHats. Set this with @ref glfwInitHint.
@anchor GLFW_COCOA_CHDIR_RESOURCES_hint @anchor GLFW_COCOA_CHDIR_RESOURCES_hint
__GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to __GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to
the application to the `Contents/Resources` subdirectory of the application's the application to the `Contents/Resources` subdirectory of the application's
bundle, if present. Set this with @ref glfwInitHint. bundle, if present. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is
ignored on other platforms.
@anchor GLFW_COCOA_MENUBAR_hint @anchor GLFW_COCOA_MENUBAR_hint
__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar, either from __GLFW_COCOA_MENUBAR__ specifies whether to create the menu bar and dock icon
a nib or manually, when the first window is created, which is when AppKit is when GLFW is initialized. This applies whether the menu bar is created from
initialized. Set this with @ref glfwInitHint. a nib or manually by GLFW. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
This is ignored on other platforms.
@subsubsection init_hints_x11 X11 specific init hints
@anchor GLFW_X11_XCB_VULKAN_SURFACE_hint
__GLFW_X11_XCB_VULKAN_SURFACE__ specifies whether to prefer the
`VK_KHR_xcb_surface` extension for creating Vulkan surfaces, or whether to use
the `VK_KHR_xlib_surface` extension. Possible values are `GLFW_TRUE` and
`GLFW_FALSE`. This is ignored on other platforms.
@subsubsection init_hints_values Supported and default values @subsubsection init_hints_values Supported and default values
Initialization hint | Default value | Supported values Initialization hint | Default value | Supported values
------------------------------- | ------------- | ---------------- -------------------------------- | ------------------------------- | ----------------
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_PLATFORM | `GLFW_ANY_PLATFORM` | `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_X11`, `GLFW_PLATFORM_WAYLAND` or `GLFW_PLATFORM_NULL`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` @ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@subsection platform Runtime platform selection
GLFW can be compiled for more than one platform (window system) at once. This lets
a single library binary support both X11 and Wayland on Linux and other Unix-like systems.
You can control platform selection via the @ref GLFW_PLATFORM initialization hint. By
default, this is set to @ref GLFW_ANY_PLATFORM, which will look for supported window
systems in order of priority and select the first one it finds. It can also be set to any
specific platform to have GLFW only look for that one.
@code
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
@endcode
This mechanism also provides the Null platform, which is always supported but needs to be
explicitly requested. This platform is effectively a stub, emulating a window system on
a single 1080p monitor, but will not interact with any actual window system.
@code
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_NULL);
@endcode
You can test whether a library binary was compiled with support for a specific platform
with @ref glfwPlatformSupported.
@code
if (glfwPlatformSupported(GLFW_PLATFORM_WAYLAND))
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
@endcode
Once GLFW has been initialized, you can query which platform was selected with @ref
glfwGetPlatform.
@code
int platform = glfwGetPlatform();
@endcode
If you are using any [native access functions](@ref native), especially on Linux and other
Unix-like systems, then you may need to check that you are calling the ones matching the
selected platform.
@subsection init_allocator Custom heap memory allocator
The heap memory allocator can be customized before initialization with @ref
glfwInitAllocator.
@code
GLFWallocator allocator;
allocator.allocate = my_malloc;
allocator.reallocate = my_realloc;
allocator.deallocate = my_free;
allocator.user = NULL;
glfwInitAllocator(&allocator);
@endcode
The allocator will be picked up at the beginning of initialization and will be
used until GLFW has been fully terminated. Any allocator set after
initialization will be picked up only at the next initialization.
The allocator will only be used for allocations that would have been made with
the C standard library. Memory allocations that must be made with platform
specific APIs will still use those.
The allocation function must have a signature matching @ref GLFWallocatefun. It receives
the desired size, in bytes, and the user pointer passed to @ref glfwInitAllocator and
returns the address to the allocated memory block.
@code
void* my_malloc(size_t size, void* user)
{
...
}
@endcode
The reallocation function must have a function signature matching @ref GLFWreallocatefun.
It receives the memory block to be reallocated, the new desired size, in bytes, and the user
pointer passed to @ref glfwInitAllocator and returns the address to the resized memory
block.
@code
void* my_realloc(void* block, size_t size, void* user)
{
...
}
@endcode
The deallocation function must have a function signature matching @ref GLFWdeallocatefun.
It receives the memory block to be deallocated and the user pointer passed to @ref
glfwInitAllocator.
@code
void my_free(void* block, void* user)
{
...
}
@endcode
@subsection intro_init_terminate Terminating GLFW @subsection intro_init_terminate Terminating GLFW
@ -124,9 +269,9 @@ This will destroy any remaining window, monitor and cursor objects, restore any
modified gamma ramps, re-enable the screensaver if it had been disabled and free modified gamma ramps, re-enable the screensaver if it had been disabled and free
any other resources allocated by GLFW. any other resources allocated by GLFW.
Once the library is terminated, it is as if it had never been initialized and Once the library is terminated, it is as if it had never been initialized, therefore
you will need to initialize it again before being able to use GLFW. If the you will need to initialize it again before being able to use GLFW. If the
library was not initialized or had already been terminated, it return library was not initialized or had already been terminated, it returns
immediately. immediately.
@ -246,14 +391,14 @@ which monitor the window is currently considered to be on.
This section describes the conditions under which GLFW can be expected to This section describes the conditions under which GLFW can be expected to
function, barring bugs in the operating system or drivers. Use of GLFW outside function, barring bugs in the operating system or drivers. Use of GLFW outside
of these limits may work on some platforms, or on some machines, or some of the these limits may work on some platforms, or on some machines, or some of the
time, or on some versions of GLFW, but it may break at any time and this will time, or on some versions of GLFW, but it may break at any time and this will
not be considered a bug. not be considered a bug.
@subsection lifetime Pointer lifetimes @subsection lifetime Pointer lifetimes
GLFW will never free any pointer you provide to it and you must never free any GLFW will never free any pointer you provide to it, and you must never free any
pointer it provides to you. pointer it provides to you.
Many GLFW functions return pointers to dynamically allocated structures, strings Many GLFW functions return pointers to dynamically allocated structures, strings
@ -346,6 +491,11 @@ Library version information may be queried from any thread.
- @ref glfwGetVersion - @ref glfwGetVersion
- @ref glfwGetVersionString - @ref glfwGetVersionString
Platform information may be queried from any thread.
- @ref glfwPlatformSupported
- @ref glfwGetPlatform
All Vulkan related functions may be called from any thread. All Vulkan related functions may be called from any thread.
- @ref glfwVulkanSupported - @ref glfwVulkanSupported
@ -438,17 +588,32 @@ __Do not use the version string__ to parse the GLFW library version. The @ref
glfwGetVersion function already provides the version of the running library glfwGetVersion function already provides the version of the running library
binary. binary.
__Do not use the version string__ to parse what platforms are supported. The @ref
glfwPlatformSupported function lets you query platform support.
__GLFW 3.4:__ The format of this string was changed to support the addition of
[runtime platform selection](@ref platform).
The format of the string is as follows: The format of the string is as follows:
- The version of GLFW - The version of GLFW
- The name of the window system API - For each supported platform:
- The name of the context creation API - The name of the window system API
- Any additional options or APIs - The name of the window system specific context creation API, if applicable
- The names of the always supported context creation APIs EGL and OSMesa
- Any additional compile-time options, APIs and (on Windows) what compiler was used
For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL For example, compiling GLFW 3.4 with MinGW as a DLL for Windows, may result in a version string
back ends, the version string may look something like this: like this:
@code @code
3.0.0 Win32 WGL MinGW 3.4.0 Win32 WGL Null EGL OSMesa MinGW DLL
@endcode
Compiling GLFW as a static library for Linux, with both Wayland and X11 enabled, may
result in a version string like this:
@code
3.4.0 Wayland X11 GLX Null EGL OSMesa monotonic
@endcode @endcode
*/ */

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -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.
@ -18,43 +18,42 @@ behave differently in GLFW 3.
@subsection quick_include Including the GLFW header @subsection quick_include Including the GLFW header
In the source files of your application where you use OpenGL or GLFW, you need In the source files of your application where you use GLFW, you need to include
to include the GLFW 3 header file. its header file.
@code @code
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
This defines all the constants, types and function prototypes of the GLFW API. This header provides all the constants, types and function prototypes of the
It also includes the OpenGL header from your development environment and GLFW API.
defines all the constants and types necessary for it to work on your platform
without including any platform-specific headers.
In other words: By default it also includes the OpenGL header from your development environment.
On some platforms this header only supports older versions of OpenGL. The most
extreme case is Windows, where it typically only supports OpenGL 1.2.
- Do _not_ include the OpenGL header yourself, as GLFW does this for you in Most programs will instead use an
a platform-independent way [extension loader library](@ref context_glext_auto) and include its header.
- Do _not_ include `windows.h` or other platform-specific headers unless This example uses files generated by [glad](https://gen.glad.sh/). The GLFW
you plan on using those APIs yourself header can detect most such headers if they are included first and will then not
- If you _do_ need to include such headers, include them _before_ the GLFW include the one from your development environment.
header and it will detect this
On some platforms supported by GLFW the OpenGL header and link library only
expose older versions of OpenGL. The most extreme case is Windows, which only
exposes OpenGL 1.2. The easiest way to work around this is to use an
[extension loader library](@ref context_glext_auto).
If you are using such a library then you should include its header _before_ the
GLFW header. This lets it replace the OpenGL header included by GLFW without
conflicts. This example uses
[glad2](https://github.com/Dav1dde/glad), but the same rule applies to all such
libraries.
@code @code
#include <glad/gl.h> #include <glad/gl.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
To make sure there will be no header conflicts, you can define @ref
GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the
development environment header. This also allows the two headers to be included
in any order.
@code
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/gl.h>
@endcode
@subsection quick_init_term Initializing and terminating GLFW @subsection quick_init_term Initializing and terminating GLFW
@ -135,9 +134,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)
{ {
@ -145,10 +149,6 @@ if (!window)
} }
@endcode @endcode
The window handle is passed to all window related functions and is provided to
along to all window related callbacks, so they can tell which window received
the event.
When a window and context is no longer needed, destroy it. When a window and context is no longer needed, destroy it.
@code @code
@ -234,7 +234,7 @@ events as described below.
@subsection quick_render Rendering with OpenGL @subsection quick_render Rendering with OpenGL
Once you have a current OpenGL context, you can use OpenGL normally. In this Once you have a current OpenGL context, you can use OpenGL normally. In this
tutorial, a multi-colored rotating triangle will be rendered. The framebuffer tutorial, a multicolored rotating triangle will be rendered. The framebuffer
size needs to be retrieved for `glViewport`. size needs to be retrieved for `glViewport`.
@code @code
@ -246,12 +246,16 @@ glViewport(0, 0, width, height);
You can also set a framebuffer size callback using @ref You can also set a framebuffer size callback using @ref
glfwSetFramebufferSizeCallback and be notified when the size changes. glfwSetFramebufferSizeCallback and be notified when the size changes.
Actual rendering with OpenGL is outside the scope of this tutorial, but there The details of how to render with OpenGL is outside the scope of this tutorial,
are [many](https://open.gl/) [excellent](https://learnopengl.com/) but there are many excellent resources for learning modern OpenGL. Here are
[tutorial](http://openglbook.com/) [sites](http://ogldev.atspace.co.uk/) that a few of them:
teach modern OpenGL. Some of them use GLFW to create the context and window
while others use GLUT or SDL, but remember that OpenGL itself always works the - [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/)
same. - [Learn OpenGL](https://learnopengl.com/)
- [Open.GL](https://open.gl/)
These all happen to use GLFW, but OpenGL itself works the same whatever API you
use to create the window and context.
@subsection quick_timer Reading the timer @subsection quick_timer Reading the timer
@ -326,19 +330,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

View File

@ -4,8 +4,8 @@
@tableofcontents @tableofcontents
This guide is intended to fill the gaps between the [Vulkan This guide is intended to fill the gaps between the official [Vulkan
documentation](https://www.khronos.org/vulkan/) and the rest of the GLFW resources](https://www.khronos.org/vulkan/) and the rest of the GLFW
documentation and is not a replacement for either. It assumes some familiarity documentation and is not a replacement for either. It assumes some familiarity
with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to
the Vulkan documentation to explain the details of Vulkan functions. the Vulkan documentation to explain the details of Vulkan functions.
@ -14,7 +14,12 @@ To develop for Vulkan you should download the [LunarG Vulkan
SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link
libraries, they also provide the validation layers necessary for development. libraries, they also provide the validation layers necessary for development.
For details on a specific function in this category, see the @ref vulkan. There The [Vulkan Tutorial](https://vulkan-tutorial.com/) has more information on how
to use GLFW and Vulkan. The [Khronos Vulkan
Samples](https://github.com/KhronosGroup/Vulkan-Samples) also use GLFW, although
with a small framework in between.
For details on a specific Vulkan support function, see the @ref vulkan. There
are also guides for the other areas of the GLFW API. are also guides for the other areas of the GLFW API.
- @ref intro_guide - @ref intro_guide
@ -24,28 +29,34 @@ are also guides for the other areas of the GLFW API.
- @ref input_guide - @ref input_guide
@section vulkan_loader Linking against the Vulkan loader @section vulkan_loader Finding the Vulkan loader
By default, GLFW will look for the Vulkan loader on demand at runtime via its GLFW itself does not ever need to be linked against the Vulkan loader.
standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other
Unix-like systems and `libvulkan.1.dylib` on macOS). This means that GLFW does
not need to be linked against the loader. However, it also means that if you
are using the static library form of the Vulkan loader GLFW will either fail to
find it or (worse) use the wrong one.
The @ref GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader By default, GLFW will load the Vulkan loader dynamically at runtime via its standard name:
directly instead of dynamically loading it at runtime. Not linking against the `vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and
Vulkan loader will then be a compile-time error. `libvulkan.1.dylib` on macOS.
@macos Because the Vulkan loader and ICD are not installed globally on macOS, @macos GLFW will also look up and search the `Frameworks` subdirectory of your
you need to set up the application bundle according to the LunarG SDK application bundle.
documentation. This is explained in more detail in the
If your code is using a Vulkan loader with a different name or in a non-standard location
you will need to direct GLFW to it. Pass your version of `vkGetInstanceProcAddr` to @ref
glfwInitVulkanLoader before initializing GLFW and it will use that function for all Vulkan
entry point retrieval. This prevents GLFW from dynamically loading the Vulkan loader.
@code
glfwInitVulkanLoader(vkGetInstanceProcAddr);
@endcode
@macos To make your application be redistributable you will need to set up the application
bundle according to the LunarG SDK documentation. This is explained in more detail in the
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
@section vulkan_include Including the Vulkan and GLFW header files @section vulkan_include Including the Vulkan header file
To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including To have GLFW include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including
the GLFW header. the GLFW header.
@code @code
@ -61,8 +72,13 @@ your own custom Vulkan header then do this before the GLFW header.
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
Unless a Vulkan header is included, either by the GLFW header or above it, any Unless a Vulkan header is included, either by the GLFW header or above it, the following
GLFW functions that take or return Vulkan types will not be declared. GLFW functions will not be declared, as depend on Vulkan types.
- @ref glfwInitVulkanLoader
- @ref glfwGetInstanceProcAddress
- @ref glfwGetPhysicalDevicePresentationSupport
- @ref glfwCreateWindowSurface
The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part
of GLFW to work. Define them only if you are using these extensions directly. of GLFW to work. Define them only if you are using these extensions directly.
@ -88,7 +104,7 @@ if (glfwVulkanSupported())
This function returns `GLFW_TRUE` if the Vulkan loader and any minimally This function returns `GLFW_TRUE` if the Vulkan loader and any minimally
functional ICD was found. functional ICD was found.
If if one or both were not found, calling any other Vulkan related GLFW function If one or both were not found, calling any other Vulkan related GLFW function
will generate a @ref GLFW_API_UNAVAILABLE error. will generate a @ref GLFW_API_UNAVAILABLE error.
@ -126,7 +142,7 @@ PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr");
@endcode @endcode
Device-specific functions may execute a little bit faster, due to not having to Device-specific functions may execute a little faster, due to not having to
dispatch internally based on the device passed to them. For more information dispatch internally based on the device passed to them. For more information
about `vkGetDeviceProcAddr`, see the Vulkan documentation. about `vkGetDeviceProcAddr`, see the Vulkan documentation.
@ -172,6 +188,13 @@ check whether any extensions you wish to enable are already in the returned
array, as it is an error to specify an extension more than once in the array, as it is an error to specify an extension more than once in the
`VkInstanceCreateInfo` struct. `VkInstanceCreateInfo` struct.
@macos MoltenVK is (as of July 2022) not yet a fully conformant implementation
of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the
`VK_KHR_portability_enumeration` instance extension and set the
`VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the instance creation
info flags for MoltenVK to show up in the list of physical devices. For more
information, see the Vulkan and MoltenVK documentation.
@section vulkan_present Querying for Vulkan presentation support @section vulkan_present Querying for Vulkan presentation support

View File

@ -236,7 +236,8 @@ does not affect window decorations. Possible values are `GLFW_TRUE` and
@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`.
@anchor GLFW_SCALE_TO_MONITOR @anchor GLFW_SCALE_TO_MONITOR
__GLFW_SCALE_TO_MONITOR__ specified whether the window content area should be __GLFW_SCALE_TO_MONITOR__ specified whether the window content area should be
@ -248,6 +249,21 @@ This hint only has an effect on platforms where screen coordinates and pixels
always map 1:1 such as Windows and X11. On platforms like macOS the resolution always map 1:1 such as Windows and X11. On platforms like macOS the resolution
of the framebuffer is changed independently of the window size. of the framebuffer is changed independently of the window size.
@anchor GLFW_MOUSE_PASSTHROUGH_hint
__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse
input, letting any mouse events pass through to whatever window is behind it.
This is only supported for undecorated windows. Decorated windows with this
enabled will behave differently between platforms. Possible values are
`GLFW_TRUE` and `GLFW_FALSE`.
@anchor GLFW_POSITION_X
@anchor GLFW_POSITION_Y
__GLFW_POSITION_X__ and __GLFW_POSITION_Y__ specify the desired initial position
of the window. The window manager may modify or ignore these coordinates. If
either or both of these hints are set to `GLFW_ANY_POSITION` then the window
manager will position the window where it thinks the user will prefer it.
Possible values are any valid screen coordinates and `GLFW_ANY_POSITION`.
@subsubsection window_hints_fb Framebuffer related hints @subsubsection window_hints_fb Framebuffer related hints
@ -271,7 +287,6 @@ __GLFW_ACCUM_ALPHA_BITS__ specify the desired bit depths of the various
components of the accumulation buffer. A value of `GLFW_DONT_CARE` means the components of the accumulation buffer. A value of `GLFW_DONT_CARE` means the
application has no preference. application has no preference.
@par
Accumulation buffers are a legacy OpenGL feature and should not be used in new Accumulation buffers are a legacy OpenGL feature and should not be used in new
code. code.
@ -279,7 +294,6 @@ code.
__GLFW_AUX_BUFFERS__ specifies the desired number of auxiliary buffers. A value __GLFW_AUX_BUFFERS__ specifies the desired number of auxiliary buffers. A value
of `GLFW_DONT_CARE` means the application has no preference. of `GLFW_DONT_CARE` means the application has no preference.
@par
Auxiliary buffers are a legacy OpenGL feature and should not be used in new Auxiliary buffers are a legacy OpenGL feature and should not be used in new
code. code.
@ -296,16 +310,15 @@ the application has no preference.
__GLFW_SRGB_CAPABLE__ specifies whether the framebuffer should be sRGB capable. __GLFW_SRGB_CAPABLE__ specifies whether the framebuffer should be sRGB capable.
Possible values are `GLFW_TRUE` and `GLFW_FALSE`. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
@par @note __OpenGL:__ If enabled and supported by the system, the
__OpenGL:__ If enabled and supported by the system, the `GL_FRAMEBUFFER_SRGB` `GL_FRAMEBUFFER_SRGB` enable will control sRGB rendering. By default, sRGB
enable will control sRGB rendering. By default, sRGB rendering will be rendering will be disabled.
disabled.
@par @note __OpenGL ES:__ If enabled and supported by the system, the context will
__OpenGL ES:__ If enabled and supported by the system, the context will always always have sRGB rendering enabled.
have sRGB rendering enabled.
@anchor GLFW_DOUBLEBUFFER @anchor GLFW_DOUBLEBUFFER
@anchor GLFW_DOUBLEBUFFER_hint
__GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double __GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double
buffered. You nearly always want to use double buffering. This is a hard buffered. You nearly always want to use double buffering. This is a hard
constraint. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. constraint. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
@ -332,28 +345,22 @@ create the context. Possible values are `GLFW_NATIVE_CONTEXT_API`,
`GLFW_EGL_CONTEXT_API` and `GLFW_OSMESA_CONTEXT_API`. This is a hard `GLFW_EGL_CONTEXT_API` and `GLFW_OSMESA_CONTEXT_API`. This is a hard
constraint. If no client API is requested, this hint is ignored. constraint. If no client API is requested, this hint is ignored.
@par An [extension loader library](@ref context_glext_auto) that assumes it knows
@macos The EGL API is not available on this platform and requests to use it which API was used to create the current context may fail if you change this
will fail. hint. This can be resolved by having it load functions via @ref
glfwGetProcAddress.
@par @note @wayland The EGL API _is_ the native context creation API, so this hint
__Wayland:__ The EGL API _is_ the native context creation API, so this hint
will have no effect. will have no effect.
@par @note @x11 On some Linux systems, creating contexts via both the native and EGL
__OSMesa:__ As its name implies, an OpenGL context created with OSMesa does not APIs in a single process will cause the application to segfault. Stick to one
update the window contents when its buffers are swapped. Use OpenGL functions API or the other on Linux for now.
or the OSMesa native access functions @ref glfwGetOSMesaColorBuffer and @ref
glfwGetOSMesaDepthBuffer to retrieve the framebuffer contents.
@note An OpenGL extension loader library that assumes it knows which context @note __OSMesa:__ As its name implies, an OpenGL context created with OSMesa
creation API is used on a given platform may fail if you change this hint. This does not update the window contents when its buffers are swapped. Use OpenGL
can be resolved by having it load via @ref glfwGetProcAddress, which always uses functions or the OSMesa native access functions @ref glfwGetOSMesaColorBuffer
the selected API. and @ref glfwGetOSMesaDepthBuffer to retrieve the framebuffer contents.
@bug On some Linux systems, creating contexts via both the native and EGL APIs
in a single process will cause the application to segfault. Stick to one API or
the other on Linux for now.
@anchor GLFW_CONTEXT_VERSION_MAJOR_hint @anchor GLFW_CONTEXT_VERSION_MAJOR_hint
@anchor GLFW_CONTEXT_VERSION_MINOR_hint @anchor GLFW_CONTEXT_VERSION_MINOR_hint
@ -361,34 +368,29 @@ __GLFW_CONTEXT_VERSION_MAJOR__ and __GLFW_CONTEXT_VERSION_MINOR__ specify the
client API version that the created context must be compatible with. The exact client API version that the created context must be compatible with. The exact
behavior of these hints depend on the requested client API. behavior of these hints depend on the requested client API.
@note Do not confuse these hints with `GLFW_VERSION_MAJOR` and
`GLFW_VERSION_MINOR`, which provide the API version of the GLFW header.
@par
__OpenGL:__ These hints are not hard constraints, but creation will fail if the
OpenGL version of the created context is less than the one requested. It is
therefore perfectly safe to use the default of version 1.0 for legacy code and
you will still get backwards-compatible contexts of version 3.0 and above when
available.
@par
While there is no way to ask the driver for a context of the highest supported While there is no way to ask the driver for a context of the highest supported
version, GLFW will attempt to provide this when you ask for a version 1.0 version, GLFW will attempt to provide this when you ask for a version 1.0
context, which is the default for these hints. context, which is the default for these hints.
@par Do not confuse these hints with @ref GLFW_VERSION_MAJOR and @ref
__OpenGL ES:__ These hints are not hard constraints, but creation will fail if GLFW_VERSION_MINOR, which provide the API version of the GLFW header.
the OpenGL ES version of the created context is less than the one requested.
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,
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 __OpenGL:__ These hints are not hard constraints, but creation will fail
OpenGL versions 3.2 and later. Before creating an OpenGL context of version if the OpenGL version of the created context is less than the one requested. It
3.2 or later you must set the is therefore perfectly safe to use the default of version 1.0 for legacy code
[GLFW_OPENGL_FORWARD_COMPAT](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) and and you will still get backwards-compatible contexts of version 3.0 and above
[GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hints accordingly. OpenGL when available.
3.0 and 3.1 contexts are not supported at all on macOS.
@note __OpenGL ES:__ These hints are not hard constraints, but creation will
fail if the OpenGL ES version of the created context is less than the one
requested. 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, but OpenGL ES 2.0 is not backward compatible with 1.x.
@note @macos The OS only supports core profile contexts for OpenGL versions 3.2
and later. Before creating an OpenGL context of version 3.2 or later you must
set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint 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
@ -396,15 +398,21 @@ forward-compatible, i.e. one where all functionality deprecated in the requested
version of OpenGL is removed. This must only be used if the requested OpenGL version of OpenGL is removed. This must only be used if the requested OpenGL
version is 3.0 or above. If OpenGL ES is requested, this hint is ignored. version is 3.0 or above. If OpenGL ES is requested, this hint is ignored.
@par
Forward-compatibility is described in detail in the Forward-compatibility is described in detail in the
[OpenGL Reference Manual](https://www.opengl.org/registry/). [OpenGL Reference Manual](https://www.opengl.org/registry/).
@anchor GLFW_CONTEXT_DEBUG_hint
@anchor GLFW_OPENGL_DEBUG_CONTEXT_hint @anchor GLFW_OPENGL_DEBUG_CONTEXT_hint
__GLFW_OPENGL_DEBUG_CONTEXT__ specifies whether to create a debug OpenGL __GLFW_CONTEXT_DEBUG__ specifies whether the context should be created in debug
context, which may have additional error and performance issue reporting mode, which may provide additional error and diagnostic reporting functionality.
functionality. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If OpenGL ES Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
is requested, this hint is ignored.
Debug contexts for OpenGL and OpenGL ES are described in detail by the
[GL_KHR_debug](https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_debug.txt)
extension.
@note `GLFW_CONTEXT_DEBUG` is the new name introduced in GLFW 3.4. The older
`GLFW_OPENGL_DEBUG_CONTEXT` name is also available for compatibility.
@anchor GLFW_OPENGL_PROFILE_hint @anchor GLFW_OPENGL_PROFILE_hint
__GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context __GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context
@ -414,7 +422,6 @@ a specific profile. If requesting an OpenGL version below 3.2,
`GLFW_OPENGL_ANY_PROFILE` must be used. If OpenGL ES is requested, this hint `GLFW_OPENGL_ANY_PROFILE` must be used. If OpenGL ES is requested, this hint
is ignored. is ignored.
@par
OpenGL profiles are described in detail in the OpenGL profiles are described in detail in the
[OpenGL Reference Manual](https://www.opengl.org/registry/). [OpenGL Reference Manual](https://www.opengl.org/registry/).
@ -434,7 +441,6 @@ 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 current one. If the behavior is `GLFW_RELEASE_BEHAVIOR_NONE`, the pipeline will
not be flushed on release. not be flushed on release.
@par
Context release behaviors are described in detail by the Context release behaviors are described in detail by the
[GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt) [GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt)
extension. extension.
@ -444,13 +450,20 @@ __GLFW_CONTEXT_NO_ERROR__ specifies whether errors should be generated by the
context. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled, context. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled,
situations that would have generated errors instead cause undefined behavior. situations that would have generated errors instead cause undefined behavior.
@par
The no error mode for OpenGL and OpenGL ES is described in detail by the The no error mode for OpenGL and OpenGL ES is described in detail by the
[GL_KHR_no_error](https://www.opengl.org/registry/specs/KHR/no_error.txt) [GL_KHR_no_error](https://www.opengl.org/registry/specs/KHR/no_error.txt)
extension. extension.
@subsubsection window_hints_osx macOS specific window hints @subsubsection window_hints_win32 Win32 specific hints
@anchor GLFW_WIN32_KEYBOARD_MENU_hint
__GLFW_WIN32_KEYBOARD_MENU__ specifies whether to allow access to the window
menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. This is
ignored on other platforms.
@subsubsection window_hints_osx macOS specific hints
@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint @anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint
__GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution __GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution
@ -470,12 +483,10 @@ run on the discrete GPU. This only affects systems with both integrated and
discrete GPUs. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is discrete GPUs. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is
ignored on other platforms. ignored on other platforms.
@par
Simpler programs and tools may want to enable this to save power, while games Simpler programs and tools may want to enable this to save power, while games
and other applications performing advanced rendering will want to leave it and other applications performing advanced rendering will want to leave it
disabled. disabled.
@par
A bundled application that wishes to participate in Automatic Graphics Switching A bundled application that wishes to participate in Automatic Graphics Switching
should also declare this in its `Info.plist` by setting the should also declare this in its `Info.plist` by setting the
`NSSupportsAutomaticGraphicsSwitching` key to `true`. `NSSupportsAutomaticGraphicsSwitching` key to `true`.
@ -486,9 +497,17 @@ should also declare this in its `Info.plist` by setting the
@anchor GLFW_X11_CLASS_NAME_hint @anchor GLFW_X11_CLASS_NAME_hint
@anchor GLFW_X11_INSTANCE_NAME_hint @anchor GLFW_X11_INSTANCE_NAME_hint
__GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired __GLFW_X11_CLASS_NAME__ and __GLFW_X11_INSTANCE_NAME__ specifies the desired
ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. ASCII encoded class and instance parts of the ICCCM `WM_CLASS` window property. Both
hints need to be set to something other than an empty string for them to take effect.
These are set with @ref glfwWindowHintString. These are set with @ref glfwWindowHintString.
@subsubsection window_hints_wayland Wayland specific window hints
@anchor GLFW_WAYLAND_APP_ID_hint
__GLFW_WAYLAND_APP_ID__ specifies the Wayland app_id for a window, used
by window managers to identify types of windows. This is set with
@ref glfwWindowHintString.
@subsubsection window_hints_values Supported and default values @subsubsection window_hints_values Supported and default values
@ -505,6 +524,9 @@ GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GL
GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_MOUSE_PASSTHROUGH | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_POSITION_X | `GLFW_ANY_POSITION` | Any valid screen x-coordinate or `GLFW_ANY_POSITION`
GLFW_POSITION_Y | `GLFW_ANY_POSITION` | Any valid screen y-coordinate or `GLFW_ANY_POSITION`
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
@ -528,13 +550,15 @@ GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor ve
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`
GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_OPENGL_DEBUG_CONTEXT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_CONTEXT_DEBUG | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE`
GLFW_WIN32_KEYBOARD_MENU | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_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`
GLFW_X11_CLASS_NAME | `""` | An ASCII encoded `WM_CLASS` class name GLFW_X11_CLASS_NAME | `""` | An ASCII encoded `WM_CLASS` class name
GLFW_X11_INSTANCE_NAME | `""` | An ASCII encoded `WM_CLASS` instance name GLFW_X11_INSTANCE_NAME | `""` | An ASCII encoded `WM_CLASS` instance name
GLFW_WAYLAND_APP_ID | `""` | An ASCII encoded Wayland `app_id` name
@section window_events Window event processing @section window_events Window event processing
@ -785,7 +809,20 @@ are undefined if they conflict.
@subsection window_pos Window position @subsection window_pos Window position
The position of a windowed-mode window can be changed with @ref By default, the window manager chooses the position of new windowed mode
windows, based on its size and which monitor the user appears to be working on.
This is most often the right choice. If you need to create a window at
a specific position, you can set the desired position with the @ref
GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints.
@code
glfwWindowHint(GLFW_POSITION_X, 70);
glfwWindowHint(GLFW_POSITION_Y, 83);
@endcode
To restore the previous behavior, set these hints to `GLFW_ANY_POSITION`.
The position of a windowed mode window can be changed with @ref
glfwSetWindowPos. This moves the window so that the upper-left corner of its glfwSetWindowPos. This moves the window so that the upper-left corner of its
content area has the specified [screen coordinates](@ref coordinate_systems). content area has the specified [screen coordinates](@ref coordinate_systems).
The window system may put limitations on window placement. The window system may put limitations on window placement.
@ -1204,7 +1241,11 @@ If the system does not support whole window transparency, this function always
returns one. returns one.
GLFW comes with a test program that lets you control whole window transparency GLFW comes with a test program that lets you control whole window transparency
at run-time called `opacity`. at run-time called `window`.
If you want to use either of these transparency methods to display a temporary
overlay like for example a notification, the @ref GLFW_FLOATING and @ref
GLFW_MOUSE_PASSTHROUGH window hints and attributes may be useful.
@subsection window_attribs Window attributes @subsection window_attribs Window attributes
@ -1294,6 +1335,15 @@ focus when @ref glfwShowWindow is called. This can be set before creation
with the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint or with the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint or
after with @ref glfwSetWindowAttrib. after with @ref glfwSetWindowAttrib.
@anchor GLFW_MOUSE_PASSTHROUGH_attrib
__GLFW_MOUSE_PASSTHROUGH__ specifies whether the window is transparent to mouse
input, letting any mouse events pass through to whatever window is behind it.
This can be set before creation with the
[GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_hint) window hint or after
with @ref glfwSetWindowAttrib. This is only supported for undecorated windows.
Decorated windows with this enabled will behave differently between platforms.
@subsubsection window_attribs_ctx Context related attributes @subsubsection window_attribs_ctx Context related attributes
@anchor GLFW_CLIENT_API_attrib @anchor GLFW_CLIENT_API_attrib
@ -1320,9 +1370,14 @@ of the GLFW header.
__GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an __GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an
OpenGL forward-compatible one, or `GLFW_FALSE` otherwise. OpenGL forward-compatible one, or `GLFW_FALSE` otherwise.
@anchor GLFW_CONTEXT_DEBUG_attrib
@anchor GLFW_OPENGL_DEBUG_CONTEXT_attrib @anchor GLFW_OPENGL_DEBUG_CONTEXT_attrib
__GLFW_OPENGL_DEBUG_CONTEXT__ is `GLFW_TRUE` if the window's context is an __GLFW_CONTEXT_DEBUG__ is `GLFW_TRUE` if the window's context is in debug
OpenGL debug context, or `GLFW_FALSE` otherwise. mode, or `GLFW_FALSE` otherwise.
@par
This is the new name, introduced in GLFW 3.4. The older
`GLFW_OPENGL_DEBUG_CONTEXT` name is also available for compatibility.
@anchor GLFW_OPENGL_PROFILE_attrib @anchor GLFW_OPENGL_PROFILE_attrib
__GLFW_OPENGL_PROFILE__ indicates the OpenGL profile used by the context. This __GLFW_OPENGL_PROFILE__ indicates the OpenGL profile used by the context. This
@ -1332,6 +1387,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`
@ -1340,9 +1410,11 @@ if the window's context supports robustness, or `GLFW_NO_ROBUSTNESS` otherwise.
@subsubsection window_attribs_fb Framebuffer related attributes @subsubsection window_attribs_fb Framebuffer related attributes
GLFW does not expose attributes of the default framebuffer (i.e. the framebuffer GLFW does not expose most attributes of the default framebuffer (i.e. the
attached to the window) as these can be queried directly with either OpenGL, framebuffer attached to the window) as these can be queried directly with either
OpenGL ES or Vulkan. OpenGL, OpenGL ES or Vulkan. The one exception is
[GLFW_DOUBLEBUFFER](@ref GLFW_DOUBLEBUFFER_attrib), as this is not provided by
OpenGL ES.
If you are using version 3.0 or later of OpenGL or OpenGL ES, the If you are using version 3.0 or later of OpenGL or OpenGL ES, the
`glGetFramebufferAttachmentParameteriv` function can be used to retrieve the `glGetFramebufferAttachmentParameteriv` function can be used to retrieve the
@ -1368,6 +1440,11 @@ alpha sizes are queried from the `GL_BACK_LEFT`, while the depth and stencil
sizes are queried from the `GL_DEPTH` and `GL_STENCIL` attachments, sizes are queried from the `GL_DEPTH` and `GL_STENCIL` attachments,
respectively. respectively.
@anchor GLFW_DOUBLEBUFFER_attrib
__GLFW_DOUBLEBUFFER__ indicates whether the specified window is double-buffered
when rendering with OpenGL or OpenGL ES. This can be set before creation with
the [GLFW_DOUBLEBUFFER](@ref GLFW_DOUBLEBUFFER_hint) window hint.
@section buffer_swap Buffer swapping @section buffer_swap Buffer swapping
@ -1385,7 +1462,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

View File

@ -1,30 +1,25 @@
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}")
endif() endif()
if (MSVC) # Workaround for the MS CRT deprecating parts of the standard library
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "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")
"${GLFW_SOURCE_DIR}/deps/glad_gl.c") set(GLAD_GLES2 "${GLFW_SOURCE_DIR}/deps/glad/gles2.h")
set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h"
"${GLFW_SOURCE_DIR}/deps/getopt.c") "${GLFW_SOURCE_DIR}/deps/getopt.c")
set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
@ -36,25 +31,33 @@ 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(triangle-opengles WIN32 MACOSX_BUNDLE triangle-opengles.c ${ICON} ${GLAD_GLES2})
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL})
target_link_libraries(particles "${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 triangle-opengles wave windows)
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 (MSVC) if (MSVC)
# Tell MSVC to use main instead of WinMain for Windows subsystem executables # Tell MSVC to use main instead of WinMain
set_target_properties(${WINDOWS_BINARIES} PROPERTIES set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
LINK_FLAGS "/ENTRY:mainCRTStartup") LINK_FLAGS "/ENTRY:mainCRTStartup")
elseif (CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
# Tell Clang using MS CRT to use main instead of WinMain
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
LINK_FLAGS "-Wl,/entry:mainCRTStartup")
endif() endif()
if (APPLE) if (APPLE)
@ -63,15 +66,18 @@ 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(triangle-opengles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL ES Triangle")
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView") set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
set_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()

View File

@ -36,7 +36,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#define GLAD_GL_IMPLEMENTATION
#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>

View File

@ -31,7 +31,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h> #include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
/** /**

View File

@ -29,7 +29,9 @@
#include <assert.h> #include <assert.h>
#include <stddef.h> #include <stddef.h>
#define GLAD_GL_IMPLEMENTATION
#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 */
@ -291,12 +293,12 @@ static void generate_heightmap__circle(float* center_x, float* center_y,
{ {
float sign; float sign;
/* random value for element in between [0-1.0] */ /* random value for element in between [0-1.0] */
*center_x = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); *center_x = (MAP_SIZE * rand()) / (float) RAND_MAX;
*center_y = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); *center_y = (MAP_SIZE * rand()) / (float) RAND_MAX;
*size = (MAX_CIRCLE_SIZE * rand()) / (1.0f * RAND_MAX); *size = (MAX_CIRCLE_SIZE * rand()) / (float) RAND_MAX;
sign = (1.0f * rand()) / (1.0f * RAND_MAX); sign = (1.0f * rand()) / (float) RAND_MAX;
sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f; sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f;
*displacement = (sign * (MAX_DISPLACEMENT * rand())) / (1.0f * RAND_MAX); *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (float) RAND_MAX;
} }
/* Run the specified number of iterations of the generation process for the /* Run the specified number of iterations of the generation process for the

View File

@ -23,14 +23,11 @@
// //
//======================================================================== //========================================================================
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h> #include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#if USE_NATIVE_OSMESA
#define GLFW_EXPOSE_NATIVE_OSMESA
#include <GLFW/glfw3native.h>
#endif
#include "linmath.h" #include "linmath.h"
#include <stdlib.h> #include <stdlib.h>
@ -147,13 +144,10 @@ 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
glfwGetOSMesaColorBuffer(window, &width, &height, NULL, (void**) &buffer);
#else
buffer = calloc(4, width * height); buffer = calloc(4, width * height);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
#endif
// Write image Y-flipped because OpenGL // Write image Y-flipped because OpenGL
stbi_write_png("offscreen.png", stbi_write_png("offscreen.png",
@ -161,11 +155,7 @@ int main(void)
buffer + (width * 4 * (height - 1)), buffer + (width * 4 * (height - 1)),
-width * 4); -width * 4);
#if USE_NATIVE_OSMESA
// Here is where there's nothing
#else
free(buffer); free(buffer);
#endif
glfwDestroyWindow(window); glfwDestroyWindow(window);

View File

@ -39,7 +39,9 @@
#include <getopt.h> #include <getopt.h>
#include <linmath.h> #include <linmath.h>
#define GLAD_GL_IMPLEMENTATION
#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 +445,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 +655,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 +722,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);

View File

@ -23,7 +23,9 @@
// //
//======================================================================== //========================================================================
#define GLAD_GL_IMPLEMENTATION
#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>

View File

@ -2,15 +2,17 @@
// This is an example program for the GLFW library // This is an example program for the GLFW library
// //
// 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. useful 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
// because I am not a friend of orthogonal projections) // because I am not a friend of orthogonal projections)
//======================================================================== //========================================================================
#define GLAD_GL_IMPLEMENTATION
#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)

View File

@ -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
@ -24,31 +24,36 @@
//======================================================================== //========================================================================
//! [code] //! [code]
#define GLAD_GL_IMPLEMENTATION
#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 +61,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 +82,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 +106,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);

View File

@ -0,0 +1,170 @@
//========================================================================
// OpenGL ES 2.0 triangle example
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLAD_GLES2_IMPLEMENTATION
#include <glad/gles2.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include "linmath.h"
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
typedef struct Vertex
{
vec2 pos;
vec3 col;
} Vertex;
static const Vertex vertices[3] =
{
{ { -0.6f, -0.4f }, { 1.f, 0.f, 0.f } },
{ { 0.6f, -0.4f }, { 0.f, 1.f, 0.f } },
{ { 0.f, 0.6f }, { 0.f, 0.f, 1.f } }
};
static const char* vertex_shader_text =
"#version 100\n"
"precision mediump float;\n"
"uniform mat4 MVP;\n"
"attribute vec3 vCol;\n"
"attribute vec2 vPos;\n"
"varying vec3 color;\n"
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
" color = vCol;\n"
"}\n";
static const char* fragment_shader_text =
"#version 100\n"
"precision mediump float;\n"
"varying vec3 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(color, 1.0);\n"
"}\n";
static void error_callback(int error, const char* description)
{
fprintf(stderr, "GLFW Error: %s\n", description);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
int main(void)
{
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
GLFWwindow* window = glfwCreateWindow(640, 480, "OpenGL ES 2.0 Triangle (EGL)", NULL, NULL);
if (!window)
{
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
window = glfwCreateWindow(640, 480, "OpenGL ES 2.0 Triangle", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
}
glfwSetKeyCallback(window, key_callback);
glfwMakeContextCurrent(window);
gladLoadGLES2(glfwGetProcAddress);
glfwSwapInterval(1);
GLuint vertex_buffer;
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
glCompileShader(vertex_shader);
const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
glCompileShader(fragment_shader);
const GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
const GLint mvp_location = glGetUniformLocation(program, "MVP");
const GLint vpos_location = glGetAttribLocation(program, "vPos");
const GLint vcol_location = glGetAttribLocation(program, "vCol");
glEnableVertexAttribArray(vpos_location);
glEnableVertexAttribArray(vcol_location);
glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void*) offsetof(Vertex, pos));
glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void*) offsetof(Vertex, col));
while (!glfwWindowShouldClose(window))
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
const float ratio = width / (float) height;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
mat4x4 m, p, mvp;
mat4x4_identity(m);
mat4x4_rotate_Z(m, m, (float) glfwGetTime());
mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
mat4x4_mul(mvp, p, m);
glUseProgram(program);
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) &mvp);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}

View File

@ -17,7 +17,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#define GLAD_GL_IMPLEMENTATION
#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>

106
examples/windows.c Normal file
View File

@ -0,0 +1,106 @@
//========================================================================
// Simple multi-window example
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int xpos, ypos, height;
const char* description;
GLFWwindow* windows[4];
if (!glfwInit())
{
glfwGetError(&description);
printf("Error: %s\n", description);
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &xpos, &ypos, NULL, &height);
for (int i = 0; i < 4; i++)
{
const int size = height / 5;
const struct
{
float r, g, b;
} colors[] =
{
{ 0.95f, 0.32f, 0.11f },
{ 0.50f, 0.80f, 0.16f },
{ 0.f, 0.68f, 0.94f },
{ 0.98f, 0.74f, 0.04f }
};
if (i > 0)
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
glfwWindowHint(GLFW_POSITION_X, xpos + size * (1 + (i & 1)));
glfwWindowHint(GLFW_POSITION_Y, ypos + size * (1 + (i >> 1)));
windows[i] = glfwCreateWindow(size, size, "Multi-Window Example", NULL, NULL);
if (!windows[i])
{
glfwGetError(&description);
printf("Error: %s\n", description);
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetInputMode(windows[i], GLFW_STICKY_KEYS, GLFW_TRUE);
glfwMakeContextCurrent(windows[i]);
gladLoadGL(glfwGetProcAddress);
glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f);
}
for (;;)
{
for (int i = 0; i < 4; i++)
{
glfwMakeContextCurrent(windows[i]);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(windows[i]);
if (glfwWindowShouldClose(windows[i]) ||
glfwGetKey(windows[i], GLFW_KEY_ESCAPE))
{
glfwTerminate();
exit(EXIT_SUCCESS);
}
}
glfwWaitEvents();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,16 @@ extern "C" {
* and which platform-specific headers to include. It is then up your (by * and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be * definition platform-specific) code to handle which of these should be
* defined. * defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/ */
@ -81,44 +91,71 @@ extern "C" {
* System headers and types * System headers and types
*************************************************************************/ *************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) #if !defined(GLFW_NATIVE_INCLUDE_NONE)
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_ARB_debug_output
// callback) but windows.h assumes no one will define APIENTRY before it does
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
typedef void* id;
#endif
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL) #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */ /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
#endif * example to allow applications to correctly declare a GL_KHR_debug callback)
#if defined(GLFW_EXPOSE_NATIVE_NSGL) * but windows.h assumes no one will define APIENTRY before it does
/* NSGL is declared by Cocoa.h */ */
#endif #if defined(GLFW_APIENTRY_DEFINED)
#if defined(GLFW_EXPOSE_NATIVE_GLX) #undef APIENTRY
#include <GL/glx.h> #undef GLFW_APIENTRY_DEFINED
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL) #include <windows.h>
#include <EGL/egl.h> #endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA) #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#include <GL/osmesa.h> #if defined(__OBJC__)
#endif #import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h>
#endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/************************************************************************* /*************************************************************************
@ -132,6 +169,8 @@ extern "C" {
* of the specified monitor, or `NULL` if an [error](@ref error_handling) * of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred. * occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -147,6 +186,8 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -161,6 +202,16 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
* @return The `HWND` of the specified window, or `NULL` if an * @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -177,6 +228,17 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
* @return The `HGLRC` of the specified window, or `NULL` if an * @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -193,6 +255,8 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
* @return The `CGDirectDisplayID` of the specified monitor, or * @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -207,6 +271,8 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
* @return The `NSWindow` of the specified window, or `nil` if an * @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -223,6 +289,9 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
* @return The `NSOpenGLContext` of the specified window, or `nil` if an * @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -239,6 +308,8 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
* @return The `Display` used by GLFW, or `NULL` if an * @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -253,6 +324,8 @@ GLFWAPI Display* glfwGetX11Display(void);
* @return The `RRCrtc` of the specified monitor, or `None` if an * @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -267,6 +340,8 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
* @return The `RROutput` of the specified monitor, or `None` if an * @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -281,6 +356,8 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @return The `Window` of the specified window, or `None` if an * @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -347,6 +424,9 @@ GLFWAPI const char* glfwGetX11SelectionString(void);
* @return The `GLXContext` of the specified window, or `NULL` if an * @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -361,6 +441,9 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @return The `GLXWindow` of the specified window, or `None` if an * @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -377,6 +460,8 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
* @return The `struct wl_display*` used by GLFW, or `NULL` if an * @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -391,6 +476,8 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an * @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -405,6 +492,8 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
* @return The main `struct wl_surface*` of the specified window, or `NULL` if * @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred. * an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -421,6 +510,11 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -435,6 +529,9 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -449,6 +546,9 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -472,6 +572,9 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -493,6 +596,9 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -507,6 +613,9 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height
* @return The `OSMesaContext` of the specified window, or `NULL` if an * @return The `OSMesaContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *

View File

@ -1,130 +1,333 @@
set(common_HEADERS internal.h mappings.h add_library(glfw ${GLFW_LIBRARY_TYPE}
"${GLFW_BINARY_DIR}/src/glfw_config.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") internal.h platform.h mappings.h
set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c) context.c init.c input.c monitor.c platform.c vulkan.c window.c
egl_context.c osmesa_context.c null_platform.h null_joystick.h
if (_GLFW_COCOA) null_init.c null_monitor.c null_window.c null_joystick.c)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
posix_thread.h nsgl_context.h egl_context.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
nsgl_context.m egl_context.c osmesa_context.c)
elseif (_GLFW_WIN32)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
wgl_context.h egl_context.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} 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)
elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h
posix_thread.h glx_context.h egl_context.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
egl_context.c osmesa_context.c)
elseif (_GLFW_WAYLAND)
set(glfw_HEADERS ${common_HEADERS} wl_platform.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
posix_time.c posix_thread.c xkb_unicode.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)
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
posix_time.h posix_thread.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
endif()
if (_GLFW_X11 OR _GLFW_WAYLAND)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
else()
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
endif()
endif()
# The time, thread and module code is shared between all backends on a given OS,
# including the null backend, which still needs those bits to be functional
if (APPLE) if (APPLE)
# For some reason, CMake doesn't know about .m target_sources(glfw PRIVATE cocoa_time.h cocoa_time.c posix_thread.h
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) posix_module.c posix_thread.c)
elseif (WIN32)
target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c
win32_time.c win32_thread.c)
else()
target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c
posix_time.c posix_thread.c)
endif() endif()
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't accept add_custom_target(update_mappings
# for all source files that VS will build COMMAND "${CMAKE_COMMAND}" -P "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" mappings.h.in mappings.h
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR COMMENT "Updating gamepad mappings from upstream repository"
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") SOURCES mappings.h.in "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake"
VERBATIM)
if (WIN32) set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3")
set(windows_SOURCES ${glfw_SOURCES})
else() if (GLFW_BUILD_COCOA)
set(windows_SOURCES ${common_SOURCES}) target_compile_definitions(glfw PRIVATE _GLFW_COCOA)
target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h cocoa_init.m
cocoa_joystick.m cocoa_monitor.m cocoa_window.m
nsgl_context.m)
endif()
if (GLFW_BUILD_WIN32)
target_compile_definitions(glfw PRIVATE _GLFW_WIN32)
target_sources(glfw PRIVATE win32_platform.h win32_joystick.h win32_init.c
win32_joystick.c win32_monitor.c win32_window.c
wgl_context.c)
endif()
if (GLFW_BUILD_X11)
target_compile_definitions(glfw PRIVATE _GLFW_X11)
target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h x11_init.c
x11_monitor.c x11_window.c xkb_unicode.c
glx_context.c)
endif()
if (GLFW_BUILD_WAYLAND)
target_compile_definitions(glfw PRIVATE _GLFW_WAYLAND)
target_sources(glfw PRIVATE wl_platform.h xkb_unicode.h wl_init.c
wl_monitor.c wl_window.c xkb_unicode.c)
endif()
if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
endif() endif()
set_source_files_properties(${windows_SOURCES} PROPERTIES target_sources(glfw PRIVATE posix_poll.h posix_poll.c)
COMPILE_FLAGS -Wdeclaration-after-statement) endif()
if (GLFW_BUILD_WAYLAND)
include(CheckIncludeFiles)
include(CheckFunctionExists)
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
if (HAVE_MEMFD_CREATE)
target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE)
endif()
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
include(FindPkgConfig)
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.15)
pkg_get_variable(WAYLAND_PROTOCOLS_BASE wayland-protocols pkgdatadir)
pkg_get_variable(WAYLAND_CLIENT_PKGDATADIR wayland-client pkgdatadir)
macro(wayland_generate protocol_file output_file)
add_custom_command(OUTPUT "${output_file}.h"
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" client-header "${protocol_file}" "${output_file}.h"
DEPENDS "${protocol_file}"
VERBATIM)
add_custom_command(OUTPUT "${output_file}-code.h"
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_file}" "${output_file}-code.h"
DEPENDS "${protocol_file}"
VERBATIM)
target_sources(glfw PRIVATE "${output_file}.h" "${output_file}-code.h")
endmacro()
wayland_generate(
"${WAYLAND_CLIENT_PKGDATADIR}/wayland.xml"
"${GLFW_BINARY_DIR}/src/wayland-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/stable/xdg-shell/xdg-shell.xml"
"${GLFW_BINARY_DIR}/src/wayland-xdg-shell-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
"${GLFW_BINARY_DIR}/src/wayland-xdg-decoration-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/stable/viewporter/viewporter.xml"
"${GLFW_BINARY_DIR}/src/wayland-viewporter-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
"${GLFW_BINARY_DIR}/src/wayland-relative-pointer-unstable-v1-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
"${GLFW_BINARY_DIR}/src/wayland-pointer-constraints-unstable-v1-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
"${GLFW_BINARY_DIR}/src/wayland-idle-inhibit-unstable-v1-client-protocol")
endif()
if (WIN32 AND GLFW_BUILD_SHARED_LIBRARY)
configure_file(glfw.rc.in glfw.rc @ONLY)
target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw.rc")
endif()
if (UNIX AND GLFW_BUILD_SHARED_LIBRARY)
# On Unix-like systems, shared libraries can use the soname system.
set(GLFW_LIB_NAME glfw)
else()
set(GLFW_LIB_NAME glfw3)
endif() endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
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}) target_link_libraries(glfw PRIVATE Threads::Threads)
# Workaround for CMake not knowing about .m files before version 3.16
if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE)
set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
cocoa_window.m nsgl_context.m PROPERTIES
LANGUAGE C)
endif()
if (GLFW_BUILD_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32")
endif()
if (GLFW_BUILD_COCOA)
target_link_libraries(glfw PRIVATE "-framework Cocoa"
"-framework IOKit"
"-framework CoreFoundation")
set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
endif()
if (GLFW_BUILD_WAYLAND)
pkg_check_modules(Wayland REQUIRED
wayland-client>=0.2.7
wayland-cursor>=0.2.7
wayland-egl>=0.2.7
xkbcommon>=0.5.0)
target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS})
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(EpollShim)
if (EPOLLSHIM_FOUND)
target_include_directories(glfw PRIVATE ${EPOLLSHIM_INCLUDE_DIRS})
target_link_libraries(glfw PRIVATE ${EPOLLSHIM_LIBRARIES})
endif()
endif()
endif()
if (GLFW_BUILD_X11)
find_package(X11 REQUIRED)
target_include_directories(glfw PRIVATE "${X11_X11_INCLUDE_PATH}")
# Check for XRandR (modern resolution switching and gamma control)
if (NOT X11_Xrandr_INCLUDE_PATH)
message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
endif()
target_include_directories(glfw PRIVATE "${X11_Xrandr_INCLUDE_PATH}")
# Check for Xinerama (legacy multi-monitor support)
if (NOT X11_Xinerama_INCLUDE_PATH)
message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
endif()
target_include_directories(glfw PRIVATE "${X11_Xinerama_INCLUDE_PATH}")
# Check for Xkb (X keyboard extension)
if (NOT X11_Xkb_INCLUDE_PATH)
message(FATAL_ERROR "XKB headers not found; install X11 development package")
endif()
target_include_directories(glfw PRIVATE "${X11_Xkb_INCLUDE_PATH}")
# Check for Xcursor (cursor creation from RGBA images)
if (NOT X11_Xcursor_INCLUDE_PATH)
message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
endif()
target_include_directories(glfw PRIVATE "${X11_Xcursor_INCLUDE_PATH}")
# Check for XInput (modern HID input)
if (NOT X11_Xi_INCLUDE_PATH)
message(FATAL_ERROR "XInput headers not found; install libxi development package")
endif()
target_include_directories(glfw PRIVATE "${X11_Xi_INCLUDE_PATH}")
# Check for X Shape (custom window input shape)
if (NOT X11_Xshape_INCLUDE_PATH)
message(FATAL_ERROR "X Shape headers not found; install libxext development package")
endif()
target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}")
endif()
if (UNIX AND NOT APPLE)
find_library(RT_LIBRARY rt)
mark_as_advanced(RT_LIBRARY)
if (RT_LIBRARY)
target_link_libraries(glfw PRIVATE "${RT_LIBRARY}")
list(APPEND glfw_PKG_LIBS "-lrt")
endif()
find_library(MATH_LIBRARY m)
mark_as_advanced(MATH_LIBRARY)
if (MATH_LIBRARY)
target_link_libraries(glfw PRIVATE "${MATH_LIBRARY}")
list(APPEND glfw_PKG_LIBS "-lm")
endif()
if (CMAKE_DL_LIBS)
target_link_libraries(glfw PRIVATE "${CMAKE_DL_LIBS}")
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
endif()
endif()
# Make GCC warn about declarations that VS 2010 and 2012 won't accept for all
# source files that VS will build (Clang ignores this because we set -std=c99)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
set_source_files_properties(context.c init.c input.c monitor.c platform.c vulkan.c
window.c null_init.c null_joystick.c null_monitor.c
null_window.c win32_init.c win32_joystick.c win32_module.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)
endif()
if (WIN32)
if (GLFW_USE_HYBRID_HPG)
target_compile_definitions(glfw PRIVATE _GLFW_USE_HYBRID_HPG)
endif()
endif()
# Enable a reasonable set of warnings
# NOTE: The order matters here, Clang-CL matches both MSVC and Clang
if (MSVC)
target_compile_options(glfw PRIVATE "/W3")
elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
CMAKE_C_COMPILER_ID STREQUAL "Clang" OR
CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
target_compile_options(glfw PRIVATE "-Wall")
endif()
if (GLFW_BUILD_WIN32)
target_compile_definitions(glfw PRIVATE UNICODE _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 WINVER=0x0501)
endif()
# Enable a reasonable set of warnings (no, -Wextra is not reasonable) # Workaround for legacy MinGW not providing XInput and DirectInput
target_compile_options(glfw PRIVATE if (MINGW)
"$<$<C_COMPILER_ID:AppleClang>:-Wall>" include(CheckIncludeFile)
"$<$<C_COMPILER_ID:Clang>:-Wall>" check_include_file(dinput.h DINPUT_H_FOUND)
"$<$<C_COMPILER_ID:GNU>:-Wall>") check_include_file(xinput.h XINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw")
endif()
endif()
if (BUILD_SHARED_LIBS) # Workaround for the MS CRT deprecating parts of the standard library
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
# Workaround for VS 2008 not shipping with stdint.h
if (MSVC90)
target_include_directories(glfw PUBLIC "${GLFW_SOURCE_DIR}/deps/vs2008")
endif()
# Check for the DirectX 9 SDK as it is not included with VS 2008
if (MSVC90)
include(CheckIncludeFile)
check_include_file(dinput.h DINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND)
message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
endif()
endif()
# Workaround for -std=c99 on Linux disabling _DEFAULT_SOURCE (POSIX 2008 and more)
if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_compile_definitions(glfw PRIVATE _DEFAULT_SOURCE)
endif()
endif()
if (GLFW_BUILD_SHARED_LIBRARY)
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,31 +337,63 @@ 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")
set_target_properties(glfw PROPERTIES target_compile_definitions(glfw INTERFACE GLFW_DLL)
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}") endif()
elseif (UNIX)
if (MINGW)
# Enable link-time exploit mitigation features enabled by default on MSVC
include(CheckCCompilerFlag)
# Compatibility with data execution prevention (DEP)
set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
check_c_compiler_flag("" _GLFW_HAS_DEP)
if (_GLFW_HAS_DEP)
target_link_libraries(glfw PRIVATE "-Wl,--nxcompat")
endif()
# Compatibility with address space layout randomization (ASLR)
set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
check_c_compiler_flag("" _GLFW_HAS_ASLR)
if (_GLFW_HAS_ASLR)
target_link_libraries(glfw PRIVATE "-Wl,--dynamicbase")
endif()
# Compatibility with 64-bit address space layout randomization (ASLR)
set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
check_c_compiler_flag("" _GLFW_HAS_64ASLR)
if (_GLFW_HAS_64ASLR)
target_link_libraries(glfw PRIVATE "-Wl,--high-entropy-va")
endif()
# Clear flags again to avoid breaking later tests
set(CMAKE_REQUIRED_FLAGS)
endif()
if (UNIX)
# 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) foreach(arg ${glfw_PKG_DEPS})
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) string(APPEND deps " ${arg}")
endif() endforeach()
foreach(arg ${glfw_PKG_LIBS})
string(APPEND libs " ${arg}")
endforeach()
set(GLFW_PKG_CONFIG_REQUIRES_PRIVATE "${deps}" CACHE INTERNAL
"GLFW pkg-config Requires.private")
set(GLFW_PKG_CONFIG_LIBS_PRIVATE "${libs}" CACHE INTERNAL
"GLFW pkg-config Libs.private")
configure_file("${GLFW_SOURCE_DIR}/CMake/glfw3.pc.in" glfw3.pc @ONLY)
if (GLFW_INSTALL) if (GLFW_INSTALL)
install(TARGETS glfw install(TARGETS glfw
EXPORT glfwTargets EXPORT glfwTargets
RUNTIME DESTINATION "bin" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif() endif()

View File

@ -23,8 +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"
#if defined(_GLFW_COCOA)
#include <sys/param.h> // For MAXPATHLEN #include <sys/param.h> // For MAXPATHLEN
// Needed for _NSGetProgname // Needed for _NSGetProgname
@ -73,7 +78,6 @@ static void changeToResourcesDirectory(void)
// //
static void createMenuBar(void) static void createMenuBar(void)
{ {
size_t i;
NSString* appName = nil; NSString* appName = nil;
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
NSString* nameKeys[] = NSString* nameKeys[] =
@ -85,7 +89,7 @@ static void createMenuBar(void)
// Try to figure out what the calling application is called // Try to figure out what the calling application is called
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
{ {
id name = bundleInfo[nameKeys[i]]; id name = bundleInfo[nameKeys[i]];
if (name && if (name &&
@ -175,8 +179,6 @@ static void createMenuBar(void)
// //
static void createKeyTables(void) static void createKeyTables(void)
{ {
int scancode;
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes)); memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes)); memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
@ -249,7 +251,7 @@ static void createKeyTables(void)
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10; _glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11; _glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12; _glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
_glfw.ns.keycodes[0x69] = GLFW_KEY_F13; _glfw.ns.keycodes[0x69] = GLFW_KEY_PRINT_SCREEN;
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14; _glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15; _glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16; _glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
@ -295,7 +297,7 @@ static void createKeyTables(void)
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY; _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT; _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 256; scancode++) for (int scancode = 0; scancode < 256; scancode++)
{ {
// Store the reverse translation for faster key name lookup // Store the reverse translation for faster key name lookup
if (_glfw.ns.keycodes[scancode] >= 0) if (_glfw.ns.keycodes[scancode] >= 0)
@ -305,7 +307,7 @@ static void createKeyTables(void)
// Retrieve Unicode data for the current keyboard layout // Retrieve Unicode data for the current keyboard layout
// //
static GLFWbool updateUnicodeDataNS(void) static GLFWbool updateUnicodeData(void)
{ {
if (_glfw.ns.inputSource) if (_glfw.ns.inputSource)
{ {
@ -375,7 +377,7 @@ static GLFWbool initializeTIS(void)
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData = _glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
*kPropertyUnicodeKeyLayoutData; *kPropertyUnicodeKeyLayoutData;
return updateUnicodeDataNS(); return updateUnicodeData();
} }
@interface GLFWHelper : NSObject @interface GLFWHelper : NSObject
@ -385,7 +387,7 @@ static GLFWbool initializeTIS(void)
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object - (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{ {
updateUnicodeDataNS(); updateUnicodeData();
} }
- (void)doNothing:(id)object - (void)doNothing:(id)object
@ -401,9 +403,7 @@ static GLFWbool initializeTIS(void)
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{ {
_GLFWwindow* window; for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
for (window = _glfw.windowListHead; window; window = window->next)
_glfwInputWindowCloseRequest(window); _glfwInputWindowCloseRequest(window);
return NSTerminateCancel; return NSTerminateCancel;
@ -411,27 +411,21 @@ static GLFWbool initializeTIS(void)
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification - (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{ {
_GLFWwindow* window; for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
for (window = _glfw.windowListHead; window; window = window->next)
{ {
if (window->context.client != GLFW_NO_API) if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
} }
_glfwPollMonitorsNS(); _glfwPollMonitorsCocoa();
} }
- (void)applicationWillFinishLaunching:(NSNotification *)notification - (void)applicationWillFinishLaunching:(NSNotification *)notification
{ {
if (_glfw.hints.init.ns.menubar) if (_glfw.hints.init.ns.menubar)
{ {
// In case we are unbundled, make us a proper UI application // Menu bar setup must go between sharedApplication and finishLaunching
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; // in order to properly emulate the behavior of NSApplicationMain
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
{ {
@ -446,27 +440,140 @@ static GLFWbool initializeTIS(void)
- (void)applicationDidFinishLaunching:(NSNotification *)notification - (void)applicationDidFinishLaunching:(NSNotification *)notification
{ {
_glfwPostEmptyEventCocoa();
[NSApp stop:nil]; [NSApp stop:nil];
_glfwPlatformPostEmptyEvent();
} }
- (void)applicationDidHide:(NSNotification *)notification - (void)applicationDidHide:(NSNotification *)notification
{ {
int i; for (int i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeCocoa(_glfw.monitors[i]);
for (i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeNS(_glfw.monitors[i]);
} }
@end // GLFWApplicationDelegate @end // GLFWApplicationDelegate
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwLoadLocalVulkanLoaderCocoa(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
if (!frameworksUrl)
return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfwPlatformLoadModule(path);
CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void) GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform cocoa =
{
GLFW_PLATFORM_COCOA,
_glfwInitCocoa,
_glfwTerminateCocoa,
_glfwGetCursorPosCocoa,
_glfwSetCursorPosCocoa,
_glfwSetCursorModeCocoa,
_glfwSetRawMouseMotionCocoa,
_glfwRawMouseMotionSupportedCocoa,
_glfwCreateCursorCocoa,
_glfwCreateStandardCursorCocoa,
_glfwDestroyCursorCocoa,
_glfwSetCursorCocoa,
_glfwGetScancodeNameCocoa,
_glfwGetKeyScancodeCocoa,
_glfwSetClipboardStringCocoa,
_glfwGetClipboardStringCocoa,
_glfwInitJoysticksCocoa,
_glfwTerminateJoysticksCocoa,
_glfwPollJoystickCocoa,
_glfwGetMappingNameCocoa,
_glfwUpdateGamepadGUIDCocoa,
_glfwFreeMonitorCocoa,
_glfwGetMonitorPosCocoa,
_glfwGetMonitorContentScaleCocoa,
_glfwGetMonitorWorkareaCocoa,
_glfwGetVideoModesCocoa,
_glfwGetVideoModeCocoa,
_glfwGetGammaRampCocoa,
_glfwSetGammaRampCocoa,
_glfwCreateWindowCocoa,
_glfwDestroyWindowCocoa,
_glfwSetWindowTitleCocoa,
_glfwSetWindowIconCocoa,
_glfwGetWindowPosCocoa,
_glfwSetWindowPosCocoa,
_glfwGetWindowSizeCocoa,
_glfwSetWindowSizeCocoa,
_glfwSetWindowSizeLimitsCocoa,
_glfwSetWindowAspectRatioCocoa,
_glfwGetFramebufferSizeCocoa,
_glfwGetWindowFrameSizeCocoa,
_glfwGetWindowContentScaleCocoa,
_glfwIconifyWindowCocoa,
_glfwRestoreWindowCocoa,
_glfwMaximizeWindowCocoa,
_glfwShowWindowCocoa,
_glfwHideWindowCocoa,
_glfwRequestWindowAttentionCocoa,
_glfwFocusWindowCocoa,
_glfwSetWindowMonitorCocoa,
_glfwWindowFocusedCocoa,
_glfwWindowIconifiedCocoa,
_glfwWindowVisibleCocoa,
_glfwWindowMaximizedCocoa,
_glfwWindowHoveredCocoa,
_glfwFramebufferTransparentCocoa,
_glfwGetWindowOpacityCocoa,
_glfwSetWindowResizableCocoa,
_glfwSetWindowDecoratedCocoa,
_glfwSetWindowFloatingCocoa,
_glfwSetWindowOpacityCocoa,
_glfwSetWindowMousePassthroughCocoa,
_glfwPollEventsCocoa,
_glfwWaitEventsCocoa,
_glfwWaitEventsTimeoutCocoa,
_glfwPostEmptyEventCocoa,
_glfwGetEGLPlatformCocoa,
_glfwGetEGLNativeDisplayCocoa,
_glfwGetEGLNativeWindowCocoa,
_glfwGetRequiredInstanceExtensionsCocoa,
_glfwGetPhysicalDevicePresentationSupportCocoa,
_glfwCreateWindowSurfaceCocoa,
};
*platform = cocoa;
return GLFW_TRUE;
}
int _glfwInitCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -476,9 +583,6 @@ int _glfwPlatformInit(void)
toTarget:_glfw.ns.helper toTarget:_glfw.ns.helper
withObject:nil]; withObject:nil];
if (NSApp)
_glfw.ns.finishedLaunching = GLFW_TRUE;
[NSApplication sharedApplication]; [NSApplication sharedApplication];
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
@ -527,16 +631,21 @@ int _glfwPlatformInit(void)
if (!initializeTIS()) if (!initializeTIS())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitTimerNS(); _glfwPollMonitorsCocoa();
_glfwInitJoysticksNS();
if (![[NSRunningApplication currentApplication] isFinishedLaunching])
[NSApp run];
// In case we are unbundled, make us a proper UI application
if (_glfw.hints.init.ns.menubar)
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
_glfwPollMonitorsNS();
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformTerminate(void) void _glfwTerminateCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -575,20 +684,14 @@ void _glfwPlatformTerminate(void)
if (_glfw.ns.keyUpMonitor) if (_glfw.ns.keyUpMonitor)
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor]; [NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
free(_glfw.ns.clipboardString); _glfw_free(_glfw.ns.clipboardString);
_glfwTerminateNSGL(); _glfwTerminateNSGL();
_glfwTerminateJoysticksNS(); _glfwTerminateEGL();
_glfwTerminateOSMesa();
} // autoreleasepool } // autoreleasepool
} }
const char* _glfwPlatformGetVersionString(void) #endif // _GLFW_COCOA
{
return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa"
#if defined(_GLFW_BUILD_DLL)
" dynamic"
#endif
;
}

View File

@ -26,13 +26,10 @@
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h> #include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h> #include <IOKit/hid/IOHIDKeys.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns #define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns;
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE #define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
// Cocoa-specific per-joystick data // Cocoa-specific per-joystick data
// //
@ -44,7 +41,9 @@ typedef struct _GLFWjoystickNS
CFMutableArrayRef hats; CFMutableArrayRef hats;
} _GLFWjoystickNS; } _GLFWjoystickNS;
GLFWbool _glfwInitJoysticksCocoa(void);
void _glfwInitJoysticksNS(void); void _glfwTerminateJoysticksCocoa(void);
void _glfwTerminateJoysticksNS(void); GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameCocoa(void);
void _glfwUpdateGamepadGUIDCocoa(char* guid);

View File

@ -24,9 +24,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"
#if defined(_GLFW_COCOA)
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
@ -94,25 +98,21 @@ static CFComparisonResult compareElements(const void* fp,
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
int i; _glfwInputJoystick(js, GLFW_DISCONNECTED);
if (!js->present) for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++)
return; _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
CFRelease(js->ns.axes); CFRelease(js->ns.axes);
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++) for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i)); _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
CFRelease(js->ns.buttons); CFRelease(js->ns.buttons);
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i)); _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
CFRelease(js->ns.hats); CFRelease(js->ns.hats);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// Callback for user-initiated joystick addition // Callback for user-initiated joystick addition
@ -125,7 +125,6 @@ static void matchCallback(void* context,
int jid; int jid;
char name[256]; char name[256];
char guid[33]; char guid[33];
CFIndex i;
CFTypeRef property; CFTypeRef property;
uint32_t vendor = 0, product = 0, version = 0; uint32_t vendor = 0, product = 0, version = 0;
_GLFWjoystick* js; _GLFWjoystick* js;
@ -183,7 +182,7 @@ static void matchCallback(void* context,
CFArrayRef elements = CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
for (i = 0; i < CFArrayGetCount(elements); i++) for (CFIndex i = 0; i < CFArrayGetCount(elements); i++)
{ {
IOHIDElementRef native = (IOHIDElementRef) IOHIDElementRef native = (IOHIDElementRef)
CFArrayGetValueAtIndex(elements, i); CFArrayGetValueAtIndex(elements, i);
@ -249,7 +248,7 @@ static void matchCallback(void* context,
if (target) if (target)
{ {
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS)); _GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS));
element->native = native; element->native = native;
element->usage = usage; element->usage = usage;
element->index = (int) CFArrayGetCount(target); element->index = (int) CFArrayGetCount(target);
@ -288,13 +287,11 @@ static void removeCallback(void* context,
void* sender, void* sender,
IOHIDDeviceRef device) IOHIDDeviceRef device)
{ {
int jid; for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (_glfw.joysticks[jid].ns.device == device) if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
{ {
closeJoystick(_glfw.joysticks + jid); closeJoystick(&_glfw.joysticks[jid]);
break; break;
} }
} }
@ -302,12 +299,10 @@ static void removeCallback(void* context,
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Initialize joystick interface GLFWbool _glfwInitJoysticksCocoa(void)
//
void _glfwInitJoysticksNS(void)
{ {
CFMutableArrayRef matching; CFMutableArrayRef matching;
const long usages[] = const long usages[] =
@ -326,10 +321,10 @@ void _glfwInitJoysticksNS(void)
if (!matching) if (!matching)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array"); _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
return; return GLFW_FALSE;
} }
for (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;
@ -381,33 +376,30 @@ void _glfwInitJoysticksNS(void)
// Execute the run loop once in order to register any initially-attached // Execute the run loop once in order to register any initially-attached
// joysticks // joysticks
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
return GLFW_TRUE;
} }
// Close all opened joystick handles void _glfwTerminateJoysticksCocoa(void)
//
void _glfwTerminateJoysticksNS(void)
{ {
int jid; for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].connected)
closeJoystick(&_glfw.joysticks[jid]);
}
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) if (_glfw.ns.hidManager)
closeJoystick(_glfw.joysticks + jid); {
CFRelease(_glfw.ns.hidManager);
CFRelease(_glfw.ns.hidManager); _glfw.ns.hidManager = NULL;
_glfw.ns.hidManager = NULL; }
} }
////////////////////////////////////////////////////////////////////////// GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{ {
if (mode & _GLFW_POLL_AXES) if (mode & _GLFW_POLL_AXES)
{ {
CFIndex i; for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++)
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
{ {
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*) _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.axes, i); CFArrayGetValueAtIndex(js->ns.axes, i);
@ -432,9 +424,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (mode & _GLFW_POLL_BUTTONS) if (mode & _GLFW_POLL_BUTTONS)
{ {
CFIndex i; for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
{ {
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*) _GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i); CFArrayGetValueAtIndex(js->ns.buttons, i);
@ -443,7 +433,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
_glfwInputJoystickButton(js, (int) i, state); _glfwInputJoystickButton(js, (int) i, state);
} }
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++)
{ {
const int states[9] = const int states[9] =
{ {
@ -468,10 +458,15 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
} }
} }
return js->present; return js->connected;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameCocoa(void)
{
return "Mac OS X";
}
void _glfwUpdateGamepadGUIDCocoa(char* guid)
{ {
if ((strncmp(guid + 4, "000000000000", 12) == 0) && if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
(strncmp(guid + 20, "000000000000", 12) == 0)) (strncmp(guid + 20, "000000000000", 12) == 0))
@ -483,3 +478,5 @@ void _glfwPlatformUpdateGamepadGUID(char* guid)
} }
} }
#endif // _GLFW_COCOA

View File

@ -24,9 +24,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"
#if defined(_GLFW_COCOA)
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
@ -37,18 +41,31 @@
// Get the name of the specified display, or NULL // Get the name of the specified display, or NULL
// //
static char* getDisplayName(CGDirectDisplayID displayID) static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
{ {
// IOKit doesn't work on Apple Silicon anymore
// Luckily, 10.15 introduced -[NSScreen localizedName].
// Use it if available, and fall back to IOKit otherwise.
if (screen)
{
if ([screen respondsToSelector:@selector(localizedName)])
{
NSString* name = [screen valueForKey:@"localizedName"];
if (name)
return _glfw_strdup([name UTF8String]);
}
}
io_iterator_t it; io_iterator_t it;
io_service_t service; io_service_t service;
CFDictionaryRef info; CFDictionaryRef info;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, if (IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceMatching("IODisplayConnect"), IOServiceMatching("IODisplayConnect"),
&it) != 0) &it) != 0)
{ {
// This may happen if a desktop Mac is running headless // This may happen if a desktop Mac is running headless
return NULL; return _glfw_strdup("Display");
} }
while ((service = IOIteratorNext(it)) != 0) while ((service = IOIteratorNext(it)) != 0)
@ -83,11 +100,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
IOObjectRelease(it); IOObjectRelease(it);
if (!service) if (!service)
{ return _glfw_strdup("Display");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find service port for display");
return NULL;
}
CFDictionaryRef names = CFDictionaryRef names =
CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
@ -99,13 +112,13 @@ static char* getDisplayName(CGDirectDisplayID displayID)
{ {
// This may happen if a desktop Mac is running headless // This may happen if a desktop Mac is running headless
CFRelease(info); CFRelease(info);
return NULL; return _glfw_strdup("Display");
} }
const CFIndex size = const CFIndex size =
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
kCFStringEncodingUTF8); kCFStringEncodingUTF8);
char* name = calloc(size + 1, 1); char* name = _glfw_calloc(size + 1, 1);
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8); CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
CFRelease(info); CFRelease(info);
@ -142,7 +155,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 +163,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);
@ -211,29 +220,72 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
} }
} }
// Finds and caches the NSScreen corresponding to the specified monitor // Returns the display refresh rate queried from the I/O registry
// //
GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor) static double getFallbackRefreshRate(CGDirectDisplayID displayID)
{ {
if (monitor->ns.screen) double refreshRate = 60.0;
return GLFW_TRUE;
for (NSScreen* screen in [NSScreen screens]) io_iterator_t it;
io_service_t service;
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceMatching("IOFramebuffer"),
&it) != 0)
{ {
NSNumber* displayID = [screen deviceDescription][@"NSScreenNumber"]; return refreshRate;
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (monitor->ns.unitNumber == CGDisplayUnitNumber([displayID unsignedIntValue]))
{
monitor->ns.screen = screen;
return GLFW_TRUE;
}
} }
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor"); while ((service = IOIteratorNext(it)) != 0)
return GLFW_FALSE; {
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);
uint32_t clock = 0, count = 0;
if (clockRef)
{
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
CFRelease(clockRef);
}
if (countRef)
{
CFNumberGetValue(countRef, kCFNumberIntType, &count);
CFRelease(countRef);
}
if (clock > 0 && count > 0)
refreshRate = clock / (double) count;
break;
}
IOObjectRelease(it);
return refreshRate;
} }
@ -243,100 +295,115 @@ GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
// Poll for changes in the set of connected monitors // Poll for changes in the set of connected monitors
// //
void _glfwPollMonitorsNS(void) void _glfwPollMonitorsCocoa(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 = _glfw_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 = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected, memcpy(disconnected,
_glfw.monitors, _glfw.monitors,
_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++) const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
NSScreen* screen = nil;
for (screen in [NSScreen screens])
{ {
NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around // HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics // display replacement on machines with automatic graphics
// switching // switching
if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
break;
}
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
uint32_t j;
for (j = 0; j < disconnectedCount; j++)
{
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber) if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
{ {
disconnected[j]->ns.screen = screen;
disconnected[j] = NULL; disconnected[j] = NULL;
break; break;
} }
} }
const CGSize size = CGDisplayScreenSize(displays[i]); if (j < disconnectedCount)
char* name = getDisplayName(displays[i]); continue;
if (!name)
name = _glfw_strdup("Unknown");
monitor = _glfwAllocMonitor(name, size.width, size.height); const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getMonitorName(displays[i], screen);
if (!name)
continue;
_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;
monitor->ns.screen = screen;
free(name); _glfw_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);
} }
free(disconnected); _glfw_free(disconnected);
free(displays); _glfw_free(displays);
} }
// Change the current video mode // Change the current video mode
// //
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{ {
CFArrayRef modes;
CFIndex count, i;
CVDisplayLinkRef link;
CGDisplayModeRef native = NULL;
GLFWvidmode current; GLFWvidmode current;
const GLFWvidmode* best; _glfwGetVideoModeCocoa(monitor, &current);
best = _glfwChooseVideoMode(monitor, desired); const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, 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,12 +422,11 @@ 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
// //
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor) void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor)
{ {
if (monitor->ns.previousMode) if (monitor->ns.previousMode)
{ {
@ -379,11 +445,11 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor)
{ {
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
@autoreleasepool { @autoreleasepool {
@ -397,13 +463,16 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
@autoreleasepool { @autoreleasepool {
if (!refreshMonitorScreen(monitor)) if (!monitor->ns.screen)
return; {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Cannot query content scale without screen");
}
const NSRect points = [monitor->ns.screen frame]; const NSRect points = [monitor->ns.screen frame];
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points]; const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
@ -416,21 +485,24 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
@autoreleasepool { @autoreleasepool {
if (!refreshMonitorScreen(monitor)) if (!monitor->ns.screen)
return; {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Cannot query workarea without screen");
}
const NSRect frameRect = [monitor->ns.screen visibleFrame]; const NSRect frameRect = [monitor->ns.screen visibleFrame];
if (xpos) if (xpos)
*xpos = frameRect.origin.x; *xpos = frameRect.origin.x;
if (ypos) if (ypos)
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1); *ypos = _glfwTransformYCocoa(frameRect.origin.y + frameRect.size.height - 1);
if (width) if (width)
*width = frameRect.size.width; *width = frameRect.size.width;
if (height) if (height)
@ -439,30 +511,25 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
} // autoreleasepool } // autoreleasepool
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) GLFWvidmode* _glfwGetVideoModesCocoa(_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 = _glfw_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++)
{ {
@ -471,7 +538,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
} }
// Skip duplicate modes // Skip duplicate modes
if (i < *count) if (j < *count)
continue; continue;
(*count)++; (*count)++;
@ -479,36 +546,28 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
} }
CFRelease(modes); CFRelease(modes);
CVDisplayLinkRelease(link);
return result; return result;
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) void _glfwGetVideoModeCocoa(_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
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampCocoa(_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 = _glfw_calloc(size * 3, sizeof(CGGammaValue));
CGGetDisplayTransferByTable(monitor->ns.displayID, CGGetDisplayTransferByTable(monitor->ns.displayID,
size, size,
@ -519,27 +578,26 @@ 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);
ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
} }
free(values); _glfw_free(values);
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
@autoreleasepool { @autoreleasepool {
int i; CGGammaValue* values = _glfw_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;
@ -552,7 +610,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
values + ramp->size, values + ramp->size,
values + ramp->size * 2); values + ramp->size * 2);
free(values); _glfw_free(values);
} // autoreleasepool } // autoreleasepool
} }
@ -569,3 +627,5 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
return monitor->ns.displayID; return monitor->ns.displayID;
} }
#endif // _GLFW_COCOA

View File

@ -25,15 +25,15 @@
//======================================================================== //========================================================================
#include <stdint.h> #include <stdint.h>
#include <dlfcn.h>
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <CoreVideo/CVBase.h> #include <IOKit/hid/IOHIDLib.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
#ifndef GL_SILENCE_DEPRECATION
#define GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION
#endif
#if defined(__OBJC__) #if defined(__OBJC__)
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -41,6 +41,16 @@
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 deprecated.
// We use the newer names in code and replace them with the older names if
// the base SDK does not provide the newer names.
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
#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
@ -59,7 +69,17 @@ typedef void* id;
#define NSWindowStyleMaskTitled NSTitledWindowMask #define NSWindowStyleMaskTitled NSTitledWindowMask
#endif #endif
// NOTE: Many Cocoa dynamically linked constants have been renamed and we need
// to build across SDK versions where one is unavailable or deprecated.
// We use the newer names in code and replace them with the older names if
// the deployment target is older than the newer names.
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
#define NSPasteboardTypeURL NSURLPboardType
#endif
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
typedef struct VkMacOSSurfaceCreateInfoMVK typedef struct VkMacOSSurfaceCreateInfoMVK
{ {
@ -69,26 +89,24 @@ 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" #define GLFW_COCOA_WINDOW_STATE _GLFWwindowNS ns;
#include "cocoa_joystick.h" #define GLFW_COCOA_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns;
#include "nsgl_context.h" #define GLFW_COCOA_MONITOR_STATE _GLFWmonitorNS ns;
#include "egl_context.h" #define GLFW_COCOA_CURSOR_STATE _GLFWcursorNS ns;
#include "osmesa_context.h"
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) #define GLFW_NSGL_CONTEXT_STATE _GLFWcontextNSGL nsgl;
#define _glfw_dlclose(handle) dlclose(handle) #define GLFW_NSGL_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.view)
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
// HIToolbox.framework pointer typedefs // HIToolbox.framework pointer typedefs
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData #define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
@ -100,6 +118,22 @@ typedef UInt8 (*PFN_LMGetKbdType)(void);
#define LMGetKbdType _glfw.ns.tis.GetKbdType #define LMGetKbdType _glfw.ns.tis.GetKbdType
// NSGL-specific per-context data
//
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
} _GLFWcontextNSGL;
// NSGL-specific global data
//
typedef struct _GLFWlibraryNSGL
{
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
CFBundleRef framework;
} _GLFWlibraryNSGL;
// Cocoa-specific per-window data // Cocoa-specific per-window data
// //
typedef struct _GLFWwindowNS typedef struct _GLFWwindowNS
@ -110,6 +144,7 @@ typedef struct _GLFWwindowNS
id layer; id layer;
GLFWbool maximized; GLFWbool maximized;
GLFWbool occluded;
GLFWbool retina; GLFWbool retina;
// Cached window properties to filter out duplicate events // Cached window properties to filter out duplicate events
@ -121,7 +156,6 @@ typedef struct _GLFWwindowNS
// since the last cursor motion event was processed // since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally // This is kept to counteract Cocoa doing the same internally
double cursorWarpDeltaX, cursorWarpDeltaY; double cursorWarpDeltaX, cursorWarpDeltaY;
} _GLFWwindowNS; } _GLFWwindowNS;
// Cocoa-specific global data // Cocoa-specific global data
@ -130,7 +164,6 @@ typedef struct _GLFWlibraryNS
{ {
CGEventSourceRef eventSource; CGEventSourceRef eventSource;
id delegate; id delegate;
GLFWbool finishedLaunching;
GLFWbool cursorHidden; GLFWbool cursorHidden;
TISInputSourceRef inputSource; TISInputSourceRef inputSource;
IOHIDManagerRef hidManager; IOHIDManagerRef hidManager;
@ -139,7 +172,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;
@ -156,7 +189,6 @@ typedef struct _GLFWlibraryNS
PFN_LMGetKbdType GetKbdType; PFN_LMGetKbdType GetKbdType;
CFStringRef kPropertyUnicodeKeyLayoutData; CFStringRef kPropertyUnicodeKeyLayoutData;
} tis; } tis;
} _GLFWlibraryNS; } _GLFWlibraryNS;
// Cocoa-specific per-monitor data // Cocoa-specific per-monitor data
@ -167,7 +199,7 @@ typedef struct _GLFWmonitorNS
CGDisplayModeRef previousMode; CGDisplayModeRef previousMode;
uint32_t unitNumber; uint32_t unitNumber;
id screen; id screen;
double fallbackRefreshRate;
} _GLFWmonitorNS; } _GLFWmonitorNS;
// Cocoa-specific per-cursor data // Cocoa-specific per-cursor data
@ -175,23 +207,96 @@ typedef struct _GLFWmonitorNS
typedef struct _GLFWcursorNS typedef struct _GLFWcursorNS
{ {
id object; id object;
} _GLFWcursorNS; } _GLFWcursorNS;
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
{
uint64_t frequency;
} _GLFWtimerNS; GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform);
int _glfwInitCocoa(void);
void _glfwTerminateCocoa(void);
GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowCocoa(_GLFWwindow* window);
void _glfwRestoreWindowCocoa(_GLFWwindow* window);
void _glfwMaximizeWindowCocoa(_GLFWwindow* window);
void _glfwShowWindowCocoa(_GLFWwindow* window);
void _glfwHideWindowCocoa(_GLFWwindow* window);
void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window);
void _glfwFocusWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window);
void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityCocoa(_GLFWwindow* window);
void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwInitTimerNS(void); void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedCocoa(void);
void _glfwPollMonitorsNS(void); void _glfwPollEventsCocoa(void);
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwWaitEventsCocoa(void);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor); void _glfwWaitEventsTimeoutCocoa(double timeout);
void _glfwPostEmptyEventCocoa(void);
float _glfwTransformYNS(float y); void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosCocoa(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameCocoa(int scancode);
int _glfwGetKeyScancodeCocoa(int key);
GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorCocoa(_GLFWcursor* cursor);
void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringCocoa(const char* string);
const char* _glfwGetClipboardStringCocoa(void);
EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void);
EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor);
void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count);
void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPollMonitorsCocoa(void);
void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
float _glfwTransformYCocoa(float y);
void* _glfwLoadLocalVulkanLoaderCocoa(void);
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);

View File

@ -23,19 +23,21 @@
// 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"
#if defined(GLFW_BUILD_COCOA_TIMER)
#include <mach/mach_time.h> #include <mach/mach_time.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Initialise timer void _glfwPlatformInitTimer(void)
//
void _glfwInitTimerNS(void)
{ {
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
mach_timebase_info(&info); mach_timebase_info(&info);
@ -43,11 +45,6 @@ void _glfwInitTimerNS(void)
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer; _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
} }
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void) uint64_t _glfwPlatformGetTimerValue(void)
{ {
return mach_absolute_time(); return mach_absolute_time();
@ -58,3 +55,5 @@ uint64_t _glfwPlatformGetTimerFrequency(void)
return _glfw.timer.ns.frequency; return _glfw.timer.ns.frequency;
} }
#endif // GLFW_BUILD_COCOA_TIMER

35
src/cocoa_time.h Normal file
View File

@ -0,0 +1,35 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_COCOA_LIBRARY_TIMER_STATE _GLFWtimerNS ns;
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
{
uint64_t frequency;
} _GLFWtimerNS;

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,8 @@
// distribution. // distribution.
// //
//======================================================================== //========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h" #include "internal.h"
@ -46,16 +48,6 @@
// //
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{ {
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API && if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API && ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API) ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
@ -76,6 +68,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
return GLFW_FALSE; return GLFW_FALSE;
} }
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (ctxconfig->source != ctxconfig->share->context.source)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Context creation APIs do not match between contexts");
return GLFW_FALSE;
}
}
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
@ -194,12 +203,6 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
continue; continue;
} }
if (desired->doublebuffer != current->doublebuffer)
{
// Double buffering is a hard constraint
continue;
}
// Count number of missing buffers // Count number of missing buffers
{ {
missing = 0; missing = 0;
@ -568,7 +571,9 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
window->context.getProcAddress("glClear"); window->context.getProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
window->context.swapBuffers(window);
if (window->doublebuffer)
window->context.swapBuffers(window);
} }
glfwMakeContextCurrent((GLFWwindow*) previous); glfwMakeContextCurrent((GLFWwindow*) previous);
@ -611,10 +616,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* previous;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window && window->context.client == GLFW_NO_API) if (window && window->context.client == GLFW_NO_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, _glfwInputError(GLFW_NO_WINDOW_CONTEXT,

View File

@ -24,6 +24,8 @@
// distribution. // distribution.
// //
//======================================================================== //========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h" #include "internal.h"
@ -86,13 +88,30 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
// Return the EGLConfig most closely matching the specified hints // Return the EGLConfig most closely matching the specified hints
// //
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* desired, const _GLFWfbconfig* fbconfig,
EGLConfig* result) EGLConfig* result)
{ {
EGLConfig* nativeConfigs; EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount; int i, nativeCount, usableCount, apiBit;
GLFWbool wrongApiAvailable = GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
apiBit = EGL_OPENGL_ES_BIT;
else
apiBit = EGL_OPENGL_ES2_BIT;
}
else
apiBit = EGL_OPENGL_BIT;
if (fbconfig->stereo)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
return GLFW_FALSE;
}
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount) if (!nativeCount)
@ -101,10 +120,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
return GLFW_FALSE; return GLFW_FALSE;
} }
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0; usableCount = 0;
for (i = 0; i < nativeCount; i++) for (i = 0; i < nativeCount; i++)
@ -121,44 +140,33 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
continue; continue;
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
XVisualInfo vi = {0}; if (_glfw.platform.platformID == GLFW_PLATFORM_X11)
// 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 (fbconfig->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
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
{ {
if (ctxconfig->major == 1) wrongApiAvailable = GLFW_TRUE;
{ continue;
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
continue;
}
else
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
continue;
}
}
else if (ctxconfig->client == GLFW_OPENGL_API)
{
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
continue;
} }
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE); u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
@ -169,19 +177,63 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE); u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE); u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
// NOTE: The wl_surface opaque region is no guarantee that its buffer
// is presented as opaque, if it also has an alpha channel
// HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
// with an alpha channel to ensure the buffer is opaque
if (!_glfw.egl.EXT_present_opaque)
{
if (!fbconfig->transparent && u->alphaBits > 0)
continue;
}
}
#endif // _GLFW_WAYLAND
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = GLFW_TRUE; u->doublebuffer = fbconfig->doublebuffer;
u->handle = (uintptr_t) n; u->handle = (uintptr_t) n;
usableCount++; usableCount++;
} }
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
if (closest) if (closest)
*result = (EGLConfig) closest->handle; *result = (EGLConfig) closest->handle;
else
{
if (wrongApiAvailable)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 1.x");
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 2 or later");
}
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL");
}
}
else
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
}
}
free(nativeConfigs); _glfw_free(nativeConfigs);
free(usableConfigs); _glfw_free(usableConfigs);
return closest != NULL; return closest != NULL;
} }
@ -227,6 +279,15 @@ static void swapBuffersEGL(_GLFWwindow* window)
return; return;
} }
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
if (!window->wl.visible)
return;
}
#endif
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
} }
@ -253,8 +314,8 @@ static GLFWglproc getProcAddressEGL(const char* procname)
if (window->context.egl.client) if (window->context.egl.client)
{ {
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client, GLFWglproc proc = (GLFWglproc)
procname); _glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
if (proc) if (proc)
return proc; return proc;
} }
@ -264,15 +325,14 @@ static GLFWglproc getProcAddressEGL(const char* procname)
static void destroyContextEGL(_GLFWwindow* window) static void destroyContextEGL(_GLFWwindow* window)
{ {
#if defined(_GLFW_X11)
// NOTE: Do not unload libGL.so.1 while the X11 display is still open, // NOTE: Do not unload libGL.so.1 while the X11 display is still open,
// as it will make XCloseDisplay segfault // as it will make XCloseDisplay segfault
if (window->context.client != GLFW_OPENGL_API) if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
#endif // _GLFW_X11 window->context.client != GLFW_OPENGL_API)
{ {
if (window->context.egl.client) if (window->context.egl.client)
{ {
_glfw_dlclose(window->context.egl.client); _glfwPlatformFreeModule(window->context.egl.client);
window->context.egl.client = NULL; window->context.egl.client = NULL;
} }
} }
@ -300,6 +360,8 @@ static void destroyContextEGL(_GLFWwindow* window)
GLFWbool _glfwInitEGL(void) GLFWbool _glfwInitEGL(void)
{ {
int i; int i;
EGLint* attribs = NULL;
const char* extensions;
const char* sonames[] = const char* sonames[] =
{ {
#if defined(_GLFW_EGL_LIBRARY) #if defined(_GLFW_EGL_LIBRARY)
@ -311,6 +373,8 @@ GLFWbool _glfwInitEGL(void)
"libEGL.dylib", "libEGL.dylib",
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libEGL-1.so", "libEGL-1.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libEGL.so",
#else #else
"libEGL.so.1", "libEGL.so.1",
#endif #endif
@ -322,7 +386,7 @@ GLFWbool _glfwInitEGL(void)
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.egl.handle = _glfw_dlopen(sonames[i]); _glfw.egl.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.egl.handle) if (_glfw.egl.handle)
break; break;
} }
@ -336,37 +400,37 @@ GLFWbool _glfwInitEGL(void)
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0); _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib) _glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = (PFN_eglGetConfigs) _glfw.egl.GetConfigs = (PFN_eglGetConfigs)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay = (PFN_eglGetDisplay) _glfw.egl.GetDisplay = (PFN_eglGetDisplay)
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = (PFN_eglGetError) _glfw.egl.GetError = (PFN_eglGetError)
_glfw_dlsym(_glfw.egl.handle, "eglGetError"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize = (PFN_eglInitialize) _glfw.egl.Initialize = (PFN_eglInitialize)
_glfw_dlsym(_glfw.egl.handle, "eglInitialize"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate = (PFN_eglTerminate) _glfw.egl.Terminate = (PFN_eglTerminate)
_glfw_dlsym(_glfw.egl.handle, "eglTerminate"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI = (PFN_eglBindAPI) _glfw.egl.BindAPI = (PFN_eglBindAPI)
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext = (PFN_eglCreateContext) _glfw.egl.CreateContext = (PFN_eglCreateContext)
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface = (PFN_eglDestroySurface) _glfw.egl.DestroySurface = (PFN_eglDestroySurface)
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext = (PFN_eglDestroyContext) _glfw.egl.DestroyContext = (PFN_eglDestroyContext)
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface) _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent) _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers) _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval = (PFN_eglSwapInterval) _glfw.egl.SwapInterval = (PFN_eglSwapInterval)
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString = (PFN_eglQueryString) _glfw.egl.QueryString = (PFN_eglQueryString)
_glfw_dlsym(_glfw.egl.handle, "eglQueryString"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress) _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib || if (!_glfw.egl.GetConfigAttrib ||
!_glfw.egl.GetConfigs || !_glfw.egl.GetConfigs ||
@ -392,7 +456,51 @@ GLFWbool _glfwInitEGL(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (extensions && eglGetError() == EGL_SUCCESS)
_glfw.egl.EXT_client_extensions = GLFW_TRUE;
if (_glfw.egl.EXT_client_extensions)
{
_glfw.egl.EXT_platform_base =
_glfwStringInExtensionString("EGL_EXT_platform_base", extensions);
_glfw.egl.EXT_platform_x11 =
_glfwStringInExtensionString("EGL_EXT_platform_x11", extensions);
_glfw.egl.EXT_platform_wayland =
_glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions);
_glfw.egl.ANGLE_platform_angle =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions);
_glfw.egl.ANGLE_platform_angle_opengl =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions);
_glfw.egl.ANGLE_platform_angle_d3d =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions);
_glfw.egl.ANGLE_platform_angle_vulkan =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
_glfw.egl.ANGLE_platform_angle_metal =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
}
if (_glfw.egl.EXT_platform_base)
{
_glfw.egl.GetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
eglGetProcAddress("eglGetPlatformDisplayEXT");
_glfw.egl.CreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)
eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
}
_glfw.egl.platform = _glfw.platform.getEGLPlatform(&attribs);
if (_glfw.egl.platform)
{
_glfw.egl.display =
eglGetPlatformDisplayEXT(_glfw.egl.platform,
_glfw.platform.getEGLNativeDisplay(),
attribs);
}
else
_glfw.egl.display = eglGetDisplay(_glfw.platform.getEGLNativeDisplay());
_glfw_free(attribs);
if (_glfw.egl.display == EGL_NO_DISPLAY) if (_glfw.egl.display == EGL_NO_DISPLAY)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
@ -423,6 +531,8 @@ GLFWbool _glfwInitEGL(void)
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses"); extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
_glfw.egl.KHR_context_flush_control = _glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control"); extensionSupportedEGL("EGL_KHR_context_flush_control");
_glfw.egl.EXT_present_opaque =
extensionSupportedEGL("EGL_EXT_present_opaque");
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -439,12 +549,12 @@ void _glfwTerminateEGL(void)
if (_glfw.egl.handle) if (_glfw.egl.handle)
{ {
_glfw_dlclose(_glfw.egl.handle); _glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL; _glfw.egl.handle = NULL;
} }
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -460,6 +570,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
EGLint attribs[40]; EGLint attribs[40];
EGLConfig config; EGLConfig config;
EGLContext share = NULL; EGLContext share = NULL;
EGLNativeWindowType native;
int index = 0; int index = 0;
if (!_glfw.egl.display) if (!_glfw.egl.display)
@ -472,11 +583,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
share = ctxconfig->share->context.egl.handle; share = ctxconfig->share->context.egl.handle;
if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE; return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
{ {
@ -521,13 +628,13 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{ {
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{ {
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR); EGL_NO_RESET_NOTIFICATION_KHR);
} }
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{ {
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_KHR); EGL_LOSE_CONTEXT_ON_RESET_KHR);
} }
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
@ -536,42 +643,42 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.egl.KHR_create_context_no_error) if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
} }
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
} }
if (mask) if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
if (flags) if (flags)
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags); SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags);
} }
else else
{ {
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
} }
if (_glfw.egl.KHR_context_flush_control) if (_glfw.egl.KHR_context_flush_control)
{ {
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{ {
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR); EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
} }
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{ {
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR); EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
} }
} }
setAttrib(EGL_NONE, EGL_NONE); SET_ATTRIB(EGL_NONE, EGL_NONE);
window->context.egl.handle = eglCreateContext(_glfw.egl.display, window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs); config, share, attribs);
@ -585,23 +692,36 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
} }
// Set up attributes for surface creation // Set up attributes for surface creation
index = 0;
if (fbconfig->sRGB)
{ {
int index = 0; if (_glfw.egl.KHR_gl_colorspace)
SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
if (fbconfig->sRGB) }
{
if (_glfw.egl.KHR_gl_colorspace) if (!fbconfig->doublebuffer)
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR); SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
}
if (_glfw.egl.EXT_present_opaque)
setAttrib(EGL_NONE, EGL_NONE); SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
SET_ATTRIB(EGL_NONE, EGL_NONE);
native = _glfw.platform.getEGLNativeWindow(window);
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
// despite reporting EGL_EXT_platform_base
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
{
window->context.egl.surface =
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
}
else
{
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
} }
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display,
config,
_GLFW_EGL_NATIVE_WINDOW,
attribs);
if (window->context.egl.surface == EGL_NO_SURFACE) if (window->context.egl.surface == EGL_NO_SURFACE)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -626,6 +746,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
"libGLES_CM.dll", "libGLES_CM.dll",
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
"libGLESv1_CM.dylib", "libGLESv1_CM.dylib",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv1_CM.so",
#else #else
"libGLESv1_CM.so.1", "libGLESv1_CM.so.1",
"libGLES_CM.so.1", "libGLES_CM.so.1",
@ -643,6 +765,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
"libGLESv2.dylib", "libGLESv2.dylib",
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libGLESv2-2.so", "libGLESv2-2.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv2.so",
#else #else
"libGLESv2.so.2", "libGLESv2.so.2",
#endif #endif
@ -654,7 +778,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_GLFW_OPENGL_LIBRARY, _GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32) #elif defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else #else
"libOpenGL.so.0",
"libGL.so.1", "libGL.so.1",
#endif #endif
NULL NULL
@ -677,7 +804,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0)) if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
continue; continue;
window->context.egl.client = _glfw_dlopen(sonames[i]); window->context.egl.client = _glfwPlatformLoadModule(sonames[i]);
if (window->context.egl.client) if (window->context.egl.client)
break; break;
} }
@ -700,7 +827,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
// Returns the Visual and depth of the chosen EGLConfig // Returns the Visual and depth of the chosen EGLConfig
// //
@ -717,11 +844,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const long vimask = VisualScreenMask | VisualIDMask; const long vimask = VisualScreenMask | VisualIDMask;
if (!chooseEGLConfig(ctxconfig, fbconfig, &native)) if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
return GLFW_FALSE; return GLFW_FALSE;
}
eglGetConfigAttrib(_glfw.egl.display, native, eglGetConfigAttrib(_glfw.egl.display, native,
EGL_NATIVE_VISUAL_ID, &visualID); EGL_NATIVE_VISUAL_ID, &visualID);
@ -761,7 +884,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
if (window->context.client == GLFW_NO_API) if (window->context.source != GLFW_EGL_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT; return EGL_NO_CONTEXT;
@ -775,7 +898,7 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
if (window->context.client == GLFW_NO_API) if (window->context.source != GLFW_EGL_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;

View File

@ -1,215 +0,0 @@
//========================================================================
// GLFW 3.4 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#if defined(_GLFW_USE_EGLPLATFORM_H)
#include <EGL/eglplatform.h>
#elif defined(_GLFW_WIN32)
#define EGLAPIENTRY __stdcall
typedef HDC EGLNativeDisplayType;
typedef HWND EGLNativeWindowType;
#elif defined(_GLFW_COCOA)
#define EGLAPIENTRY
typedef void* EGLNativeDisplayType;
typedef id EGLNativeWindowType;
#elif defined(_GLFW_X11)
#define EGLAPIENTRY
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
#elif defined(_GLFW_WAYLAND)
#define EGLAPIENTRY
typedef struct wl_display* EGLNativeDisplayType;
typedef struct wl_egl_window* EGLNativeWindowType;
#else
#error "No supported EGL platform selected"
#endif
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300a
#define EGL_BAD_NATIVE_WINDOW 0x300b
#define EGL_BAD_PARAMETER 0x300c
#define EGL_BAD_SURFACE 0x300d
#define EGL_CONTEXT_LOST 0x300e
#define EGL_COLOR_BUFFER_TYPE 0x303f
#define EGL_RGB_BUFFER 0x308e
#define EGL_SURFACE_TYPE 0x3033
#define EGL_WINDOW_BIT 0x0004
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_OPENGL_BIT 0x0008
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
#define EGL_GREEN_SIZE 0x3023
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SAMPLES 0x3031
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
#define EGL_CONTEXT_FLAGS_KHR 0x30fc
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_GL_COLORSPACE_KHR 0x309d
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);
typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
#define eglGetDisplay _glfw.egl.GetDisplay
#define eglGetError _glfw.egl.GetError
#define eglInitialize _glfw.egl.Initialize
#define eglTerminate _glfw.egl.Terminate
#define eglBindAPI _glfw.egl.BindAPI
#define eglCreateContext _glfw.egl.CreateContext
#define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
#define eglQueryString _glfw.egl.QueryString
#define eglGetProcAddress _glfw.egl.GetProcAddress
#define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
// EGL-specific per-context data
//
typedef struct _GLFWcontextEGL
{
EGLConfig config;
EGLContext handle;
EGLSurface surface;
void* client;
} _GLFWcontextEGL;
// EGL-specific global data
//
typedef struct _GLFWlibraryEGL
{
EGLDisplay display;
EGLint major, minor;
GLFWbool prefix;
GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
void* handle;
PFN_eglGetConfigAttrib GetConfigAttrib;
PFN_eglGetConfigs GetConfigs;
PFN_eglGetDisplay GetDisplay;
PFN_eglGetError GetError;
PFN_eglInitialize Initialize;
PFN_eglTerminate Terminate;
PFN_eglBindAPI BindAPI;
PFN_eglCreateContext CreateContext;
PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString;
PFN_eglGetProcAddress GetProcAddress;
} _GLFWlibraryEGL;
GLFWbool _glfwInitEGL(void);
void _glfwTerminateEGL(void);
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/

30
src/glfw.rc.in Normal file
View 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
}
}

View File

@ -1 +0,0 @@
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")

View File

@ -1,60 +0,0 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2010-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// As glfw_config.h.in, this file is used by CMake to produce the
// glfw_config.h configuration header file. If you are adding a feature
// requiring conditional compilation, this is where to add the macro.
//========================================================================
// As glfw_config.h, this file defines compile-time option macros for a
// specific platform and development environment. If you are using the
// GLFW CMake files, modify glfw_config.h.in instead of this file. If you
// are using your own build system, make this file define the appropriate
// macros in whatever way is suitable.
//========================================================================
// Define this to 1 if building GLFW for X11
#cmakedefine _GLFW_X11
// Define this to 1 if building GLFW for Win32
#cmakedefine _GLFW_WIN32
// Define this to 1 if building GLFW for Cocoa
#cmakedefine _GLFW_COCOA
// Define this to 1 if building GLFW for Wayland
#cmakedefine _GLFW_WAYLAND
// Define this to 1 if building GLFW for 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
#cmakedefine _GLFW_VULKAN_STATIC
// Define this to 1 to force use of high-performance GPU on hybrid systems
#cmakedefine _GLFW_USE_HYBRID_HPG
// Define this to 1 if xkbcommon supports the compose key
#cmakedefine HAVE_XKBCOMMON_COMPOSE_H
// Define this to 1 if the libc supports memfd_create()
#cmakedefine HAVE_MEMFD_CREATE

View File

@ -24,9 +24,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"
#if defined(_GLFW_X11)
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -53,7 +57,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
GLXFBConfig* nativeConfigs; GLXFBConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount; int nativeCount, usableCount;
const char* vendor; const char* vendor;
GLFWbool trustWindowBit = GLFW_TRUE; GLFWbool trustWindowBit = GLFW_TRUE;
@ -71,10 +75,10 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
return GLFW_FALSE; return GLFW_FALSE;
} }
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0; usableCount = 0;
for (i = 0; i < nativeCount; i++) for (int i = 0; i < nativeCount; i++)
{ {
const GLXFBConfig n = nativeConfigs[i]; const GLXFBConfig n = nativeConfigs[i];
_GLFWfbconfig* u = usableConfigs + usableCount; _GLFWfbconfig* u = usableConfigs + usableCount;
@ -90,6 +94,9 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
continue; continue;
} }
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER) != desired->doublebuffer)
continue;
if (desired->transparent) if (desired->transparent)
{ {
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n); XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
@ -117,8 +124,6 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
if (getGLXFBConfigAttrib(n, GLX_STEREO)) if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE; u->stereo = GLFW_TRUE;
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
u->doublebuffer = GLFW_TRUE;
if (_glfw.glx.ARB_multisample) if (_glfw.glx.ARB_multisample)
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES); u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
@ -135,7 +140,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
*result = (GLXFBConfig) closest->handle; *result = (GLXFBConfig) closest->handle;
XFree(nativeConfigs); XFree(nativeConfigs);
free(usableConfigs); _glfw_free(usableConfigs);
return closest != NULL; return closest != NULL;
} }
@ -223,11 +228,12 @@ static GLFWglproc getProcAddressGLX(const char* procname)
else if (_glfw.glx.GetProcAddressARB) else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else else
return _glfw_dlsym(_glfw.glx.handle, procname); {
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
return _glfwPlatformGetModuleSymbol(_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)
@ -252,14 +258,16 @@ static void destroyContextGLX(_GLFWwindow* window)
// //
GLFWbool _glfwInitGLX(void) GLFWbool _glfwInitGLX(void)
{ {
int i;
const char* sonames[] = const char* sonames[] =
{ {
#if defined(_GLFW_GLX_LIBRARY) #if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY, _GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libGL-1.so", "libGL-1.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else #else
"libGLX.so.0",
"libGL.so.1", "libGL.so.1",
"libGL.so", "libGL.so",
#endif #endif
@ -269,9 +277,9 @@ GLFWbool _glfwInitGLX(void)
if (_glfw.glx.handle) if (_glfw.glx.handle)
return GLFW_TRUE; return GLFW_TRUE;
for (i = 0; sonames[i]; i++) for (int i = 0; sonames[i]; i++)
{ {
_glfw.glx.handle = _glfw_dlopen(sonames[i]); _glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.glx.handle) if (_glfw.glx.handle)
break; break;
} }
@ -282,36 +290,32 @@ GLFWbool _glfwInitGLX(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.glx.GetFBConfigs = _glfw.glx.GetFBConfigs = (PFNGLXGETFBCONFIGSPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigs");
_glfw.glx.GetFBConfigAttrib = _glfw.glx.GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigAttrib");
_glfw.glx.GetClientString = _glfw.glx.GetClientString = (PFNGLXGETCLIENTSTRINGPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetClientString");
_glfw.glx.QueryExtension = _glfw.glx.QueryExtension = (PFNGLXQUERYEXTENSIONPROC)
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtension");
_glfw.glx.QueryVersion = _glfw.glx.QueryVersion = (PFNGLXQUERYVERSIONPROC)
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryVersion");
_glfw.glx.DestroyContext = _glfw.glx.DestroyContext = (PFNGLXDESTROYCONTEXTPROC)
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyContext");
_glfw.glx.MakeCurrent = _glfw.glx.MakeCurrent = (PFNGLXMAKECURRENTPROC)
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXMakeCurrent");
_glfw.glx.SwapBuffers = _glfw.glx.SwapBuffers = (PFNGLXSWAPBUFFERSPROC)
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXSwapBuffers");
_glfw.glx.QueryExtensionsString = _glfw.glx.QueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC)
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtensionsString");
_glfw.glx.CreateNewContext = _glfw.glx.CreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateNewContext");
_glfw.glx.CreateWindow = _glfw.glx.CreateWindow = (PFNGLXCREATEWINDOWPROC)
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow");
_glfw.glx.DestroyWindow = _glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC)
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow");
_glfw.glx.GetProcAddress = _glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetVisualFromFBConfig");
_glfw.glx.GetProcAddressARB =
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
_glfw.glx.GetVisualFromFBConfig =
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw.glx.GetFBConfigs || if (!_glfw.glx.GetFBConfigs ||
!_glfw.glx.GetFBConfigAttrib || !_glfw.glx.GetFBConfigAttrib ||
@ -325,8 +329,6 @@ GLFWbool _glfwInitGLX(void)
!_glfw.glx.CreateNewContext || !_glfw.glx.CreateNewContext ||
!_glfw.glx.CreateWindow || !_glfw.glx.CreateWindow ||
!_glfw.glx.DestroyWindow || !_glfw.glx.DestroyWindow ||
!_glfw.glx.GetProcAddress ||
!_glfw.glx.GetProcAddressARB ||
!_glfw.glx.GetVisualFromFBConfig) !_glfw.glx.GetVisualFromFBConfig)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -334,6 +336,12 @@ GLFWbool _glfwInitGLX(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
// NOTE: Unlike GLX 1.3 entry points these are not required to be present
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB");
if (!glXQueryExtension(_glfw.x11.display, if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase, &_glfw.glx.errorBase,
&_glfw.glx.eventBase)) &_glfw.glx.eventBase))
@ -424,16 +432,16 @@ GLFWbool _glfwInitGLX(void)
void _glfwTerminateGLX(void) void _glfwTerminateGLX(void)
{ {
// NOTE: This function must not call any X11 functions, as it is called // NOTE: This function must not call any X11 functions, as it is called
// after XCloseDisplay (see _glfwPlatformTerminate for details) // after XCloseDisplay (see _glfwTerminateX11 for details)
if (_glfw.glx.handle) if (_glfw.glx.handle)
{ {
_glfw_dlclose(_glfw.glx.handle); _glfwPlatformFreeModule(_glfw.glx.handle);
_glfw.glx.handle = NULL; _glfw.glx.handle = NULL;
} }
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -521,13 +529,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{ {
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{ {
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_NO_RESET_NOTIFICATION_ARB); GLX_NO_RESET_NOTIFICATION_ARB);
} }
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{ {
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_LOSE_CONTEXT_ON_RESET_ARB); GLX_LOSE_CONTEXT_ON_RESET_ARB);
} }
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
@ -540,13 +548,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{ {
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{ {
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
} }
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{ {
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
} }
} }
} }
@ -554,7 +562,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.glx.ARB_create_context_no_error) if (_glfw.glx.ARB_create_context_no_error)
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); SET_ATTRIB(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
} }
// NOTE: Only request an explicitly versioned context when necessary, as // NOTE: Only request an explicitly versioned context when necessary, as
@ -562,17 +570,17 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
// highest version supported by the driver // highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
} }
if (mask) if (mask)
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
if (flags) if (flags)
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags); SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags);
setAttrib(None, None); SET_ATTRIB(None, None);
window->context.glx.handle = window->context.glx.handle =
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display, _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
@ -629,7 +637,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
// Returns the Visual and depth of the chosen GLXFBConfig // Returns the Visual and depth of the chosen GLXFBConfig
// //
@ -673,7 +681,13 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return NULL;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL; return NULL;
@ -687,7 +701,13 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None); _GLFW_REQUIRE_INIT_OR_RETURN(None);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return None;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return None; return None;
@ -696,3 +716,5 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return window->context.glx.window; return window->context.glx.window;
} }
#endif // _GLFW_X11

View File

@ -1,181 +0,0 @@
//========================================================================
// GLFW 3.4 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLX_VENDOR 1
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_RGBA_TYPE 0x8014
#define GLX_DOUBLEBUFFER 5
#define GLX_STEREO 6
#define GLX_AUX_BUFFERS 7
#define GLX_RED_SIZE 8
#define GLX_GREEN_SIZE 9
#define GLX_BLUE_SIZE 10
#define GLX_ALPHA_SIZE 11
#define GLX_DEPTH_SIZE 12
#define GLX_STENCIL_SIZE 13
#define GLX_ACCUM_RED_SIZE 14
#define GLX_ACCUM_GREEN_SIZE 15
#define GLX_ACCUM_BLUE_SIZE 16
#define GLX_ACCUM_ALPHA_SIZE 17
#define GLX_SAMPLES 0x186a1
#define GLX_VISUAL_ID 0x800b
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
typedef XID GLXWindow;
typedef XID GLXDrawable;
typedef struct __GLXFBConfig* GLXFBConfig;
typedef struct __GLXcontext* GLXContext;
typedef void (*__GLXextproc)(void);
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);
typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
// libGL.so function pointer typedefs
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
#define glXGetClientString _glfw.glx.GetClientString
#define glXQueryExtension _glfw.glx.QueryExtension
#define glXQueryVersion _glfw.glx.QueryVersion
#define glXDestroyContext _glfw.glx.DestroyContext
#define glXMakeCurrent _glfw.glx.MakeCurrent
#define glXSwapBuffers _glfw.glx.SwapBuffers
#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString
#define glXCreateNewContext _glfw.glx.CreateNewContext
#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
#define glXCreateWindow _glfw.glx.CreateWindow
#define glXDestroyWindow _glfw.glx.DestroyWindow
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
// GLX-specific per-context data
//
typedef struct _GLFWcontextGLX
{
GLXContext handle;
GLXWindow window;
} _GLFWcontextGLX;
// GLX-specific global data
//
typedef struct _GLFWlibraryGLX
{
int major, minor;
int eventBase;
int errorBase;
// dlopen handle for libGL.so.1
void* handle;
// GLX 1.3 functions
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
PFNGLXGETCLIENTSTRINGPROC GetClientString;
PFNGLXQUERYEXTENSIONPROC QueryExtension;
PFNGLXQUERYVERSIONPROC QueryVersion;
PFNGLXDESTROYCONTEXTPROC DestroyContext;
PFNGLXMAKECURRENTPROC MakeCurrent;
PFNGLXSWAPBUFFERSPROC SwapBuffers;
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
PFNGLXCREATEWINDOWPROC CreateWindow;
PFNGLXDESTROYWINDOWPROC DestroyWindow;
// GLX 1.4 and extension functions
PFNGLXGETPROCADDRESSPROC GetProcAddress;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool SGI_swap_control;
GLFWbool EXT_swap_control;
GLFWbool MESA_swap_control;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryGLX;
GLFWbool _glfwInitGLX(void);
void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

View File

@ -24,9 +24,10 @@
// distribution. // distribution.
// //
//======================================================================== //========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h" #include "internal.h"
#include "mappings.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -35,28 +36,55 @@
#include <assert.h> #include <assert.h>
// The global variables below comprise all mutable global data in GLFW // NOTE: The global variables below comprise all mutable global data in GLFW
// // Any other mutable global variable is a bug
// Any other global variable is a bug
// Global state shared between compilation units of GLFW // This contains all mutable state shared between compilation units of GLFW
// //
_GLFWlibrary _glfw = { GLFW_FALSE }; _GLFWlibrary _glfw = { GLFW_FALSE };
// These are outside of _glfw so they can be used before initialization and // These are outside of _glfw so they can be used before initialization and
// after termination // after termination without special handling when _glfw is cleared to zero
// //
static _GLFWerror _glfwMainThreadError; static _GLFWerror _glfwMainThreadError;
static GLFWerrorfun _glfwErrorCallback; static GLFWerrorfun _glfwErrorCallback;
static GLFWallocator _glfwInitAllocator;
static _GLFWinitconfig _glfwInitHints = static _GLFWinitconfig _glfwInitHints =
{ {
GLFW_TRUE, // hat buttons GLFW_TRUE, // hat buttons
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
GLFW_ANY_PLATFORM, // preferred platform
NULL, // vkGetInstanceProcAddr function
{ {
GLFW_TRUE, // macOS menu bar GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir GLFW_TRUE // macOS bundle chdir
} },
{
GLFW_TRUE, // X11 XCB Vulkan surface
},
}; };
// The allocation function used when no custom allocator is set
//
static void* defaultAllocate(size_t size, void* user)
{
return malloc(size);
}
// The deallocation function used when no custom allocator is set
//
static void defaultDeallocate(void* block, void* user)
{
free(block);
}
// The reallocation function used when no custom allocator is set
//
static void* defaultReallocate(void* block, size_t size, void* user)
{
return realloc(block, size);
}
// Terminate the library // Terminate the library
// //
static void terminate(void) static void terminate(void)
@ -75,20 +103,21 @@ static void terminate(void)
{ {
_GLFWmonitor* monitor = _glfw.monitors[i]; _GLFWmonitor* monitor = _glfw.monitors[i];
if (monitor->originalRamp.size) if (monitor->originalRamp.size)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); _glfw.platform.setGammaRamp(monitor, &monitor->originalRamp);
_glfwFreeMonitor(monitor); _glfwFreeMonitor(monitor);
} }
free(_glfw.monitors); _glfw_free(_glfw.monitors);
_glfw.monitors = NULL; _glfw.monitors = NULL;
_glfw.monitorCount = 0; _glfw.monitorCount = 0;
free(_glfw.mappings); _glfw_free(_glfw.mappings);
_glfw.mappings = NULL; _glfw.mappings = NULL;
_glfw.mappingCount = 0; _glfw.mappingCount = 0;
_glfwTerminateVulkan(); _glfwTerminateVulkan();
_glfwPlatformTerminate(); _glfw.platform.terminateJoysticks();
_glfw.platform.terminate();
_glfw.initialized = GLFW_FALSE; _glfw.initialized = GLFW_FALSE;
@ -96,7 +125,7 @@ static void terminate(void)
{ {
_GLFWerror* error = _glfw.errorListHead; _GLFWerror* error = _glfw.errorListHead;
_glfw.errorListHead = error->next; _glfw.errorListHead = error->next;
free(error); _glfw_free(error);
} }
_glfwPlatformDestroyTls(&_glfw.contextSlot); _glfwPlatformDestroyTls(&_glfw.contextSlot);
@ -111,14 +140,108 @@ static void terminate(void)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Encode a Unicode code point to a UTF-8 stream
// Based on cutef8 by Jeff Bezanson (Public Domain)
//
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
{
size_t count = 0;
if (codepoint < 0x80)
s[count++] = (char) codepoint;
else if (codepoint < 0x800)
{
s[count++] = (codepoint >> 6) | 0xc0;
s[count++] = (codepoint & 0x3f) | 0x80;
}
else if (codepoint < 0x10000)
{
s[count++] = (codepoint >> 12) | 0xe0;
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
s[count++] = (codepoint & 0x3f) | 0x80;
}
else if (codepoint < 0x110000)
{
s[count++] = (codepoint >> 18) | 0xf0;
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
s[count++] = (codepoint & 0x3f) | 0x80;
}
return count;
}
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
char** _glfwParseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** paths = NULL;
char* line;
*count = 0;
while ((line = strtok(text, "\r\n")))
{
char* path;
text = NULL;
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
{
line += strlen(prefix);
// TODO: Validate hostname
while (*line != '/')
line++;
}
(*count)++;
path = _glfw_calloc(strlen(line) + 1, 1);
paths = _glfw_realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*path = (char) strtol(digits, NULL, 16);
line += 2;
}
else
*path = *line;
path++;
line++;
}
}
return paths;
}
char* _glfw_strdup(const char* source) char* _glfw_strdup(const char* source)
{ {
const size_t length = strlen(source); const size_t length = strlen(source);
char* result = calloc(length + 1, 1); char* result = _glfw_calloc(length + 1, 1);
strcpy(result, source); strcpy(result, source);
return result; return result;
} }
int _glfw_min(int a, int b)
{
return a < b ? a : b;
}
int _glfw_max(int a, int b)
{
return a > b ? a : b;
}
float _glfw_fminf(float a, float b) float _glfw_fminf(float a, float b)
{ {
if (a != a) if (a != a)
@ -143,6 +266,59 @@ float _glfw_fmaxf(float a, float b)
return b; return b;
} }
void* _glfw_calloc(size_t count, size_t size)
{
if (count && size)
{
void* block;
if (count > SIZE_MAX / size)
{
_glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
return NULL;
}
block = _glfw.allocator.allocate(count * size, _glfw.allocator.user);
if (block)
return memset(block, 0, count * size);
else
{
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
}
else
return NULL;
}
void* _glfw_realloc(void* block, size_t size)
{
if (block && size)
{
void* resized = _glfw.allocator.reallocate(block, size, _glfw.allocator.user);
if (resized)
return resized;
else
{
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
}
else if (block)
{
_glfw_free(block);
return NULL;
}
else
return _glfw_calloc(1, size);
}
void _glfw_free(void* block)
{
if (block)
_glfw.allocator.deallocate(block, _glfw.allocator.user);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////
@ -187,6 +363,14 @@ 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 if (code == GLFW_FEATURE_UNAVAILABLE)
strcpy(description, "The requested feature cannot be implemented for this platform");
else if (code == GLFW_FEATURE_UNIMPLEMENTED)
strcpy(description, "The requested feature has not yet been implemented for this platform");
else if (code == GLFW_PLATFORM_UNAVAILABLE)
strcpy(description, "The requested platform is unavailable");
else else
strcpy(description, "ERROR: UNKNOWN GLFW ERROR"); strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
} }
@ -196,7 +380,7 @@ void _glfwInputError(int code, const char* format, ...)
error = _glfwPlatformGetTls(&_glfw.errorSlot); error = _glfwPlatformGetTls(&_glfw.errorSlot);
if (!error) if (!error)
{ {
error = calloc(1, sizeof(_GLFWerror)); error = _glfw_calloc(1, sizeof(_GLFWerror));
_glfwPlatformSetTls(&_glfw.errorSlot, error); _glfwPlatformSetTls(&_glfw.errorSlot, error);
_glfwPlatformLockMutex(&_glfw.errorLock); _glfwPlatformLockMutex(&_glfw.errorLock);
error->next = _glfw.errorListHead; error->next = _glfw.errorListHead;
@ -227,7 +411,18 @@ GLFWAPI int glfwInit(void)
memset(&_glfw, 0, sizeof(_glfw)); memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints; _glfw.hints.init = _glfwInitHints;
if (!_glfwPlatformInit()) _glfw.allocator = _glfwInitAllocator;
if (!_glfw.allocator.allocate)
{
_glfw.allocator.allocate = defaultAllocate;
_glfw.allocator.reallocate = defaultReallocate;
_glfw.allocator.deallocate = defaultDeallocate;
}
if (!_glfwSelectPlatform(_glfw.hints.init.platformID, &_glfw.platform))
return GLFW_FALSE;
if (!_glfw.platform.init())
{ {
terminate(); terminate();
return GLFW_FALSE; return GLFW_FALSE;
@ -243,24 +438,14 @@ GLFWAPI int glfwInit(void)
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError); _glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
_glfw.initialized = GLFW_TRUE; _glfwInitGamepadMappings();
_glfwPlatformInitTimer();
_glfw.timer.offset = _glfwPlatformGetTimerValue(); _glfw.timer.offset = _glfwPlatformGetTimerValue();
_glfw.initialized = GLFW_TRUE;
glfwDefaultWindowHints(); glfwDefaultWindowHints();
{
int i;
for (i = 0; _glfwDefaultMappings[i]; i++)
{
if (!glfwUpdateGamepadMappings(_glfwDefaultMappings[i]))
{
terminate();
return GLFW_FALSE;
}
}
}
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -279,18 +464,45 @@ GLFWAPI void glfwInitHint(int hint, int value)
case GLFW_JOYSTICK_HAT_BUTTONS: case GLFW_JOYSTICK_HAT_BUTTONS:
_glfwInitHints.hatButtons = value; _glfwInitHints.hatButtons = value;
return; return;
case GLFW_ANGLE_PLATFORM_TYPE:
_glfwInitHints.angleType = value;
return;
case GLFW_PLATFORM:
_glfwInitHints.platformID = value;
return;
case GLFW_COCOA_CHDIR_RESOURCES: case GLFW_COCOA_CHDIR_RESOURCES:
_glfwInitHints.ns.chdir = value; _glfwInitHints.ns.chdir = value;
return; return;
case GLFW_COCOA_MENUBAR: case GLFW_COCOA_MENUBAR:
_glfwInitHints.ns.menubar = value; _glfwInitHints.ns.menubar = value;
return; return;
case GLFW_X11_XCB_VULKAN_SURFACE:
_glfwInitHints.x11.xcbVulkanSurface = value;
return;
} }
_glfwInputError(GLFW_INVALID_ENUM, _glfwInputError(GLFW_INVALID_ENUM,
"Invalid init hint 0x%08X", hint); "Invalid init hint 0x%08X", hint);
} }
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
{
if (allocator)
{
if (allocator->allocate && allocator->reallocate && allocator->deallocate)
_glfwInitAllocator = *allocator;
else
_glfwInputError(GLFW_INVALID_VALUE, "Missing function in allocator");
}
else
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
}
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
{
_glfwInitHints.vulkanLoader = loader;
}
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{ {
if (major != NULL) if (major != NULL)
@ -301,11 +513,6 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
*rev = GLFW_VERSION_REVISION; *rev = GLFW_VERSION_REVISION;
} }
GLFWAPI const char* glfwGetVersionString(void)
{
return _glfwPlatformGetVersionString();
}
GLFWAPI int glfwGetError(const char** description) GLFWAPI int glfwGetError(const char** description)
{ {
_GLFWerror* error; _GLFWerror* error;
@ -332,7 +539,7 @@ GLFWAPI int glfwGetError(const char** description)
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
{ {
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); _GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun);
return cbfun; return cbfun;
} }

View File

@ -24,8 +24,11 @@
// distribution. // distribution.
// //
//======================================================================== //========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h" #include "internal.h"
#include "mappings.h"
#include <assert.h> #include <assert.h>
#include <float.h> #include <float.h>
@ -41,6 +44,29 @@
#define _GLFW_JOYSTICK_BUTTON 2 #define _GLFW_JOYSTICK_BUTTON 2
#define _GLFW_JOYSTICK_HATBIT 3 #define _GLFW_JOYSTICK_HATBIT 3
#define GLFW_MOD_MASK (GLFW_MOD_SHIFT | \
GLFW_MOD_CONTROL | \
GLFW_MOD_ALT | \
GLFW_MOD_SUPER | \
GLFW_MOD_CAPS_LOCK | \
GLFW_MOD_NUM_LOCK)
// Initializes the platform joystick API if it has not been already
//
static GLFWbool initJoysticks(void)
{
if (!_glfw.joysticksInitialized)
{
if (!_glfw.platform.initJoysticks())
{
_glfw.platform.terminateJoysticks();
return GLFW_FALSE;
}
}
return _glfw.joysticksInitialized = GLFW_TRUE;
}
// Finds a mapping based on joystick GUID // Finds a mapping based on joystick GUID
// //
static _GLFWmapping* findMapping(const char* guid) static _GLFWmapping* findMapping(const char* guid)
@ -83,25 +109,13 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
{ {
if (!isValidElementForJoystick(mapping->buttons + i, js)) if (!isValidElementForJoystick(mapping->buttons + i, js))
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid button in gamepad mapping %s (%s)",
mapping->guid,
mapping->name);
return NULL; return NULL;
}
} }
for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++) for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
{ {
if (!isValidElementForJoystick(mapping->axes + i, js)) if (!isValidElementForJoystick(mapping->axes + i, js))
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid axis in gamepad mapping %s (%s)",
mapping->guid,
mapping->name);
return NULL; return NULL;
}
} }
} }
@ -227,8 +241,9 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
} }
else else
{ {
length = strlen(_GLFW_PLATFORM_MAPPING_NAME); const char* name = _glfw.platform.getMappingName();
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0) length = strlen(name);
if (strncmp(c, name, length) != 0)
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -245,7 +260,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
mapping->guid[i] += 'a' - 'A'; mapping->guid[i] += 'a' - 'A';
} }
_glfwPlatformUpdateGamepadGUID(mapping->guid); _glfw.platform.updateGamepadGUID(mapping->guid);
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -258,6 +273,12 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
// //
void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods) void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
assert(window != NULL);
assert(key >= 0 || key == GLFW_KEY_UNKNOWN);
assert(key <= GLFW_KEY_LAST);
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
assert(mods == (mods & GLFW_MOD_MASK));
if (key >= 0 && key <= GLFW_KEY_LAST) if (key >= 0 && key <= GLFW_KEY_LAST)
{ {
GLFWbool repeated = GLFW_FALSE; GLFWbool repeated = GLFW_FALSE;
@ -287,8 +308,12 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m
// Notifies shared code of a Unicode codepoint input event // Notifies shared code of a Unicode codepoint input event
// The 'plain' parameter determines whether to emit a regular character event // The 'plain' parameter determines whether to emit a regular character event
// //
void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain) void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain)
{ {
assert(window != NULL);
assert(mods == (mods & GLFW_MOD_MASK));
assert(plain == GLFW_TRUE || plain == GLFW_FALSE);
if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
return; return;
@ -309,6 +334,12 @@ void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWb
// //
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
{ {
assert(window != NULL);
assert(xoffset > -FLT_MAX);
assert(xoffset < FLT_MAX);
assert(yoffset > -FLT_MAX);
assert(yoffset < FLT_MAX);
if (window->callbacks.scroll) if (window->callbacks.scroll)
window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
} }
@ -317,6 +348,12 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
// //
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
{ {
assert(window != NULL);
assert(button >= 0);
assert(button <= GLFW_MOUSE_BUTTON_LAST);
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
assert(mods == (mods & GLFW_MOD_MASK));
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
return; return;
@ -337,6 +374,12 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
// //
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{ {
assert(window != NULL);
assert(xpos > -FLT_MAX);
assert(xpos < FLT_MAX);
assert(ypos > -FLT_MAX);
assert(ypos < FLT_MAX);
if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos) if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
return; return;
@ -351,6 +394,9 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
// //
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
{ {
assert(window != NULL);
assert(entered == GLFW_TRUE || entered == GLFW_FALSE);
if (window->callbacks.cursorEnter) if (window->callbacks.cursorEnter)
window->callbacks.cursorEnter((GLFWwindow*) window, entered); window->callbacks.cursorEnter((GLFWwindow*) window, entered);
} }
@ -359,6 +405,10 @@ void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
// //
void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths) void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
{ {
assert(window != NULL);
assert(count > 0);
assert(paths != NULL);
if (window->callbacks.drop) if (window->callbacks.drop)
window->callbacks.drop((GLFWwindow*) window, count, paths); window->callbacks.drop((GLFWwindow*) window, count, paths);
} }
@ -367,16 +417,26 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
// //
void _glfwInputJoystick(_GLFWjoystick* js, int event) void _glfwInputJoystick(_GLFWjoystick* js, int event)
{ {
const int jid = (int) (js - _glfw.joysticks); assert(js != NULL);
assert(event == GLFW_CONNECTED || event == GLFW_DISCONNECTED);
if (event == GLFW_CONNECTED)
js->connected = GLFW_TRUE;
else if (event == GLFW_DISCONNECTED)
js->connected = GLFW_FALSE;
if (_glfw.callbacks.joystick) if (_glfw.callbacks.joystick)
_glfw.callbacks.joystick(jid, event); _glfw.callbacks.joystick((int) (js - _glfw.joysticks), event);
} }
// Notifies shared code of the new value of a joystick axis // Notifies shared code of the new value of a joystick axis
// //
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value) void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
{ {
assert(js != NULL);
assert(axis >= 0);
assert(axis < js->axisCount);
js->axes[axis] = value; js->axes[axis] = value;
} }
@ -384,6 +444,11 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
// //
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value) void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
{ {
assert(js != NULL);
assert(button >= 0);
assert(button < js->buttonCount);
assert(value == GLFW_PRESS || value == GLFW_RELEASE);
js->buttons[button] = value; js->buttons[button] = value;
} }
@ -391,7 +456,18 @@ void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
// //
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value) void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
{ {
const int base = js->buttonCount + hat * 4; int base;
assert(js != NULL);
assert(hat >= 0);
assert(hat < js->hatCount);
// Valid hat values only use the least significant nibble and have at most two bits
// set, which can be considered adjacent plus an arbitrary rotation within the nibble
assert((value & 0xf0) == 0);
assert((value & ((value << 2) | (value >> 2))) == 0);
base = js->buttonCount + hat * 4;
js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE; js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE; js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE;
@ -406,6 +482,21 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Adds the built-in set of gamepad mappings
//
void _glfwInitGamepadMappings(void)
{
size_t i;
const size_t count = sizeof(_glfwDefaultMappings) / sizeof(char*);
_glfw.mappings = _glfw_calloc(count, sizeof(_GLFWmapping));
for (i = 0; i < count; i++)
{
if (parseMapping(&_glfw.mappings[_glfw.mappingCount], _glfwDefaultMappings[i]))
_glfw.mappingCount++;
}
}
// Returns an available joystick object with arrays and name allocated // Returns an available joystick object with arrays and name allocated
// //
_GLFWjoystick* _glfwAllocJoystick(const char* name, _GLFWjoystick* _glfwAllocJoystick(const char* name,
@ -419,7 +510,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (!_glfw.joysticks[jid].present) if (!_glfw.joysticks[jid].allocated)
break; break;
} }
@ -427,15 +518,15 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
js->present = GLFW_TRUE; js->allocated = GLFW_TRUE;
js->name = _glfw_strdup(name); js->axes = _glfw_calloc(axisCount, sizeof(float));
js->axes = calloc(axisCount, sizeof(float)); js->buttons = _glfw_calloc(buttonCount + (size_t) hatCount * 4, 1);
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1); js->hats = _glfw_calloc(hatCount, 1);
js->hats = calloc(hatCount, 1);
js->axisCount = axisCount; js->axisCount = axisCount;
js->buttonCount = buttonCount; js->buttonCount = buttonCount;
js->hatCount = hatCount; js->hatCount = hatCount;
strncpy(js->name, name, sizeof(js->name) - 1);
strncpy(js->guid, guid, sizeof(js->guid) - 1); strncpy(js->guid, guid, sizeof(js->guid) - 1);
js->mapping = findValidMapping(js); js->mapping = findValidMapping(js);
@ -446,10 +537,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
// //
void _glfwFreeJoystick(_GLFWjoystick* js) void _glfwFreeJoystick(_GLFWjoystick* js)
{ {
free(js->name); _glfw_free(js->axes);
free(js->axes); _glfw_free(js->buttons);
free(js->buttons); _glfw_free(js->hats);
free(js->hats);
memset(js, 0, sizeof(_GLFWjoystick)); memset(js, 0, sizeof(_GLFWjoystick));
} }
@ -459,8 +549,8 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
{ {
int width, height; int width, height;
_glfwPlatformGetWindowSize(window, &width, &height); _glfw.platform.getWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfw.platform.setCursorPos(window, width / 2.0, height / 2.0);
} }
@ -500,96 +590,109 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (mode == GLFW_CURSOR) switch (mode)
{ {
if (value != GLFW_CURSOR_NORMAL && case GLFW_CURSOR:
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
{ {
_glfwInputError(GLFW_INVALID_ENUM, if (value != GLFW_CURSOR_NORMAL &&
"Invalid cursor mode 0x%08X", value != GLFW_CURSOR_HIDDEN &&
value); value != GLFW_CURSOR_DISABLED &&
return; value != GLFW_CURSOR_CAPTURED)
}
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
_glfwPlatformSetCursorMode(window, value);
}
else if (mode == GLFW_STICKY_KEYS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyKeys == value)
return;
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{ {
if (window->keys[i] == _GLFW_STICK) _glfwInputError(GLFW_INVALID_ENUM,
window->keys[i] = GLFW_RELEASE; "Invalid cursor mode 0x%08X",
value);
return;
} }
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfw.platform.getCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
_glfw.platform.setCursorMode(window, value);
return;
} }
window->stickyKeys = value; case GLFW_STICKY_KEYS:
}
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyMouseButtons == value)
return;
if (!value)
{ {
int i; value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyKeys == value)
return;
// Release all sticky mouse buttons if (!value)
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{ {
if (window->mouseButtons[i] == _GLFW_STICK) int i;
window->mouseButtons[i] = GLFW_RELEASE;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
} }
window->stickyKeys = value;
return;
} }
window->stickyMouseButtons = value; case GLFW_STICKY_MOUSE_BUTTONS:
}
else if (mode == GLFW_LOCK_KEY_MODS)
{
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
}
else if (mode == GLFW_RAW_MOUSE_MOTION)
{
if (!_glfwPlatformRawMouseMotionSupported())
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, value = value ? GLFW_TRUE : GLFW_FALSE;
"Raw mouse motion is not supported on this system"); if (window->stickyMouseButtons == value)
return;
if (!value)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value;
return; return;
} }
value = value ? GLFW_TRUE : GLFW_FALSE; case GLFW_LOCK_KEY_MODS:
if (window->rawMouseMotion == value) {
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
}
window->rawMouseMotion = value; case GLFW_RAW_MOUSE_MOTION:
_glfwPlatformSetRawMouseMotion(window, value); {
if (!_glfw.platform.rawMouseMotionSupported())
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Raw mouse motion is not supported on this system");
return;
}
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->rawMouseMotion == value)
return;
window->rawMouseMotion = value;
_glfw.platform.setRawMouseMotion(window, value);
return;
}
} }
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
} }
GLFWAPI int glfwRawMouseMotionSupported(void) GLFWAPI int glfwRawMouseMotionSupported(void)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfwPlatformRawMouseMotionSupported(); return _glfw.platform.rawMouseMotionSupported();
} }
GLFWAPI const char* glfwGetKeyName(int key, int scancode) GLFWAPI const char* glfwGetKeyName(int key, int scancode)
@ -605,10 +708,10 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
return NULL; return NULL;
} }
scancode = _glfwPlatformGetKeyScancode(key); scancode = _glfw.platform.getKeyScancode(key);
} }
return _glfwPlatformGetScancodeName(scancode); return _glfw.platform.getScancodeName(scancode);
} }
GLFWAPI int glfwGetKeyScancode(int key) GLFWAPI int glfwGetKeyScancode(int key)
@ -621,7 +724,7 @@ GLFWAPI int glfwGetKeyScancode(int key)
return GLFW_RELEASE; return GLFW_RELEASE;
} }
return _glfwPlatformGetKeyScancode(key); return _glfw.platform.getKeyScancode(key);
} }
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
@ -690,7 +793,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
*ypos = window->virtualCursorPosY; *ypos = window->virtualCursorPosY;
} }
else else
_glfwPlatformGetCursorPos(window, xpos, ypos); _glfw.platform.getCursorPos(window, xpos, ypos);
} }
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
@ -709,7 +812,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
return; return;
} }
if (!_glfwPlatformWindowFocused(window)) if (!_glfw.platform.windowFocused(window))
return; return;
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
@ -721,7 +824,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
else else
{ {
// Update system cursor position // Update system cursor position
_glfwPlatformSetCursorPos(window, xpos, ypos); _glfw.platform.setCursorPos(window, xpos, ypos);
} }
} }
@ -730,14 +833,21 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
_GLFWcursor* cursor; _GLFWcursor* cursor;
assert(image != NULL); assert(image != NULL);
assert(image->pixels != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
cursor = calloc(1, sizeof(_GLFWcursor)); if (image->width <= 0 || image->height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image dimensions for cursor");
return NULL;
}
cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
cursor->next = _glfw.cursorListHead; cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor; _glfw.cursorListHead = cursor;
if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot)) if (!_glfw.platform.createCursor(cursor, image, xhot, yhot))
{ {
glfwDestroyCursor((GLFWcursor*) cursor); glfwDestroyCursor((GLFWcursor*) cursor);
return NULL; return NULL;
@ -755,19 +865,23 @@ 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;
} }
cursor = calloc(1, sizeof(_GLFWcursor)); cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
cursor->next = _glfw.cursorListHead; cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor; _glfw.cursorListHead = cursor;
if (!_glfwPlatformCreateStandardCursor(cursor, shape)) if (!_glfw.platform.createStandardCursor(cursor, shape))
{ {
glfwDestroyCursor((GLFWcursor*) cursor); glfwDestroyCursor((GLFWcursor*) cursor);
return NULL; return NULL;
@ -796,7 +910,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
} }
} }
_glfwPlatformDestroyCursor(cursor); _glfw.platform.destroyCursor(cursor);
// Unlink cursor from global linked list // Unlink cursor from global linked list
{ {
@ -808,7 +922,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
*prev = cursor->next; *prev = cursor->next;
} }
free(cursor); _glfw_free(cursor);
} }
GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
@ -821,7 +935,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
window->cursor = cursor; window->cursor = cursor;
_glfwPlatformSetCursor(window, cursor); _glfw.platform.setCursor(window, cursor);
} }
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
@ -830,7 +944,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); _GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun);
return cbfun; return cbfun;
} }
@ -840,7 +954,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); _GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun);
return cbfun; return cbfun;
} }
@ -850,7 +964,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); _GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun);
return cbfun; return cbfun;
} }
@ -861,7 +975,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); _GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun);
return cbfun; return cbfun;
} }
@ -872,7 +986,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); _GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun);
return cbfun; return cbfun;
} }
@ -883,7 +997,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); _GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun);
return cbfun; return cbfun;
} }
@ -894,7 +1008,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); _GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun);
return cbfun; return cbfun;
} }
@ -904,7 +1018,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); _GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun);
return cbfun; return cbfun;
} }
@ -923,11 +1037,14 @@ GLFWAPI int glfwJoystickPresent(int jid)
return GLFW_FALSE; return GLFW_FALSE;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return GLFW_FALSE; return GLFW_FALSE;
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); js = _glfw.joysticks + jid;
if (!js->connected)
return GLFW_FALSE;
return _glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE);
} }
GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count) GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
@ -948,11 +1065,14 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
return NULL; return NULL;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES)) js = _glfw.joysticks + jid;
if (!js->connected)
return NULL;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_AXES))
return NULL; return NULL;
*count = js->axisCount; *count = js->axisCount;
@ -977,11 +1097,14 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
return NULL; return NULL;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) js = _glfw.joysticks + jid;
if (!js->connected)
return NULL;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_BUTTONS))
return NULL; return NULL;
if (_glfw.hints.init.hatButtons) if (_glfw.hints.init.hatButtons)
@ -1010,11 +1133,14 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
return NULL; return NULL;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) js = _glfw.joysticks + jid;
if (!js->connected)
return NULL;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_BUTTONS))
return NULL; return NULL;
*count = js->hatCount; *count = js->hatCount;
@ -1036,11 +1162,14 @@ GLFWAPI const char* glfwGetJoystickName(int jid)
return NULL; return NULL;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) js = _glfw.joysticks + jid;
if (!js->connected)
return NULL;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return NULL; return NULL;
return js->name; return js->name;
@ -1061,11 +1190,14 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
return NULL; return NULL;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) js = _glfw.joysticks + jid;
if (!js->connected)
return NULL;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return NULL; return NULL;
return js->guid; return js->guid;
@ -1081,7 +1213,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->allocated)
return; return;
js->userPointer = pointer; js->userPointer = pointer;
@ -1097,7 +1229,7 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->allocated)
return NULL; return NULL;
return js->userPointer; return js->userPointer;
@ -1106,7 +1238,11 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid)
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun) GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
if (!initJoysticks())
return NULL;
_GLFW_SWAP(GLFWjoystickfun, _glfw.callbacks.joystick, cbfun);
return cbfun; return cbfun;
} }
@ -1144,8 +1280,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
{ {
_glfw.mappingCount++; _glfw.mappingCount++;
_glfw.mappings = _glfw.mappings =
realloc(_glfw.mappings, _glfw_realloc(_glfw.mappings,
sizeof(_GLFWmapping) * _glfw.mappingCount); sizeof(_GLFWmapping) * _glfw.mappingCount);
_glfw.mappings[_glfw.mappingCount - 1] = mapping; _glfw.mappings[_glfw.mappingCount - 1] = mapping;
} }
} }
@ -1163,7 +1299,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
js->mapping = findValidMapping(js); js->mapping = findValidMapping(js);
} }
@ -1185,11 +1321,14 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
return GLFW_FALSE; return GLFW_FALSE;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) js = _glfw.joysticks + jid;
if (!js->connected)
return GLFW_FALSE;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return GLFW_FALSE; return GLFW_FALSE;
return js->mapping != NULL; return js->mapping != NULL;
@ -1210,11 +1349,14 @@ GLFWAPI const char* glfwGetGamepadName(int jid)
return NULL; return NULL;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) js = _glfw.joysticks + jid;
if (!js->connected)
return NULL;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return NULL; return NULL;
if (!js->mapping) if (!js->mapping)
@ -1242,11 +1384,14 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
return GLFW_FALSE; return GLFW_FALSE;
} }
js = _glfw.joysticks + jid; if (!initJoysticks())
if (!js->present)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL)) js = _glfw.joysticks + jid;
if (!js->connected)
return GLFW_FALSE;
if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_ALL))
return GLFW_FALSE; return GLFW_FALSE;
if (!js->mapping) if (!js->mapping)
@ -1311,13 +1456,13 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
assert(string != NULL); assert(string != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetClipboardString(string); _glfw.platform.setClipboardString(string);
} }
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetClipboardString(); return _glfw.platform.getClipboardString();
} }
GLFWAPI double glfwGetTime(void) GLFWAPI double glfwGetTime(void)
@ -1352,3 +1497,4 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void)
_GLFW_REQUIRE_INIT_OR_RETURN(0); _GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformGetTimerFrequency(); return _glfwPlatformGetTimerFrequency();
} }

View File

@ -59,6 +59,7 @@
#define _GLFW_MESSAGE_SIZE 1024 #define _GLFW_MESSAGE_SIZE 1024
typedef int GLFWbool; typedef int GLFWbool;
typedef void (*GLFWproc)(void);
typedef struct _GLFWerror _GLFWerror; typedef struct _GLFWerror _GLFWerror;
typedef struct _GLFWinitconfig _GLFWinitconfig; typedef struct _GLFWinitconfig _GLFWinitconfig;
@ -67,6 +68,7 @@ typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig; typedef struct _GLFWfbconfig _GLFWfbconfig;
typedef struct _GLFWcontext _GLFWcontext; typedef struct _GLFWcontext _GLFWcontext;
typedef struct _GLFWwindow _GLFWwindow; typedef struct _GLFWwindow _GLFWwindow;
typedef struct _GLFWplatform _GLFWplatform;
typedef struct _GLFWlibrary _GLFWlibrary; typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor; typedef struct _GLFWmonitor _GLFWmonitor;
typedef struct _GLFWcursor _GLFWcursor; typedef struct _GLFWcursor _GLFWcursor;
@ -76,16 +78,9 @@ typedef struct _GLFWjoystick _GLFWjoystick;
typedef struct _GLFWtls _GLFWtls; typedef struct _GLFWtls _GLFWtls;
typedef struct _GLFWmutex _GLFWmutex; typedef struct _GLFWmutex _GLFWmutex;
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
typedef void (* _GLFWswapintervalfun)(int);
typedef int (* _GLFWextensionsupportedfun)(const char*);
typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
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 +97,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;
@ -113,6 +108,165 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#if defined(_GLFW_WIN32)
#define EGLAPIENTRY __stdcall
#else
#define EGLAPIENTRY
#endif
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300a
#define EGL_BAD_NATIVE_WINDOW 0x300b
#define EGL_BAD_PARAMETER 0x300c
#define EGL_BAD_SURFACE 0x300d
#define EGL_CONTEXT_LOST 0x300e
#define EGL_COLOR_BUFFER_TYPE 0x303f
#define EGL_RGB_BUFFER 0x308e
#define EGL_SURFACE_TYPE 0x3033
#define EGL_WINDOW_BIT 0x0004
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_OPENGL_BIT 0x0008
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
#define EGL_GREEN_SIZE 0x3023
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SAMPLES 0x3031
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_RENDER_BUFFER 0x3086
#define EGL_SINGLE_BUFFER 0x3085
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
#define EGL_CONTEXT_FLAGS_KHR 0x30fc
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_GL_COLORSPACE_KHR 0x309d
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
#define EGL_PLATFORM_X11_EXT 0x31d5
#define EGL_PLATFORM_WAYLAND_EXT 0x31d8
#define EGL_PRESENT_OPAQUE_EXT 0x31df
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
typedef void* EGLNativeDisplayType;
typedef void* EGLNativeWindowType;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);
typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
#define eglGetDisplay _glfw.egl.GetDisplay
#define eglGetError _glfw.egl.GetError
#define eglInitialize _glfw.egl.Initialize
#define eglTerminate _glfw.egl.Terminate
#define eglBindAPI _glfw.egl.BindAPI
#define eglCreateContext _glfw.egl.CreateContext
#define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
#define eglQueryString _glfw.egl.QueryString
#define eglGetProcAddress _glfw.egl.GetProcAddress
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*);
#define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT
#define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT
#define OSMESA_RGBA 0x1908
#define OSMESA_FORMAT 0x22
#define OSMESA_DEPTH_BITS 0x30
#define OSMESA_STENCIL_BITS 0x31
#define OSMESA_ACCUM_BITS 0x32
#define OSMESA_PROFILE 0x33
#define OSMESA_CORE_PROFILE 0x34
#define OSMESA_COMPAT_PROFILE 0x35
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
typedef void* OSMesaContext;
typedef void (*OSMESAproc)(void);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext);
typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext);
typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int);
typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt
#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs
#define OSMesaDestroyContext _glfw.osmesa.DestroyContext
#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent
#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
#define VK_NULL_HANDLE 0 #define VK_NULL_HANDLE 0
typedef void* VkInstance; typedef void* VkInstance;
@ -128,6 +282,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;
@ -169,36 +324,11 @@ typedef struct VkExtensionProperties
typedef void (APIENTRY * PFN_vkVoidFunction)(void); typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#if defined(_GLFW_VULKAN_STATIC) typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*); typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*); #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#else
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#endif
#if defined(_GLFW_COCOA) #include "platform.h"
#include "cocoa_platform.h"
#elif defined(_GLFW_WIN32)
#include "win32_platform.h"
#elif defined(_GLFW_X11)
#include "x11_platform.h"
#elif defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#elif defined(_GLFW_OSMESA)
#include "null_platform.h"
#else
#error "No supported window creation API selected"
#endif
// Constructs a version number string from the public header macros
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \
GLFW_VERSION_MINOR, \
GLFW_VERSION_REVISION)
// Checks for whether the library has been initialized // Checks for whether the library has been initialized
#define _GLFW_REQUIRE_INIT() \ #define _GLFW_REQUIRE_INIT() \
@ -215,12 +345,12 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
} }
// Swaps the provided pointers // Swaps the provided pointers
#define _GLFW_SWAP_POINTERS(x, y) \ #define _GLFW_SWAP(type, x, y) \
{ \ { \
void* t; \ type t; \
t = x; \ t = x; \
x = y; \ x = y; \
y = t; \ y = t; \
} }
// Per-thread error structure // Per-thread error structure
@ -239,10 +369,16 @@ struct _GLFWerror
struct _GLFWinitconfig struct _GLFWinitconfig
{ {
GLFWbool hatButtons; GLFWbool hatButtons;
int angleType;
int platformID;
PFN_vkGetInstanceProcAddr vulkanLoader;
struct { struct {
GLFWbool menubar; GLFWbool menubar;
GLFWbool chdir; GLFWbool chdir;
} ns; } ns;
struct {
GLFWbool xcbVulkanSurface;
} x11;
}; };
// Window configuration // Window configuration
@ -253,6 +389,8 @@ struct _GLFWinitconfig
// //
struct _GLFWwndconfig struct _GLFWwndconfig
{ {
int xpos;
int ypos;
int width; int width;
int height; int height;
const char* title; const char* title;
@ -265,6 +403,7 @@ struct _GLFWwndconfig
GLFWbool maximized; GLFWbool maximized;
GLFWbool centerCursor; GLFWbool centerCursor;
GLFWbool focusOnShow; GLFWbool focusOnShow;
GLFWbool mousePassthrough;
GLFWbool scaleToMonitor; GLFWbool scaleToMonitor;
struct { struct {
GLFWbool retina; GLFWbool retina;
@ -274,6 +413,12 @@ struct _GLFWwndconfig
char className[256]; char className[256];
char instanceName[256]; char instanceName[256];
} x11; } x11;
struct {
GLFWbool keymenu;
} win32;
struct {
char appId[256];
} wl;
}; };
// Context configuration // Context configuration
@ -341,23 +486,33 @@ struct _GLFWcontext
int robustness; int robustness;
int release; int release;
PFNGLGETSTRINGIPROC GetStringi; PFNGLGETSTRINGIPROC GetStringi;
PFNGLGETINTEGERVPROC GetIntegerv; PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString; PFNGLGETSTRINGPROC GetString;
_GLFWmakecontextcurrentfun makeCurrent; void (*makeCurrent)(_GLFWwindow*);
_GLFWswapbuffersfun swapBuffers; void (*swapBuffers)(_GLFWwindow*);
_GLFWswapintervalfun swapInterval; void (*swapInterval)(int);
_GLFWextensionsupportedfun extensionSupported; int (*extensionSupported)(const char*);
_GLFWgetprocaddressfun getProcAddress; GLFWglproc (*getProcAddress)(const char*);
_GLFWdestroycontextfun destroy; void (*destroy)(_GLFWwindow*);
// This is defined in the context API's context.h struct {
_GLFW_PLATFORM_CONTEXT_STATE; EGLConfig config;
// This is defined in egl_context.h EGLContext handle;
_GLFW_EGL_CONTEXT_STATE; EGLSurface surface;
// This is defined in osmesa_context.h void* client;
_GLFW_OSMESA_CONTEXT_STATE; } egl;
struct {
OSMesaContext handle;
int width;
int height;
void* buffer;
} osmesa;
// This is defined in platform.h
GLFW_PLATFORM_CONTEXT_STATE
}; };
// Window and context structure // Window and context structure
@ -372,8 +527,10 @@ struct _GLFWwindow
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
GLFWbool focusOnShow; GLFWbool focusOnShow;
GLFWbool mousePassthrough;
GLFWbool shouldClose; GLFWbool shouldClose;
void* userPointer; void* userPointer;
GLFWbool doublebuffer;
GLFWvidmode videoMode; GLFWvidmode videoMode;
_GLFWmonitor* monitor; _GLFWmonitor* monitor;
_GLFWcursor* cursor; _GLFWcursor* cursor;
@ -395,34 +552,34 @@ struct _GLFWwindow
_GLFWcontext context; _GLFWcontext context;
struct { struct {
GLFWwindowposfun pos; GLFWwindowposfun pos;
GLFWwindowsizefun size; GLFWwindowsizefun size;
GLFWwindowclosefun close; GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh; GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus; GLFWwindowfocusfun focus;
GLFWwindowiconifyfun iconify; GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize; GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize; GLFWframebuffersizefun fbsize;
GLFWwindowcontentscalefun scale; GLFWwindowcontentscalefun scale;
GLFWmousebuttonfun mouseButton; GLFWmousebuttonfun mouseButton;
GLFWcursorposfun cursorPos; GLFWcursorposfun cursorPos;
GLFWcursorenterfun cursorEnter; GLFWcursorenterfun cursorEnter;
GLFWscrollfun scroll; GLFWscrollfun scroll;
GLFWkeyfun key; GLFWkeyfun key;
GLFWcharfun character; GLFWcharfun character;
GLFWcharmodsfun charmods; GLFWcharmodsfun charmods;
GLFWdropfun drop; GLFWdropfun drop;
} callbacks; } callbacks;
// This is defined in the window API's platform.h // This is defined in platform.h
_GLFW_PLATFORM_WINDOW_STATE; GLFW_PLATFORM_WINDOW_STATE
}; };
// Monitor structure // Monitor structure
// //
struct _GLFWmonitor struct _GLFWmonitor
{ {
char* name; char name[128];
void* userPointer; void* userPointer;
// Physical dimensions in millimeters. // Physical dimensions in millimeters.
@ -438,8 +595,8 @@ struct _GLFWmonitor
GLFWgammaramp originalRamp; GLFWgammaramp originalRamp;
GLFWgammaramp currentRamp; GLFWgammaramp currentRamp;
// This is defined in the window API's platform.h // This is defined in platform.h
_GLFW_PLATFORM_MONITOR_STATE; GLFW_PLATFORM_MONITOR_STATE
}; };
// Cursor structure // Cursor structure
@ -447,9 +604,8 @@ struct _GLFWmonitor
struct _GLFWcursor struct _GLFWcursor
{ {
_GLFWcursor* next; _GLFWcursor* next;
// This is defined in platform.h
// This is defined in the window API's platform.h GLFW_PLATFORM_CURSOR_STATE
_GLFW_PLATFORM_CURSOR_STATE;
}; };
// Gamepad mapping element structure // Gamepad mapping element structure
@ -476,36 +632,121 @@ struct _GLFWmapping
// //
struct _GLFWjoystick struct _GLFWjoystick
{ {
GLFWbool present; GLFWbool allocated;
GLFWbool connected;
float* axes; float* axes;
int axisCount; int axisCount;
unsigned char* buttons; unsigned char* buttons;
int buttonCount; int buttonCount;
unsigned char* hats; unsigned char* hats;
int hatCount; int hatCount;
char* name; char name[128];
void* userPointer; void* userPointer;
char guid[33]; char guid[33];
_GLFWmapping* mapping; _GLFWmapping* mapping;
// This is defined in the joystick API's joystick.h // This is defined in platform.h
_GLFW_PLATFORM_JOYSTICK_STATE; GLFW_PLATFORM_JOYSTICK_STATE
}; };
// Thread local storage structure // Thread local storage structure
// //
struct _GLFWtls struct _GLFWtls
{ {
// This is defined in the platform's thread.h // This is defined in platform.h
_GLFW_PLATFORM_TLS_STATE; GLFW_PLATFORM_TLS_STATE
}; };
// Mutex structure // Mutex structure
// //
struct _GLFWmutex struct _GLFWmutex
{ {
// This is defined in the platform's thread.h // This is defined in platform.h
_GLFW_PLATFORM_MUTEX_STATE; GLFW_PLATFORM_MUTEX_STATE
};
// Platform API structure
//
struct _GLFWplatform
{
int platformID;
// init
GLFWbool (*init)(void);
void (*terminate)(void);
// input
void (*getCursorPos)(_GLFWwindow*,double*,double*);
void (*setCursorPos)(_GLFWwindow*,double,double);
void (*setCursorMode)(_GLFWwindow*,int);
void (*setRawMouseMotion)(_GLFWwindow*,GLFWbool);
GLFWbool (*rawMouseMotionSupported)(void);
GLFWbool (*createCursor)(_GLFWcursor*,const GLFWimage*,int,int);
GLFWbool (*createStandardCursor)(_GLFWcursor*,int);
void (*destroyCursor)(_GLFWcursor*);
void (*setCursor)(_GLFWwindow*,_GLFWcursor*);
const char* (*getScancodeName)(int);
int (*getKeyScancode)(int);
void (*setClipboardString)(const char*);
const char* (*getClipboardString)(void);
GLFWbool (*initJoysticks)(void);
void (*terminateJoysticks)(void);
GLFWbool (*pollJoystick)(_GLFWjoystick*,int);
const char* (*getMappingName)(void);
void (*updateGamepadGUID)(char*);
// monitor
void (*freeMonitor)(_GLFWmonitor*);
void (*getMonitorPos)(_GLFWmonitor*,int*,int*);
void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*);
void (*getMonitorWorkarea)(_GLFWmonitor*,int*,int*,int*,int*);
GLFWvidmode* (*getVideoModes)(_GLFWmonitor*,int*);
void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*);
GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*);
void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*);
// window
GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*);
void (*destroyWindow)(_GLFWwindow*);
void (*setWindowTitle)(_GLFWwindow*,const char*);
void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*);
void (*getWindowPos)(_GLFWwindow*,int*,int*);
void (*setWindowPos)(_GLFWwindow*,int,int);
void (*getWindowSize)(_GLFWwindow*,int*,int*);
void (*setWindowSize)(_GLFWwindow*,int,int);
void (*setWindowSizeLimits)(_GLFWwindow*,int,int,int,int);
void (*setWindowAspectRatio)(_GLFWwindow*,int,int);
void (*getFramebufferSize)(_GLFWwindow*,int*,int*);
void (*getWindowFrameSize)(_GLFWwindow*,int*,int*,int*,int*);
void (*getWindowContentScale)(_GLFWwindow*,float*,float*);
void (*iconifyWindow)(_GLFWwindow*);
void (*restoreWindow)(_GLFWwindow*);
void (*maximizeWindow)(_GLFWwindow*);
void (*showWindow)(_GLFWwindow*);
void (*hideWindow)(_GLFWwindow*);
void (*requestWindowAttention)(_GLFWwindow*);
void (*focusWindow)(_GLFWwindow*);
void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int);
GLFWbool (*windowFocused)(_GLFWwindow*);
GLFWbool (*windowIconified)(_GLFWwindow*);
GLFWbool (*windowVisible)(_GLFWwindow*);
GLFWbool (*windowMaximized)(_GLFWwindow*);
GLFWbool (*windowHovered)(_GLFWwindow*);
GLFWbool (*framebufferTransparent)(_GLFWwindow*);
float (*getWindowOpacity)(_GLFWwindow*);
void (*setWindowResizable)(_GLFWwindow*,GLFWbool);
void (*setWindowDecorated)(_GLFWwindow*,GLFWbool);
void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
void (*setWindowOpacity)(_GLFWwindow*,float);
void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
void (*pollEvents)(void);
void (*waitEvents)(void);
void (*waitEventsTimeout)(double);
void (*postEmptyEvent)(void);
// EGL
EGLenum (*getEGLPlatform)(EGLint**);
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
// vulkan
void (*getRequiredInstanceExtensions)(char**);
GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
}; };
// Library global data // Library global data
@ -513,6 +754,9 @@ struct _GLFWmutex
struct _GLFWlibrary struct _GLFWlibrary
{ {
GLFWbool initialized; GLFWbool initialized;
GLFWallocator allocator;
_GLFWplatform platform;
struct { struct {
_GLFWinitconfig init; _GLFWinitconfig init;
@ -529,6 +773,7 @@ struct _GLFWlibrary
_GLFWmonitor** monitors; _GLFWmonitor** monitors;
int monitorCount; int monitorCount;
GLFWbool joysticksInitialized;
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1]; _GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
_GLFWmapping* mappings; _GLFWmapping* mappings;
int mappingCount; int mappingCount;
@ -539,29 +784,80 @@ struct _GLFWlibrary
struct { struct {
uint64_t offset; uint64_t offset;
// This is defined in the platform's time.h // This is defined in platform.h
_GLFW_PLATFORM_LIBRARY_TIMER_STATE; GLFW_PLATFORM_LIBRARY_TIMER_STATE
} timer; } timer;
struct {
EGLenum platform;
EGLDisplay display;
EGLint major, minor;
GLFWbool prefix;
GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
GLFWbool EXT_client_extensions;
GLFWbool EXT_platform_base;
GLFWbool EXT_platform_x11;
GLFWbool EXT_platform_wayland;
GLFWbool EXT_present_opaque;
GLFWbool ANGLE_platform_angle;
GLFWbool ANGLE_platform_angle_opengl;
GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal;
void* handle;
PFN_eglGetConfigAttrib GetConfigAttrib;
PFN_eglGetConfigs GetConfigs;
PFN_eglGetDisplay GetDisplay;
PFN_eglGetError GetError;
PFN_eglInitialize Initialize;
PFN_eglTerminate Terminate;
PFN_eglBindAPI BindAPI;
PFN_eglCreateContext CreateContext;
PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString;
PFN_eglGetProcAddress GetProcAddress;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT;
} egl;
struct {
void* handle;
PFN_OSMesaCreateContextExt CreateContextExt;
PFN_OSMesaCreateContextAttribs CreateContextAttribs;
PFN_OSMesaDestroyContext DestroyContext;
PFN_OSMesaMakeCurrent MakeCurrent;
PFN_OSMesaGetColorBuffer GetColorBuffer;
PFN_OSMesaGetDepthBuffer GetDepthBuffer;
PFN_OSMesaGetProcAddress GetProcAddress;
} osmesa;
struct { struct {
GLFWbool available; GLFWbool available;
void* handle; void* handle;
char* extensions[2]; char* extensions[2];
#if !defined(_GLFW_VULKAN_STATIC)
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
GLFWbool KHR_surface; GLFWbool KHR_surface;
#if defined(_GLFW_WIN32)
GLFWbool KHR_win32_surface; GLFWbool KHR_win32_surface;
#elif defined(_GLFW_COCOA)
GLFWbool MVK_macos_surface; GLFWbool MVK_macos_surface;
#elif defined(_GLFW_X11) GLFWbool EXT_metal_surface;
GLFWbool KHR_xlib_surface; GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface; GLFWbool KHR_xcb_surface;
#elif defined(_GLFW_WAYLAND)
GLFWbool KHR_wayland_surface; GLFWbool KHR_wayland_surface;
#endif
} vk; } vk;
struct { struct {
@ -569,16 +865,10 @@ struct _GLFWlibrary
GLFWjoystickfun joystick; GLFWjoystickfun joystick;
} callbacks; } callbacks;
// This is defined in the window API's platform.h // These are defined in platform.h
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE; GLFW_PLATFORM_LIBRARY_WINDOW_STATE
// This is defined in the context API's context.h GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE; GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
// This is defined in the platform's joystick.h
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
// This is defined in egl_context.h
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
// This is defined in osmesa_context.h
_GLFW_OSMESA_LIBRARY_CONTEXT_STATE;
}; };
// Global state shared between compilation units of GLFW // Global state shared between compilation units of GLFW
@ -590,40 +880,7 @@ extern _GLFWlibrary _glfw;
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void); void _glfwPlatformInitTimer(void);
void _glfwPlatformTerminate(void);
const char* _glfwPlatformGetVersionString(void);
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwPlatformRawMouseMotionSupported(void);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, int xhot, int yhot);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
const char* _glfwPlatformGetScancodeName(int scancode);
int _glfwPlatformGetKeyScancode(int key);
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale);
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPlatformSetClipboardString(const char* string);
const char* _glfwPlatformGetClipboardString(void);
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
uint64_t _glfwPlatformGetTimerValue(void); uint64_t _glfwPlatformGetTimerValue(void);
uint64_t _glfwPlatformGetTimerFrequency(void); uint64_t _glfwPlatformGetTimerFrequency(void);
@ -697,6 +954,10 @@ void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
void _glfwPlatformLockMutex(_GLFWmutex* mutex); void _glfwPlatformLockMutex(_GLFWmutex* mutex);
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex); void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
void* _glfwPlatformLoadModule(const char* path);
void _glfwPlatformFreeModule(void* module);
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////
@ -717,7 +978,7 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
void _glfwInputKey(_GLFWwindow* window, void _glfwInputKey(_GLFWwindow* window,
int key, int scancode, int action, int mods); int key, int scancode, int action, int mods);
void _glfwInputChar(_GLFWwindow* window, void _glfwInputChar(_GLFWwindow* window,
unsigned int codepoint, int mods, GLFWbool plain); uint32_t codepoint, int mods, GLFWbool plain);
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset); void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
@ -743,6 +1004,8 @@ void _glfwInputError(int code, const char* format, ...);
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwSelectPlatform(int platformID, _GLFWplatform* platform);
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions); GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives, const _GLFWfbconfig* alternatives,
@ -760,6 +1023,7 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
void _glfwFreeGammaArrays(GLFWgammaramp* ramp); void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
void _glfwInitGamepadMappings(void);
_GLFWjoystick* _glfwAllocJoystick(const char* name, _GLFWjoystick* _glfwAllocJoystick(const char* name,
const char* guid, const char* guid,
int axisCount, int axisCount,
@ -768,11 +1032,38 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
void _glfwFreeJoystick(_GLFWjoystick* js); void _glfwFreeJoystick(_GLFWjoystick* js);
void _glfwCenterCursorInContentArea(_GLFWwindow* window); void _glfwCenterCursorInContentArea(_GLFWwindow* window);
GLFWbool _glfwInitEGL(void);
void _glfwTerminateEGL(void);
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/
GLFWbool _glfwInitOSMesa(void);
void _glfwTerminateOSMesa(void);
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
GLFWbool _glfwInitVulkan(int mode); GLFWbool _glfwInitVulkan(int mode);
void _glfwTerminateVulkan(void); void _glfwTerminateVulkan(void);
const char* _glfwGetVulkanResultString(VkResult result); const char* _glfwGetVulkanResultString(VkResult result);
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
char** _glfwParseUriList(char* text, int* count);
char* _glfw_strdup(const char* source); char* _glfw_strdup(const char* source);
int _glfw_min(int a, int b);
int _glfw_max(int a, int b);
float _glfw_fminf(float a, float b); float _glfw_fminf(float a, float b);
float _glfw_fmaxf(float a, float b); float _glfw_fmaxf(float a, float b);
void* _glfw_calloc(size_t count, size_t size);
void* _glfw_realloc(void* pointer, size_t size);
void _glfw_free(void* pointer);

View File

@ -24,9 +24,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"
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/inotify.h> #include <sys/inotify.h>
@ -104,9 +108,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,29 +128,24 @@ 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].connected)
continue; continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE; return GLFW_FALSE;
} }
_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 ||
@ -162,15 +159,19 @@ static GLFWbool openJoystickDevice(const char* path)
} }
// Ensure this device supports the events expected of a joystick // Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits)) if (!isBitSet(EV_ABS, evBits))
{ {
close(linjs.fd); close(linjs.fd);
return GLFW_FALSE; return GLFW_FALSE;
} }
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 +190,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 +201,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 +224,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);
@ -243,9 +247,9 @@ static GLFWbool openJoystickDevice(const char* path)
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
_glfwInputJoystick(js, GLFW_DISCONNECTED);
close(js->linjs.fd); close(js->linjs.fd);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// Lexically compare joysticks by name; used by qsort // Lexically compare joysticks by name; used by qsort
@ -262,12 +266,51 @@ static int compareJoysticks(const void* fp, const void* sp)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Initialize joystick interface void _glfwDetectJoystickConnectionLinux(void)
// {
if (_glfw.linjs.inotify <= 0)
return;
ssize_t offset = 0;
char buffer[16384];
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
{
regmatch_t match;
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
offset += sizeof(struct inotify_event) + e->len;
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
if (e->mask & (IN_CREATE | IN_ATTRIB))
openJoystickDevice(path);
else if (e->mask & IN_DELETE)
{
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
{
closeJoystick(_glfw.joysticks + jid);
break;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
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 +332,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;
@ -318,77 +363,26 @@ GLFWbool _glfwInitJoysticksLinux(void)
return GLFW_TRUE; return GLFW_TRUE;
} }
// Close all opened joystick handles
//
void _glfwTerminateJoysticksLinux(void) void _glfwTerminateJoysticksLinux(void)
{ {
int jid; for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
closeJoystick(js); closeJoystick(js);
} }
regfree(&_glfw.linjs.regex);
if (_glfw.linjs.inotify > 0) if (_glfw.linjs.inotify > 0)
{ {
if (_glfw.linjs.watch > 0) if (_glfw.linjs.watch > 0)
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch); inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
close(_glfw.linjs.inotify); close(_glfw.linjs.inotify);
regfree(&_glfw.linjs.regex);
} }
} }
void _glfwDetectJoystickConnectionLinux(void) GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode)
{
ssize_t offset = 0;
char buffer[16384];
if (_glfw.linjs.inotify <= 0)
return;
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
{
regmatch_t match;
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
offset += sizeof(struct inotify_event) + e->len;
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
if (e->mask & (IN_CREATE | IN_ATTRIB))
openJoystickDevice(path);
else if (e->mask & IN_DELETE)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
{
closeJoystick(_glfw.joysticks + jid);
break;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
{ {
// Read all queued events (non-blocking) // Read all queued events (non-blocking)
for (;;) for (;;)
@ -425,10 +419,17 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
handleAbsEvent(js, e.code, e.value); handleAbsEvent(js, e.code, e.value);
} }
return js->present; return js->connected;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameLinux(void)
{
return "Linux";
}
void _glfwUpdateGamepadGUIDLinux(char* guid)
{ {
} }
#endif // GLFW_BUILD_LINUX_JOYSTICK

View File

@ -28,10 +28,8 @@
#include <linux/limits.h> #include <linux/limits.h>
#include <regex.h> #include <regex.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs #define GLFW_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs;
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs #define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
// Linux-specific joystick data // Linux-specific joystick data
// //
@ -55,8 +53,11 @@ typedef struct _GLFWlibraryLinux
GLFWbool dropped; GLFWbool dropped;
} _GLFWlibraryLinux; } _GLFWlibraryLinux;
void _glfwDetectJoystickConnectionLinux(void);
GLFWbool _glfwInitJoysticksLinux(void); GLFWbool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticksLinux(void); void _glfwTerminateJoysticksLinux(void);
void _glfwDetectJoystickConnectionLinux(void); GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameLinux(void);
void _glfwUpdateGamepadGUIDLinux(char* guid);

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad // all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB. // mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
// This file can be re-generated from mappings.h.in and the upstream // This file can be re-generated from mappings.h.in and the upstream
// gamecontrollerdb.txt with the GenerateMappings.cmake script. // gamecontrollerdb.txt with the 'update_mappings' CMake target.
//======================================================================== //========================================================================
// All gamepad mappings not labeled GLFW are copied from the // All gamepad mappings not labeled GLFW are copied from the
@ -60,7 +60,8 @@
const char* _glfwDefaultMappings[] = const char* _glfwDefaultMappings[] =
{ {
@GLFW_GAMEPAD_MAPPINGS@ #if defined(_GLFW_WIN32)
@GLFW_WIN32_MAPPINGS@
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
@ -68,6 +69,14 @@ const char* _glfwDefaultMappings[] =
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", "78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
NULL #endif // _GLFW_WIN32
#if defined(_GLFW_COCOA)
@GLFW_COCOA_MAPPINGS@
#endif // _GLFW_COCOA
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
@GLFW_LINUX_MAPPINGS@
#endif // GLFW_BUILD_LINUX_JOYSTICK
}; };

View File

@ -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;
} }
@ -68,13 +74,13 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
if (monitor->modes) if (monitor->modes)
return GLFW_TRUE; return GLFW_TRUE;
modes = _glfwPlatformGetVideoModes(monitor, &modeCount); modes = _glfw.platform.getVideoModes(monitor, &modeCount);
if (!modes) if (!modes)
return GLFW_FALSE; return GLFW_FALSE;
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
free(monitor->modes); _glfw_free(monitor->modes);
monitor->modes = modes; monitor->modes = modes;
monitor->modeCount = modeCount; monitor->modeCount = modeCount;
@ -90,11 +96,16 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
// //
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement) void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{ {
assert(monitor != NULL);
assert(action == GLFW_CONNECTED || action == GLFW_DISCONNECTED);
assert(placement == _GLFW_INSERT_FIRST || placement == _GLFW_INSERT_LAST);
if (action == GLFW_CONNECTED) if (action == GLFW_CONNECTED)
{ {
_glfw.monitorCount++; _glfw.monitorCount++;
_glfw.monitors = _glfw.monitors =
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount); _glfw_realloc(_glfw.monitors,
sizeof(_GLFWmonitor*) * _glfw.monitorCount);
if (placement == _GLFW_INSERT_FIRST) if (placement == _GLFW_INSERT_FIRST)
{ {
@ -116,10 +127,10 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
if (window->monitor == monitor) if (window->monitor == monitor)
{ {
int width, height, xoff, yoff; int width, height, xoff, yoff;
_glfwPlatformGetWindowSize(window, &width, &height); _glfw.platform.getWindowSize(window, &width, &height);
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0); _glfw.platform.setWindowMonitor(window, NULL, 0, 0, width, height, 0);
_glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL); _glfw.platform.getWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
_glfwPlatformSetWindowPos(window, xoff, yoff); _glfw.platform.setWindowPos(window, xoff, yoff);
} }
} }
@ -148,6 +159,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
// //
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window) void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
{ {
assert(monitor != NULL);
monitor->window = window; monitor->window = window;
} }
@ -160,12 +172,11 @@ void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
// //
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
{ {
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); _GLFWmonitor* monitor = _glfw_calloc(1, sizeof(_GLFWmonitor));
monitor->widthMM = widthMM; monitor->widthMM = widthMM;
monitor->heightMM = heightMM; monitor->heightMM = heightMM;
if (name) strncpy(monitor->name, name, sizeof(monitor->name) - 1);
monitor->name = _glfw_strdup(name);
return monitor; return monitor;
} }
@ -177,23 +188,22 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor)
if (monitor == NULL) if (monitor == NULL)
return; return;
_glfwPlatformFreeMonitor(monitor); _glfw.platform.freeMonitor(monitor);
_glfwFreeGammaArrays(&monitor->originalRamp); _glfwFreeGammaArrays(&monitor->originalRamp);
_glfwFreeGammaArrays(&monitor->currentRamp); _glfwFreeGammaArrays(&monitor->currentRamp);
free(monitor->modes); _glfw_free(monitor->modes);
free(monitor->name); _glfw_free(monitor);
free(monitor);
} }
// Allocates red, green and blue value arrays of the specified size // Allocates red, green and blue value arrays of the specified size
// //
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
{ {
ramp->red = calloc(size, sizeof(unsigned short)); ramp->red = _glfw_calloc(size, sizeof(unsigned short));
ramp->green = calloc(size, sizeof(unsigned short)); ramp->green = _glfw_calloc(size, sizeof(unsigned short));
ramp->blue = calloc(size, sizeof(unsigned short)); ramp->blue = _glfw_calloc(size, sizeof(unsigned short));
ramp->size = size; ramp->size = size;
} }
@ -201,9 +211,9 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
// //
void _glfwFreeGammaArrays(GLFWgammaramp* ramp) void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
{ {
free(ramp->red); _glfw_free(ramp->red);
free(ramp->green); _glfw_free(ramp->green);
free(ramp->blue); _glfw_free(ramp->blue);
memset(ramp, 0, sizeof(GLFWgammaramp)); memset(ramp, 0, sizeof(GLFWgammaramp));
} }
@ -327,7 +337,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorPos(monitor, xpos, ypos); _glfw.platform.getMonitorPos(monitor, xpos, ypos);
} }
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
@ -348,7 +358,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height); _glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height);
} }
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
@ -381,7 +391,7 @@ GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
*yscale = 0.f; *yscale = 0.f;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorContentScale(monitor, xscale, yscale); _glfw.platform.getMonitorContentScale(monitor, xscale, yscale);
} }
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
@ -414,7 +424,7 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); _GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun);
return cbfun; return cbfun;
} }
@ -442,7 +452,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwPlatformGetVideoMode(monitor, &monitor->currentMode); _glfw.platform.getVideoMode(monitor, &monitor->currentMode);
return &monitor->currentMode; return &monitor->currentMode;
} }
@ -468,7 +478,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
if (!original) if (!original)
return; return;
values = calloc(original->size, sizeof(unsigned short)); values = _glfw_calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++) for (i = 0; i < original->size; i++)
{ {
@ -490,7 +500,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
ramp.size = original->size; ramp.size = original->size;
glfwSetGammaRamp(handle, &ramp); glfwSetGammaRamp(handle, &ramp);
free(values); _glfw_free(values);
} }
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
@ -501,7 +511,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp); _glfwFreeGammaArrays(&monitor->currentRamp);
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp)) if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp))
return NULL; return NULL;
return &monitor->currentRamp; return &monitor->currentRamp;
@ -517,6 +527,8 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
assert(ramp->green != NULL); assert(ramp->green != NULL);
assert(ramp->blue != NULL); assert(ramp->blue != NULL);
_GLFW_REQUIRE_INIT();
if (ramp->size <= 0) if (ramp->size <= 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,
@ -525,14 +537,12 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
return; return;
} }
_GLFW_REQUIRE_INIT();
if (!monitor->originalRamp.size) if (!monitor->originalRamp.size)
{ {
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) if (!_glfw.platform.getGammaRamp(monitor, &monitor->originalRamp))
return; return;
} }
_glfwPlatformSetGammaRamp(monitor, ramp); _glfw.platform.setGammaRamp(monitor, ramp);
} }

View File

@ -1,68 +0,0 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
#include <stdatomic.h>
// NSGL-specific per-context data
//
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
CVDisplayLinkRef displayLink;
atomic_int swapInterval;
int swapIntervalsPassed;
id swapIntervalCond;
} _GLFWcontextNSGL;
// NSGL-specific global data
//
typedef struct _GLFWlibraryNSGL
{
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
CFBundleRef framework;
} _GLFWlibraryNSGL;
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);
void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window);

View File

@ -23,32 +23,15 @@
// 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 #if defined(_GLFW_COCOA)
// This is based on a similar workaround added to SDL2
//
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); #include <unistd.h>
if (interval > 0) #include <math.h>
{
[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 +51,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.occluded)
{ {
[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 +81,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 +112,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 +176,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
@ -215,45 +190,45 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but // No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
// are not a hard constraint, so ignore and continue // are not a hard constraint, so ignore and continue
#define addAttrib(a) \ #define ADD_ATTRIB(a) \
{ \ { \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
} }
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); } #define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); }
NSOpenGLPixelFormatAttribute attribs[40]; NSOpenGLPixelFormatAttribute attribs[40];
int index = 0; int index = 0;
addAttrib(NSOpenGLPFAAccelerated); ADD_ATTRIB(NSOpenGLPFAAccelerated);
addAttrib(NSOpenGLPFAClosestPolicy); ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
if (ctxconfig->nsgl.offline) if (ctxconfig->nsgl.offline)
{ {
addAttrib(NSOpenGLPFAAllowOfflineRenderers); ADD_ATTRIB(NSOpenGLPFAAllowOfflineRenderers);
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in // NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
// Info.plist for unbundled applications // Info.plist for unbundled applications
// HACK: This assumes that NSOpenGLPixelFormat will remain // HACK: This assumes that NSOpenGLPixelFormat will remain
// a straightforward wrapper of its CGL counterpart // a straightforward wrapper of its CGL counterpart
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching); ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
} }
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4) if (ctxconfig->major >= 4)
{ {
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
} }
else else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3) if (ctxconfig->major >= 3)
{ {
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
} }
if (ctxconfig->major <= 2) if (ctxconfig->major <= 2)
{ {
if (fbconfig->auxBuffers != GLFW_DONT_CARE) if (fbconfig->auxBuffers != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->accumRedBits != GLFW_DONT_CARE && if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
fbconfig->accumGreenBits != GLFW_DONT_CARE && fbconfig->accumGreenBits != GLFW_DONT_CARE &&
@ -265,7 +240,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
fbconfig->accumBlueBits + fbconfig->accumBlueBits +
fbconfig->accumAlphaBits; fbconfig->accumAlphaBits;
setAttrib(NSOpenGLPFAAccumSize, accumBits); SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
} }
} }
@ -283,17 +258,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
else if (colorBits < 15) else if (colorBits < 15)
colorBits = 15; colorBits = 15;
setAttrib(NSOpenGLPFAColorSize, colorBits); SET_ATTRIB(NSOpenGLPFAColorSize, colorBits);
} }
if (fbconfig->alphaBits != GLFW_DONT_CARE) if (fbconfig->alphaBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits != GLFW_DONT_CARE) if (fbconfig->depthBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits); SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits != GLFW_DONT_CARE) if (fbconfig->stencilBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits); SET_ATTRIB(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
if (fbconfig->stereo) if (fbconfig->stereo)
{ {
@ -302,33 +277,33 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
"NSGL: Stereo rendering is deprecated"); "NSGL: Stereo rendering is deprecated");
return GLFW_FALSE; return GLFW_FALSE;
#else #else
addAttrib(NSOpenGLPFAStereo); ADD_ATTRIB(NSOpenGLPFAStereo);
#endif #endif
} }
if (fbconfig->doublebuffer) if (fbconfig->doublebuffer)
addAttrib(NSOpenGLPFADoubleBuffer); ADD_ATTRIB(NSOpenGLPFADoubleBuffer);
if (fbconfig->samples != GLFW_DONT_CARE) if (fbconfig->samples != GLFW_DONT_CARE)
{ {
if (fbconfig->samples == 0) if (fbconfig->samples == 0)
{ {
setAttrib(NSOpenGLPFASampleBuffers, 0); SET_ATTRIB(NSOpenGLPFASampleBuffers, 0);
} }
else else
{ {
setAttrib(NSOpenGLPFASampleBuffers, 1); SET_ATTRIB(NSOpenGLPFASampleBuffers, 1);
setAttrib(NSOpenGLPFASamples, fbconfig->samples); SET_ATTRIB(NSOpenGLPFASamples, fbconfig->samples);
} }
} }
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it // framebuffer, so there's no need (and no way) to request it
addAttrib(0); ADD_ATTRIB(0);
#undef addAttrib #undef ADD_ATTRIB
#undef setAttrib #undef SET_ATTRIB
window->context.nsgl.pixelFormat = window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
@ -339,7 +314,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 +336,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 +347,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 //////
@ -409,12 +360,21 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil); _GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
"NSGL: Platform not initialized");
return nil;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_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;
} }
#endif // _GLFW_COCOA

View File

@ -24,27 +24,110 @@
// 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 <stdlib.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void) GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
{ {
_glfwInitTimerPOSIX(); const _GLFWplatform null =
{
GLFW_PLATFORM_NULL,
_glfwInitNull,
_glfwTerminateNull,
_glfwGetCursorPosNull,
_glfwSetCursorPosNull,
_glfwSetCursorModeNull,
_glfwSetRawMouseMotionNull,
_glfwRawMouseMotionSupportedNull,
_glfwCreateCursorNull,
_glfwCreateStandardCursorNull,
_glfwDestroyCursorNull,
_glfwSetCursorNull,
_glfwGetScancodeNameNull,
_glfwGetKeyScancodeNull,
_glfwSetClipboardStringNull,
_glfwGetClipboardStringNull,
_glfwInitJoysticksNull,
_glfwTerminateJoysticksNull,
_glfwPollJoystickNull,
_glfwGetMappingNameNull,
_glfwUpdateGamepadGUIDNull,
_glfwFreeMonitorNull,
_glfwGetMonitorPosNull,
_glfwGetMonitorContentScaleNull,
_glfwGetMonitorWorkareaNull,
_glfwGetVideoModesNull,
_glfwGetVideoModeNull,
_glfwGetGammaRampNull,
_glfwSetGammaRampNull,
_glfwCreateWindowNull,
_glfwDestroyWindowNull,
_glfwSetWindowTitleNull,
_glfwSetWindowIconNull,
_glfwGetWindowPosNull,
_glfwSetWindowPosNull,
_glfwGetWindowSizeNull,
_glfwSetWindowSizeNull,
_glfwSetWindowSizeLimitsNull,
_glfwSetWindowAspectRatioNull,
_glfwGetFramebufferSizeNull,
_glfwGetWindowFrameSizeNull,
_glfwGetWindowContentScaleNull,
_glfwIconifyWindowNull,
_glfwRestoreWindowNull,
_glfwMaximizeWindowNull,
_glfwShowWindowNull,
_glfwHideWindowNull,
_glfwRequestWindowAttentionNull,
_glfwFocusWindowNull,
_glfwSetWindowMonitorNull,
_glfwWindowFocusedNull,
_glfwWindowIconifiedNull,
_glfwWindowVisibleNull,
_glfwWindowMaximizedNull,
_glfwWindowHoveredNull,
_glfwFramebufferTransparentNull,
_glfwGetWindowOpacityNull,
_glfwSetWindowResizableNull,
_glfwSetWindowDecoratedNull,
_glfwSetWindowFloatingNull,
_glfwSetWindowOpacityNull,
_glfwSetWindowMousePassthroughNull,
_glfwPollEventsNull,
_glfwWaitEventsNull,
_glfwWaitEventsTimeoutNull,
_glfwPostEmptyEventNull,
_glfwGetEGLPlatformNull,
_glfwGetEGLNativeDisplayNull,
_glfwGetEGLNativeWindowNull,
_glfwGetRequiredInstanceExtensionsNull,
_glfwGetPhysicalDevicePresentationSupportNull,
_glfwCreateWindowSurfaceNull,
};
*platform = null;
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminate(void) int _glfwInitNull(void)
{ {
_glfwPollMonitorsNull();
return GLFW_TRUE;
}
void _glfwTerminateNull(void)
{
free(_glfw.null.clipboardString);
_glfwTerminateOSMesa(); _glfwTerminateOSMesa();
} _glfwTerminateEGL();
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " null OSMesa";
} }

View File

@ -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"
@ -31,12 +33,26 @@
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) GLFWbool _glfwInitJoysticksNull(void)
{
return GLFW_TRUE;
}
void _glfwTerminateJoysticksNull(void)
{
}
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameNull(void)
{
return "";
}
void _glfwUpdateGamepadGUIDNull(char* guid)
{ {
} }

View File

@ -24,8 +24,9 @@
// //
//======================================================================== //========================================================================
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs GLFWbool _glfwInitJoysticksNull(void);
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs void _glfwTerminateJoysticksNull(void);
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode);
#define _GLFW_PLATFORM_MAPPING_NAME "" const char* _glfwGetMappingNameNull(void);
void _glfwUpdateGamepadGUIDNull(char* guid);

View File

@ -24,24 +24,62 @@
// 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 <stdlib.h>
#include <string.h>
#include <math.h>
// The the sole (fake) video mode of our (sole) fake monitor
//
static GLFWvidmode getVideoMode(void)
{
GLFWvidmode mode;
mode.width = 1920;
mode.height = 1080;
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = 60;
return mode;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPollMonitorsNull(void)
{
const float dpi = 141.f;
const GLFWvidmode mode = getVideoMode();
_GLFWmonitor* monitor = _glfwAllocMonitor("Null SuperNoop 0",
(int) (mode.width * 25.4f / dpi),
(int) (mode.height * 25.4f / dpi));
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorNull(_GLFWmonitor* monitor)
{ {
_glfwFreeGammaArrays(&monitor->null.ramp);
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = 1.f; *xscale = 1.f;
@ -49,27 +87,75 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = 1.f; *yscale = 1.f;
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
const GLFWvidmode mode = getVideoMode();
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 10;
if (width)
*width = mode.width;
if (height)
*height = mode.height - 10;
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found)
{ {
return NULL; GLFWvidmode* mode = _glfw_calloc(1, sizeof(GLFWvidmode));
*mode = getVideoMode();
*found = 1;
return mode;
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
*mode = getVideoMode();
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
return GLFW_FALSE; if (!monitor->null.ramp.size)
{
unsigned int i;
_glfwAllocGammaArrays(&monitor->null.ramp, 256);
for (i = 0; i < monitor->null.ramp.size; i++)
{
const float gamma = 2.2f;
float value;
value = i / (float) (monitor->null.ramp.size - 1);
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
value = _glfw_fminf(value, 65535.f);
monitor->null.ramp.red[i] = (unsigned short) value;
monitor->null.ramp.green[i] = (unsigned short) value;
monitor->null.ramp.blue[i] = (unsigned short) value;
}
}
_glfwAllocGammaArrays(ramp, monitor->null.ramp.size);
memcpy(ramp->red, monitor->null.ramp.red, sizeof(short) * ramp->size);
memcpy(ramp->green, monitor->null.ramp.green, sizeof(short) * ramp->size);
memcpy(ramp->blue, monitor->null.ramp.blue, sizeof(short) * ramp->size);
return GLFW_TRUE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
if (monitor->null.ramp.size != ramp->size)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Null: Gamma ramp size must match current ramp size");
return;
}
memcpy(monitor->null.ramp.red, ramp->red, sizeof(short) * ramp->size);
memcpy(monitor->null.ramp.green, ramp->green, sizeof(short) * ramp->size);
memcpy(monitor->null.ramp.blue, ramp->blue, sizeof(short) * ramp->size);
} }

View File

@ -25,38 +25,125 @@
// //
//======================================================================== //========================================================================
#include <dlfcn.h> #define GLFW_NULL_WINDOW_STATE _GLFWwindowNull null;
#define GLFW_NULL_LIBRARY_WINDOW_STATE _GLFWlibraryNull null;
#define GLFW_NULL_MONITOR_STATE _GLFWmonitorNull null;
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null #define GLFW_NULL_CONTEXT_STATE
#define GLFW_NULL_CURSOR_STATE
#define GLFW_NULL_LIBRARY_CONTEXT_STATE
#define _GLFW_PLATFORM_CONTEXT_STATE
#define _GLFW_PLATFORM_MONITOR_STATE
#define _GLFW_PLATFORM_CURSOR_STATE
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
#define _GLFW_EGL_CONTEXT_STATE
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
#include "osmesa_context.h"
#include "posix_time.h"
#include "posix_thread.h"
#include "null_joystick.h"
#if defined(_GLFW_WIN32)
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#else
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#endif
// Null-specific per-window data // Null-specific per-window data
// //
typedef struct _GLFWwindowNull typedef struct _GLFWwindowNull
{ {
int width; int xpos;
int height; int ypos;
int width;
int height;
char* title;
GLFWbool visible;
GLFWbool iconified;
GLFWbool maximized;
GLFWbool resizable;
GLFWbool decorated;
GLFWbool floating;
GLFWbool transparent;
float opacity;
} _GLFWwindowNull; } _GLFWwindowNull;
// Null-specific per-monitor data
//
typedef struct _GLFWmonitorNull
{
GLFWgammaramp ramp;
} _GLFWmonitorNull;
// Null-specific global data
//
typedef struct _GLFWlibraryNull
{
int xcursor;
int ycursor;
char* clipboardString;
_GLFWwindow* focusedWindow;
} _GLFWlibraryNull;
void _glfwPollMonitorsNull(void);
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform);
int _glfwInitNull(void);
void _glfwTerminateNull(void);
void _glfwFreeMonitorNull(_GLFWmonitor* monitor);
void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found);
void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowNull(_GLFWwindow* window);
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d);
void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeNull(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowNull(_GLFWwindow* window);
void _glfwRestoreWindowNull(_GLFWwindow* window);
void _glfwMaximizeWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window);
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityNull(_GLFWwindow* window);
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity);
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedNull(void);
void _glfwShowWindowNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwHideWindowNull(_GLFWwindow* window);
void _glfwFocusWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window);
void _glfwPollEventsNull(void);
void _glfwWaitEventsNull(void);
void _glfwWaitEventsTimeoutNull(double timeout);
void _glfwPostEmptyEventNull(void);
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y);
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode);
GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorNull(_GLFWcursor* cursor);
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringNull(const char* string);
const char* _glfwGetClipboardStringNull(void);
const char* _glfwGetScancodeNameNull(int scancode);
int _glfwGetKeyScancodeNull(int key);
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsNull(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwPollMonitorsNull(void);

View File

@ -24,15 +24,85 @@
// 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 <stdlib.h>
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
{
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
{
const float ratio = (float) window->numer / (float) window->denom;
*height = (int) (*width / ratio);
}
if (window->minwidth != GLFW_DONT_CARE)
*width = _glfw_max(*width, window->minwidth);
else if (window->maxwidth != GLFW_DONT_CARE)
*width = _glfw_min(*width, window->maxwidth);
if (window->minheight != GLFW_DONT_CARE)
*height = _glfw_min(*height, window->minheight);
else if (window->maxheight != GLFW_DONT_CARE)
*height = _glfw_max(*height, window->maxheight);
}
static void fitToMonitor(_GLFWwindow* window)
{
GLFWvidmode mode;
_glfwGetVideoModeNull(window->monitor, &mode);
_glfwGetMonitorPosNull(window->monitor,
&window->null.xpos,
&window->null.ypos);
window->null.width = mode.width;
window->null.height = mode.height;
}
static void acquireMonitor(_GLFWwindow* window)
{
_glfwInputMonitorWindow(window->monitor, window);
}
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
_glfwInputMonitorWindow(window->monitor, NULL);
}
static int createNativeWindow(_GLFWwindow* window, static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig) const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{ {
window->null.width = wndconfig->width; if (window->monitor)
window->null.height = wndconfig->height; fitToMonitor(window);
else
{
if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION)
{
window->null.xpos = 17;
window->null.ypos = 17;
}
else
{
window->null.xpos = wndconfig->xpos;
window->null.ypos = wndconfig->ypos;
}
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
}
window->null.visible = wndconfig->visible;
window->null.decorated = wndconfig->decorated;
window->null.maximized = wndconfig->maximized;
window->null.floating = wndconfig->floating;
window->null.transparent = fbconfig->transparent;
window->null.opacity = 1.f;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -42,12 +112,12 @@ static int createNativeWindow(_GLFWwindow* window,
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window, GLFWbool _glfwCreateWindowNull(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig, const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
if (!createNativeWindow(window, wndconfig)) if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API) if (ctxconfig->client != GLFW_NO_API)
@ -60,48 +130,120 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
else else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available"); if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE; return GLFW_FALSE;
}
if (wndconfig->mousePassthrough)
_glfwSetWindowMousePassthroughNull(window, GLFW_TRUE);
if (window->monitor)
{
_glfwShowWindowNull(window);
_glfwFocusWindowNull(window);
acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwShowWindowNull(window);
if (wndconfig->focused)
_glfwFocusWindowNull(window);
} }
} }
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwDestroyWindowNull(_GLFWwindow* window)
{ {
if (window->monitor)
releaseMonitor(window);
if (_glfw.null.focusedWindow == window)
_glfw.null.focusedWindow = NULL;
if (window->context.destroy) if (window->context.destroy)
window->context.destroy(window); window->context.destroy(window);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title)
{ {
} }
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images)
const GLFWimage* images)
{ {
} }
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, void _glfwSetWindowMonitorNull(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,
int width, int height, int width, int height,
int refreshRate) int refreshRate)
{ {
if (window->monitor == monitor)
{
if (!monitor)
{
_glfwSetWindowPosNull(window, xpos, ypos);
_glfwSetWindowSizeNull(window, width, height);
}
return;
}
if (window->monitor)
releaseMonitor(window);
_glfwInputWindowMonitor(window, monitor);
if (window->monitor)
{
window->null.visible = GLFW_TRUE;
acquireMonitor(window);
fitToMonitor(window);
}
else
{
_glfwSetWindowPosNull(window, xpos, ypos);
_glfwSetWindowSizeNull(window, width, height);
}
} }
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos)
{ {
if (xpos)
*xpos = window->null.xpos;
if (ypos)
*ypos = window->null.ypos;
} }
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos)
{ {
if (window->monitor)
return;
if (window->null.xpos != xpos || window->null.ypos != ypos)
{
window->null.xpos = xpos;
window->null.ypos = ypos;
_glfwInputWindowPos(window, xpos, ypos);
}
} }
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height)
{ {
if (width) if (width)
*width = window->null.width; *width = window->null.width;
@ -109,23 +251,39 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
*height = window->null.height; *height = window->null.height;
} }
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height)
{ {
window->null.width = width; if (window->monitor)
window->null.height = height; return;
if (window->null.width != width || window->null.height != height)
{
window->null.width = width;
window->null.height = height;
_glfwInputWindowSize(window, width, height);
_glfwInputFramebufferSize(window, width, height);
}
} }
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window,
int minwidth, int minheight, int minwidth, int minheight,
int maxwidth, int maxheight) int maxwidth, int maxheight)
{ {
int width = window->null.width;
int height = window->null.height;
applySizeLimits(window, &width, &height);
_glfwSetWindowSizeNull(window, width, height);
} }
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d) void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d)
{ {
int width = window->null.width;
int height = window->null.height;
applySizeLimits(window, &width, &height);
_glfwSetWindowSizeNull(window, width, height);
} }
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height)
{ {
if (width) if (width)
*width = window->null.width; *width = window->null.width;
@ -133,14 +291,35 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
*height = window->null.height; *height = window->null.height;
} }
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwGetWindowFrameSizeNull(_GLFWwindow* window,
int* left, int* top, int* left, int* top,
int* right, int* bottom) int* right, int* bottom)
{ {
if (window->null.decorated && !window->monitor)
{
if (left)
*left = 1;
if (top)
*top = 10;
if (right)
*right = 1;
if (bottom)
*bottom = 1;
}
else
{
if (left)
*left = 0;
if (top)
*top = 0;
if (right)
*right = 0;
if (bottom)
*bottom = 0;
}
} }
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale)
float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = 1.f; *xscale = 1.f;
@ -148,82 +327,147 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = 1.f; *yscale = 1.f;
} }
void _glfwPlatformIconifyWindow(_GLFWwindow* window) void _glfwIconifyWindowNull(_GLFWwindow* window)
{
if (_glfw.null.focusedWindow == window)
{
_glfw.null.focusedWindow = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE);
}
if (!window->null.iconified)
{
window->null.iconified = GLFW_TRUE;
_glfwInputWindowIconify(window, GLFW_TRUE);
if (window->monitor)
releaseMonitor(window);
}
}
void _glfwRestoreWindowNull(_GLFWwindow* window)
{
if (window->null.iconified)
{
window->null.iconified = GLFW_FALSE;
_glfwInputWindowIconify(window, GLFW_FALSE);
if (window->monitor)
acquireMonitor(window);
}
else if (window->null.maximized)
{
window->null.maximized = GLFW_FALSE;
_glfwInputWindowMaximize(window, GLFW_FALSE);
}
}
void _glfwMaximizeWindowNull(_GLFWwindow* window)
{
if (!window->null.maximized)
{
window->null.maximized = GLFW_TRUE;
_glfwInputWindowMaximize(window, GLFW_TRUE);
}
}
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window)
{
return window->null.maximized;
}
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window)
{
return _glfw.null.xcursor >= window->null.xpos &&
_glfw.null.ycursor >= window->null.ypos &&
_glfw.null.xcursor <= window->null.xpos + window->null.width - 1 &&
_glfw.null.ycursor <= window->null.ypos + window->null.height - 1;
}
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window)
{
return window->null.transparent;
}
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.resizable = enabled;
}
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.decorated = enabled;
}
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.floating = enabled;
}
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled)
{ {
} }
void _glfwPlatformRestoreWindow(_GLFWwindow* window) float _glfwGetWindowOpacityNull(_GLFWwindow* window)
{
return window->null.opacity;
}
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity)
{
window->null.opacity = opacity;
}
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled)
{ {
} }
void _glfwPlatformMaximizeWindow(_GLFWwindow* window) GLFWbool _glfwRawMouseMotionSupportedNull(void)
{
return GLFW_TRUE;
}
void _glfwShowWindowNull(_GLFWwindow* window)
{
window->null.visible = GLFW_TRUE;
}
void _glfwRequestWindowAttentionNull(_GLFWwindow* window)
{ {
} }
int _glfwPlatformWindowMaximized(_GLFWwindow* window) void _glfwHideWindowNull(_GLFWwindow* window)
{ {
return GLFW_FALSE; if (_glfw.null.focusedWindow == window)
{
_glfw.null.focusedWindow = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE);
}
window->null.visible = GLFW_FALSE;
} }
int _glfwPlatformWindowHovered(_GLFWwindow* window) void _glfwFocusWindowNull(_GLFWwindow* window)
{ {
return GLFW_FALSE; _GLFWwindow* previous;
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) if (_glfw.null.focusedWindow == window)
{ return;
return GLFW_FALSE;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) if (!window->null.visible)
{ return;
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) previous = _glfw.null.focusedWindow;
{ _glfw.null.focusedWindow = window;
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) if (previous)
{ {
} _glfwInputWindowFocus(previous, GLFW_FALSE);
if (previous->monitor && previous->autoIconify)
_glfwIconifyWindowNull(previous);
}
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) _glfwInputWindowFocus(window, GLFW_TRUE);
{
return 1.f;
}
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{
}
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
{
}
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
{
return GLFW_FALSE;
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
} }
void _glfwPlatformDragWindow(_GLFWwindow* window) void _glfwPlatformDragWindow(_GLFWwindow* window)
@ -236,103 +480,254 @@ void _glfwPlatformResizeWindow(_GLFWwindow* window, int border)
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
return GLFW_FALSE; return _glfw.null.focusedWindow == window;
} }
int _glfwPlatformWindowIconified(_GLFWwindow* window) GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window)
{ {
return GLFW_FALSE; return _glfw.null.focusedWindow == window;
} }
int _glfwPlatformWindowVisible(_GLFWwindow* window) GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window)
{ {
return GLFW_FALSE; return window->null.iconified;
} }
void _glfwPlatformPollEvents(void) GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window)
{
return window->null.visible;
}
void _glfwPollEventsNull(void)
{ {
} }
void _glfwPlatformWaitEvents(void) void _glfwWaitEventsNull(void)
{ {
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwWaitEventsTimeoutNull(double timeout)
{ {
} }
void _glfwPlatformPostEmptyEvent(void) void _glfwPostEmptyEventNull(void)
{ {
} }
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos)
{
if (xpos)
*xpos = _glfw.null.xcursor - window->null.xpos;
if (ypos)
*ypos = _glfw.null.ycursor - window->null.ypos;
}
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y)
{
_glfw.null.xcursor = window->null.xpos + (int) x;
_glfw.null.ycursor = window->null.ypos + (int) y;
}
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode)
{ {
} }
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor,
{ const GLFWimage* image,
} int xhot, int yhot)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) void _glfwDestroyCursorNull(_GLFWcursor* cursor)
{ {
} }
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
} }
void _glfwPlatformSetClipboardString(const char* string) void _glfwSetClipboardStringNull(const char* string)
{ {
char* copy = _glfw_strdup(string);
_glfw_free(_glfw.null.clipboardString);
_glfw.null.clipboardString = copy;
} }
const char* _glfwPlatformGetClipboardString(void) const char* _glfwGetClipboardStringNull(void)
{ {
return _glfw.null.clipboardString;
}
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
{
return 0;
}
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
{
return 0;
}
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
{
return 0;
}
const char* _glfwGetScancodeNameNull(int scancode)
{
if (scancode < GLFW_KEY_SPACE || scancode > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL;
}
switch (scancode)
{
case GLFW_KEY_APOSTROPHE:
return "'";
case GLFW_KEY_COMMA:
return ",";
case GLFW_KEY_MINUS:
case GLFW_KEY_KP_SUBTRACT:
return "-";
case GLFW_KEY_PERIOD:
case GLFW_KEY_KP_DECIMAL:
return ".";
case GLFW_KEY_SLASH:
case GLFW_KEY_KP_DIVIDE:
return "/";
case GLFW_KEY_SEMICOLON:
return ";";
case GLFW_KEY_EQUAL:
case GLFW_KEY_KP_EQUAL:
return "=";
case GLFW_KEY_LEFT_BRACKET:
return "[";
case GLFW_KEY_RIGHT_BRACKET:
return "]";
case GLFW_KEY_KP_MULTIPLY:
return "*";
case GLFW_KEY_KP_ADD:
return "+";
case GLFW_KEY_BACKSLASH:
case GLFW_KEY_WORLD_1:
case GLFW_KEY_WORLD_2:
return "\\";
case GLFW_KEY_0:
case GLFW_KEY_KP_0:
return "0";
case GLFW_KEY_1:
case GLFW_KEY_KP_1:
return "1";
case GLFW_KEY_2:
case GLFW_KEY_KP_2:
return "2";
case GLFW_KEY_3:
case GLFW_KEY_KP_3:
return "3";
case GLFW_KEY_4:
case GLFW_KEY_KP_4:
return "4";
case GLFW_KEY_5:
case GLFW_KEY_KP_5:
return "5";
case GLFW_KEY_6:
case GLFW_KEY_KP_6:
return "6";
case GLFW_KEY_7:
case GLFW_KEY_KP_7:
return "7";
case GLFW_KEY_8:
case GLFW_KEY_KP_8:
return "8";
case GLFW_KEY_9:
case GLFW_KEY_KP_9:
return "9";
case GLFW_KEY_A:
return "a";
case GLFW_KEY_B:
return "b";
case GLFW_KEY_C:
return "c";
case GLFW_KEY_D:
return "d";
case GLFW_KEY_E:
return "e";
case GLFW_KEY_F:
return "f";
case GLFW_KEY_G:
return "g";
case GLFW_KEY_H:
return "h";
case GLFW_KEY_I:
return "i";
case GLFW_KEY_J:
return "j";
case GLFW_KEY_K:
return "k";
case GLFW_KEY_L:
return "l";
case GLFW_KEY_M:
return "m";
case GLFW_KEY_N:
return "n";
case GLFW_KEY_O:
return "o";
case GLFW_KEY_P:
return "p";
case GLFW_KEY_Q:
return "q";
case GLFW_KEY_R:
return "r";
case GLFW_KEY_S:
return "s";
case GLFW_KEY_T:
return "t";
case GLFW_KEY_U:
return "u";
case GLFW_KEY_V:
return "v";
case GLFW_KEY_W:
return "w";
case GLFW_KEY_X:
return "x";
case GLFW_KEY_Y:
return "y";
case GLFW_KEY_Z:
return "z";
}
return NULL; return NULL;
} }
const char* _glfwPlatformGetScancodeName(int scancode) int _glfwGetKeyScancodeNull(int key)
{ {
return ""; return key;
} }
int _glfwPlatformGetKeyScancode(int key) void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
{
return -1;
}
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
{ {
} }
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance,
VkPhysicalDevice device, VkPhysicalDevice device,
uint32_t queuefamily) uint32_t queuefamily)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
_GLFWwindow* window, _GLFWwindow* window,
const VkAllocationCallbacks* allocator, const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface) VkSurfaceKHR* surface)
{ {
// This seems like the most appropriate error to return here // This seems like the most appropriate error to return here
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_EXTENSION_NOT_PRESENT;
} }

View File

@ -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>
@ -37,17 +39,17 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
if (window) if (window)
{ {
int width, height; int width, height;
_glfwPlatformGetFramebufferSize(window, &width, &height); _glfw.platform.getFramebufferSize(window, &width, &height);
// Check to see if we need to allocate a new buffer // Check to see if we need to allocate a new buffer
if ((window->context.osmesa.buffer == NULL) || if ((window->context.osmesa.buffer == NULL) ||
(width != window->context.osmesa.width) || (width != window->context.osmesa.width) ||
(height != window->context.osmesa.height)) (height != window->context.osmesa.height))
{ {
free(window->context.osmesa.buffer); _glfw_free(window->context.osmesa.buffer);
// Allocate the new buffer (width * height * 8-bit RGBA) // Allocate the new buffer (width * height * 8-bit RGBA)
window->context.osmesa.buffer = calloc(4, (size_t) width * height); window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height);
window->context.osmesa.width = width; window->context.osmesa.width = width;
window->context.osmesa.height = height; window->context.osmesa.height = height;
} }
@ -81,7 +83,7 @@ static void destroyContextOSMesa(_GLFWwindow* window)
if (window->context.osmesa.buffer) if (window->context.osmesa.buffer)
{ {
free(window->context.osmesa.buffer); _glfw_free(window->context.osmesa.buffer);
window->context.osmesa.width = 0; window->context.osmesa.width = 0;
window->context.osmesa.height = 0; window->context.osmesa.height = 0;
} }
@ -122,6 +124,8 @@ GLFWbool _glfwInitOSMesa(void)
"libOSMesa.8.dylib", "libOSMesa.8.dylib",
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libOSMesa-8.so", "libOSMesa-8.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libOSMesa.so",
#else #else
"libOSMesa.so.8", "libOSMesa.so.8",
"libOSMesa.so.6", "libOSMesa.so.6",
@ -134,7 +138,7 @@ GLFWbool _glfwInitOSMesa(void)
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.osmesa.handle = _glfw_dlopen(sonames[i]); _glfw.osmesa.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.osmesa.handle) if (_glfw.osmesa.handle)
break; break;
} }
@ -146,19 +150,19 @@ GLFWbool _glfwInitOSMesa(void)
} }
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt) _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt");
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs) _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext) _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext");
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent) _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent");
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer) _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer) _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress) _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetProcAddress");
if (!_glfw.osmesa.CreateContextExt || if (!_glfw.osmesa.CreateContextExt ||
!_glfw.osmesa.DestroyContext || !_glfw.osmesa.DestroyContext ||
@ -181,12 +185,12 @@ void _glfwTerminateOSMesa(void)
{ {
if (_glfw.osmesa.handle) if (_glfw.osmesa.handle)
{ {
_glfw_dlclose(_glfw.osmesa.handle); _glfwPlatformFreeModule(_glfw.osmesa.handle);
_glfw.osmesa.handle = NULL; _glfw.osmesa.handle = NULL;
} }
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -217,24 +221,24 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{ {
int index = 0, attribs[40]; int index = 0, attribs[40];
setAttrib(OSMESA_FORMAT, OSMESA_RGBA); SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits); SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits); SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
setAttrib(OSMESA_ACCUM_BITS, accumBits); SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
{ {
setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE); SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
} }
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
{ {
setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE); SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
} }
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major); SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor); SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
} }
if (ctxconfig->forward) if (ctxconfig->forward)
@ -244,7 +248,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
setAttrib(0, 0); SET_ATTRIB(0, 0);
window->context.osmesa.handle = window->context.osmesa.handle =
OSMesaCreateContextAttribs(attribs, share); OSMesaCreateContextAttribs(attribs, share);
@ -283,7 +287,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -300,6 +304,12 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (!OSMesaGetColorBuffer(window->context.osmesa.handle, if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight, &mesaWidth, &mesaHeight,
&mesaFormat, &mesaBuffer)) &mesaFormat, &mesaBuffer))
@ -333,6 +343,12 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle, if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight, &mesaWidth, &mesaHeight,
&mesaBytes, &mesaBuffer)) &mesaBytes, &mesaBuffer))
@ -359,7 +375,7 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API) if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL; return NULL;

View File

@ -1,94 +0,0 @@
//========================================================================
// GLFW 3.4 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define OSMESA_RGBA 0x1908
#define OSMESA_FORMAT 0x22
#define OSMESA_DEPTH_BITS 0x30
#define OSMESA_STENCIL_BITS 0x31
#define OSMESA_ACCUM_BITS 0x32
#define OSMESA_PROFILE 0x33
#define OSMESA_CORE_PROFILE 0x34
#define OSMESA_COMPAT_PROFILE 0x35
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
typedef void* OSMesaContext;
typedef void (*OSMESAproc)(void);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext);
typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext);
typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int);
typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt
#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs
#define OSMesaDestroyContext _glfw.osmesa.DestroyContext
#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent
#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
#define _GLFW_OSMESA_CONTEXT_STATE _GLFWcontextOSMesa osmesa
#define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
// OSMesa-specific per-context data
//
typedef struct _GLFWcontextOSMesa
{
OSMesaContext handle;
int width;
int height;
void* buffer;
} _GLFWcontextOSMesa;
// OSMesa-specific global data
//
typedef struct _GLFWlibraryOSMesa
{
void* handle;
PFN_OSMesaCreateContextExt CreateContextExt;
PFN_OSMesaCreateContextAttribs CreateContextAttribs;
PFN_OSMesaDestroyContext DestroyContext;
PFN_OSMesaMakeCurrent MakeCurrent;
PFN_OSMesaGetColorBuffer GetColorBuffer;
PFN_OSMesaGetDepthBuffer GetDepthBuffer;
PFN_OSMesaGetProcAddress GetProcAddress;
} _GLFWlibraryOSMesa;
GLFWbool _glfwInitOSMesa(void);
void _glfwTerminateOSMesa(void);
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

195
src/platform.c Normal file
View File

@ -0,0 +1,195 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
// These construct a string literal from individual numeric constants
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
static const struct
{
int ID;
GLFWbool (*connect)(int,_GLFWplatform*);
} supportedPlatforms[] =
{
#if defined(_GLFW_WIN32)
{ GLFW_PLATFORM_WIN32, _glfwConnectWin32 },
#endif
#if defined(_GLFW_COCOA)
{ GLFW_PLATFORM_COCOA, _glfwConnectCocoa },
#endif
#if defined(_GLFW_X11)
{ GLFW_PLATFORM_X11, _glfwConnectX11 },
#endif
#if defined(_GLFW_WAYLAND)
{ GLFW_PLATFORM_WAYLAND, _glfwConnectWayland },
#endif
};
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
{
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
size_t i;
if (desiredID != GLFW_ANY_PLATFORM &&
desiredID != GLFW_PLATFORM_WIN32 &&
desiredID != GLFW_PLATFORM_COCOA &&
desiredID != GLFW_PLATFORM_WAYLAND &&
desiredID != GLFW_PLATFORM_X11 &&
desiredID != GLFW_PLATFORM_NULL)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID);
return GLFW_FALSE;
}
// Only allow the Null platform if specifically requested
if (desiredID == GLFW_PLATFORM_NULL)
return _glfwConnectNull(desiredID, platform);
else if (count == 0)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform");
return GLFW_FALSE;
}
if (desiredID == GLFW_ANY_PLATFORM)
{
// If there is exactly one platform available for auto-selection, let it emit the
// error on failure as the platform-specific error description may be more helpful
if (count == 1)
return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform);
for (i = 0; i < count; i++)
{
if (supportedPlatforms[i].connect(desiredID, platform))
return GLFW_TRUE;
}
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform");
}
else
{
for (i = 0; i < count; i++)
{
if (supportedPlatforms[i].ID == desiredID)
return supportedPlatforms[i].connect(desiredID, platform);
}
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported");
}
return GLFW_FALSE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwGetPlatform(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfw.platform.platformID;
}
GLFWAPI int glfwPlatformSupported(int platformID)
{
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
size_t i;
if (platformID != GLFW_PLATFORM_WIN32 &&
platformID != GLFW_PLATFORM_COCOA &&
platformID != GLFW_PLATFORM_WAYLAND &&
platformID != GLFW_PLATFORM_X11 &&
platformID != GLFW_PLATFORM_NULL)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", platformID);
return GLFW_FALSE;
}
if (platformID == GLFW_PLATFORM_NULL)
return GLFW_TRUE;
for (i = 0; i < count; i++)
{
if (platformID == supportedPlatforms[i].ID)
return GLFW_TRUE;
}
return GLFW_FALSE;
}
GLFWAPI const char* glfwGetVersionString(void)
{
return _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR,
GLFW_VERSION_MINOR,
GLFW_VERSION_REVISION)
#if defined(_GLFW_WIN32)
" Win32 WGL"
#endif
#if defined(_GLFW_COCOA)
" Cocoa NSGL"
#endif
#if defined(_GLFW_WAYLAND)
" Wayland"
#endif
#if defined(_GLFW_X11)
" X11 GLX"
#endif
" Null"
" EGL"
" OSMesa"
#if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64"
#elif defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#endif
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
" hybrid-GPU"
#endif
#if defined(_POSIX_MONOTONIC_CLOCK)
" monotonic"
#endif
#if defined(_GLFW_BUILD_DLL)
#if defined(_WIN32)
" DLL"
#elif defined(__APPLE__)
" dynamic"
#else
" shared"
#endif
#endif
;
}

Some files were not shown because too many files have changed in this diff Show More