summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rw-r--r--.travis.yml62
-rw-r--r--CMakeLists.txt8
-rw-r--r--README.md17
-rw-r--r--appveyor.yml64
-rw-r--r--examples/CMakeLists.txt21
-rw-r--r--examples/Makefile43
-rw-r--r--examples/models/models_yaw_pitch_roll.c14
-rw-r--r--examples/models/resources/angle_gauge.pngbin11761 -> 12919 bytes
-rw-r--r--examples/models/resources/plane.pngbin4872 -> 4810 bytes
-rw-r--r--examples/others/audio_standalone.c7
-rw-r--r--examples/others/resources/shaders/glsl100/standard.vs4
-rw-r--r--examples/others/resources/shaders/glsl330/standard.vs4
-rw-r--r--examples/shaders/resources/shaders/glsl120/base.fs22
-rw-r--r--examples/shaders/resources/shaders/glsl120/base.vs26
-rw-r--r--examples/shaders/resources/shaders/glsl120/bloom.fs37
-rw-r--r--examples/shaders/resources/shaders/glsl120/blur.fs32
-rw-r--r--examples/shaders/resources/shaders/glsl120/cross_hatching.fs45
-rw-r--r--examples/shaders/resources/shaders/glsl120/cross_stitching.fs55
-rw-r--r--examples/shaders/resources/shaders/glsl120/distortion.fs52
-rw-r--r--examples/shaders/resources/shaders/glsl120/dream_vision.fs35
-rw-r--r--examples/shaders/resources/shaders/glsl120/fisheye.fs41
-rw-r--r--examples/shaders/resources/shaders/glsl120/grayscale.fs23
-rw-r--r--examples/shaders/resources/shaders/glsl120/pixelizer.fs30
-rw-r--r--examples/shaders/resources/shaders/glsl120/posterization.fs27
-rw-r--r--examples/shaders/resources/shaders/glsl120/predator.fs29
-rw-r--r--examples/shaders/resources/shaders/glsl120/scanlines.fs42
-rw-r--r--examples/shaders/resources/shaders/glsl120/sobel.fs38
-rw-r--r--examples/shaders/resources/shaders/glsl120/swirl.fs44
-rw-r--r--examples/shaders/shaders_postprocessing.c29
-rw-r--r--examples/text/text_ttf_loading.c2
-rw-r--r--examples/textures/resources/KAISG.ttfbin0 -> 79912 bytes
-rw-r--r--examples/textures/textures_image_text.c83
-rw-r--r--examples/textures/textures_image_text.pngbin0 -> 556322 bytes
-rw-r--r--games/koala_seasons/Makefile6
-rw-r--r--games/koala_seasons/resources/graphics/atlas02.pngbin920645 -> 1017615 bytes
-rw-r--r--games/koala_seasons/resources/shaders/glsl100/base.vs4
-rw-r--r--games/koala_seasons/screens/screen_title.c10
-rw-r--r--games/wave_collector/wave_collector.c4
-rw-r--r--project/vs2015/examples/core_basic_window.vcxproj8
-rw-r--r--project/vs2015/examples/core_basic_window_cpp.vcxproj8
-rw-r--r--project/vs2015/external/glfw3/include/GLFW/glfw3native.h456
-rw-r--r--project/vs2015/external/glfw3/lib/win32/glfw3.dllbin70656 -> 0 bytes
-rw-r--r--project/vs2015/external/glfw3/lib/win32/glfw3.libbin240738 -> 0 bytes
-rw-r--r--project/vs2015/external/glfw3/lib/win32/glfw3dll.libbin24454 -> 0 bytes
-rw-r--r--project/vs2015/external/openal_soft/COPYING484
-rw-r--r--project/vs2015/external/openal_soft/include/AL/al.h656
-rw-r--r--project/vs2015/external/openal_soft/include/AL/alc.h237
-rw-r--r--project/vs2015/external/openal_soft/include/AL/alext.h438
-rw-r--r--project/vs2015/external/openal_soft/include/AL/efx-creative.h3
-rw-r--r--project/vs2015/external/openal_soft/include/AL/efx-presets.h402
-rw-r--r--project/vs2015/external/openal_soft/include/AL/efx.h761
-rw-r--r--project/vs2015/external/openal_soft/lib/win32/OpenAL32.dllbin845045 -> 0 bytes
-rw-r--r--project/vs2015/external/openal_soft/lib/win32/OpenAL32.libbin116274 -> 0 bytes
-rw-r--r--project/vs2015/external/openal_soft/lib/win64/OpenAL32.dllbin980543 -> 0 bytes
-rw-r--r--project/vs2015/external/openal_soft/lib/win64/OpenAL32.libbin116896 -> 0 bytes
-rw-r--r--project/vs2015/raylib.sln8
-rw-r--r--project/vs2015/raylib/raylib.dll.vcxproj130
-rw-r--r--project/vs2015/raylib/raylib.vcxproj4
-rw-r--r--project/vs2017/examples/core_basic_window.vcxproj106
-rw-r--r--project/vs2017/examples/core_basic_window_cpp.vcxproj105
-rw-r--r--project/vs2017/raylib.sln46
-rw-r--r--project/vs2017/raylib/raylib.dll.vcxproj130
-rw-r--r--project/vs2017/raylib/raylib.vcxproj123
-rw-r--r--raylib.pc.in13
-rw-r--r--release/libs/win32/mingw32/raylib.h1168
-rw-r--r--release/libs/win32/msvc/OpenAL32.dllbin763904 -> 731648 bytes
-rw-r--r--release/libs/win32/msvc/OpenAL32.libbin117830 -> 0 bytes
-rw-r--r--release/libs/win32/msvc/OpenAL32dll.libbin0 -> 34440 bytes
-rw-r--r--release/libs/win32/msvc/libOpenAL32.dll.abin101606 -> 0 bytes
-rw-r--r--release/libs/win32/msvc/raylib.dllbin0 -> 593920 bytes
-rw-r--r--release/libs/win32/msvc/raylibdll.libbin0 -> 64760 bytes
-rw-r--r--src/CMakeLists.txt158
-rw-r--r--src/Makefile80
-rw-r--r--src/core.c63
-rw-r--r--src/external/glfw/LICENSE.md (renamed from project/vs2015/external/glfw3/COPYING.txt)4
-rw-r--r--src/external/glfw/README.md435
-rw-r--r--src/external/glfw/deps/mingw/_mingw_dxhelper.h117
-rw-r--r--src/external/glfw/deps/mingw/dinput.h2467
-rw-r--r--src/external/glfw/deps/mingw/xinput.h239
-rw-r--r--src/external/glfw/deps/vs2008/stdint.h247
-rw-r--r--src/external/glfw/include/GLFW/glfw3.h (renamed from project/vs2015/external/glfw3/include/GLFW/glfw3.h)1517
-rw-r--r--src/external/glfw/include/GLFW/glfw3native.h (renamed from src/external/include/GLFW/glfw3native.h)130
-rw-r--r--src/external/glfw/src/cocoa_init.m374
-rw-r--r--src/external/glfw/src/cocoa_joystick.h50
-rw-r--r--src/external/glfw/src/cocoa_joystick.m462
-rw-r--r--src/external/glfw/src/cocoa_monitor.m531
-rw-r--r--src/external/glfw/src/cocoa_platform.h164
-rw-r--r--src/external/glfw/src/cocoa_time.c60
-rw-r--r--src/external/glfw/src/cocoa_window.m1863
-rw-r--r--src/external/glfw/src/context.c723
-rw-r--r--src/external/glfw/src/egl_context.c786
-rw-r--r--src/external/glfw/src/egl_context.h219
-rw-r--r--src/external/glfw/src/glfw3.pc.in13
-rw-r--r--src/external/glfw/src/glfw3Config.cmake.in1
-rw-r--r--src/external/glfw/src/glfw_config.h.in57
-rw-r--r--src/external/glfw/src/glx_context.c698
-rw-r--r--src/external/glfw/src/glx_context.h181
-rw-r--r--src/external/glfw/src/init.c317
-rw-r--r--src/external/glfw/src/input.c1151
-rw-r--r--src/external/glfw/src/internal.h1016
-rw-r--r--src/external/glfw/src/linux_joystick.c429
-rw-r--r--src/external/glfw/src/linux_joystick.h62
-rw-r--r--src/external/glfw/src/mappings.h241
-rw-r--r--src/external/glfw/src/mappings.h.in70
-rw-r--r--src/external/glfw/src/mir_init.c240
-rw-r--r--src/external/glfw/src/mir_monitor.c214
-rw-r--r--src/external/glfw/src/mir_platform.h133
-rw-r--r--src/external/glfw/src/mir_window.c955
-rw-r--r--src/external/glfw/src/monitor.c467
-rw-r--r--src/external/glfw/src/nsgl_context.h56
-rw-r--r--src/external/glfw/src/nsgl_context.m335
-rw-r--r--src/external/glfw/src/null_init.c50
-rw-r--r--src/external/glfw/src/null_joystick.c42
-rw-r--r--src/external/glfw/src/null_joystick.h31
-rw-r--r--src/external/glfw/src/null_monitor.c64
-rw-r--r--src/external/glfw/src/null_platform.h62
-rw-r--r--src/external/glfw/src/null_window.c307
-rw-r--r--src/external/glfw/src/osmesa_context.c370
-rw-r--r--src/external/glfw/src/osmesa_context.h94
-rw-r--r--src/external/glfw/src/posix_thread.c103
-rw-r--r--src/external/glfw/src/posix_thread.h51
-rw-r--r--src/external/glfw/src/posix_time.c85
-rw-r--r--src/external/glfw/src/posix_time.h44
-rw-r--r--src/external/glfw/src/vulkan.c322
-rw-r--r--src/external/glfw/src/wgl_context.c731
-rw-r--r--src/external/glfw/src/wgl_context.h158
-rw-r--r--src/external/glfw/src/win32_init.c583
-rw-r--r--src/external/glfw/src/win32_joystick.c751
-rw-r--r--src/external/glfw/src/win32_joystick.h56
-rw-r--r--src/external/glfw/src/win32_monitor.c512
-rw-r--r--src/external/glfw/src/win32_platform.h409
-rw-r--r--src/external/glfw/src/win32_thread.c97
-rw-r--r--src/external/glfw/src/win32_time.c74
-rw-r--r--src/external/glfw/src/win32_window.c1953
-rw-r--r--src/external/glfw/src/window.c1021
-rw-r--r--src/external/glfw/src/wl_init.c792
-rw-r--r--src/external/glfw/src/wl_monitor.c201
-rw-r--r--src/external/glfw/src/wl_platform.h223
-rw-r--r--src/external/glfw/src/wl_window.c1106
-rw-r--r--src/external/glfw/src/x11_init.c1045
-rw-r--r--src/external/glfw/src/x11_monitor.c510
-rw-r--r--src/external/glfw/src/x11_platform.h442
-rw-r--r--src/external/glfw/src/x11_window.c2991
-rw-r--r--src/external/glfw/src/xkb_unicode.c940
-rw-r--r--src/external/glfw/src/xkb_unicode.h28
-rw-r--r--src/external/include/GLFW/glfw3.h4235
-rw-r--r--src/external/include/GLFW_COPYING.txt22
-rw-r--r--src/external/rgif.h75
-rw-r--r--src/gestures.h32
-rw-r--r--src/physac.h28
-rw-r--r--src/raylib.h60
-rw-r--r--src/raymath.h20
-rw-r--r--src/rglfw.c107
-rw-r--r--src/rlgl.c323
-rw-r--r--src/rlgl.h108
-rw-r--r--src/shader_distortion.h4
-rw-r--r--src/text.c19
-rw-r--r--src/textures.c82
-rw-r--r--utils.cmake79
160 files changed, 35341 insertions, 9684 deletions
diff --git a/.gitignore b/.gitignore
index 212d66b5..65b3020c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,10 +93,9 @@ project/vs2015/*.opendb
!project/vs2015/raylib.sln
!project/vs2015/raylib/*.vcxproj
!project/vs2015/examples/*.vcxproj
-!project/vs2015/external/glfw3/lib/win32/glfw3.dll
-!project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll
-!project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
-!project/vs2015/external/lua/lib/win32/lua53.dll
+!project/vs2017/raylib.sln
+!project/vs2017/raylib/*.vcxproj
+!project/vs2017/examples/*.vcxproj
# Web examples
docs/examples/web/*.html
@@ -133,3 +132,8 @@ build
# Ignore Android generated files and folders
templates/android_project/output
+
+# Ignore GNU global tags
+GPATH
+GRTAGS
+GTAGS
diff --git a/.travis.yml b/.travis.yml
index 703206e2..28641b38 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,50 +1,54 @@
language: c
-sudo: required
dist: trusty
git:
depth: 3
-os:
- - osx
- - linux
+# TODO we could use a 32 bit Docker container for running true 32-bit tests
+# services: - docker
-env:
- global:
- - VERBOSE=1
- matrix:
- - CFLAGS=-m64
- - CFLAGS=-m32
+matrix: # We don't install x11 32-bit libraries, so skip shared libraries on -m32
+ include:
+ - os: linux
+ env: ARCH=i386 SHARED=OFF EXAMPLES=OFF
+ sudo: required
+ - os: linux
+ env: ARCH=amd64 SHARED=ON EXAMPLES=ON
+ sudo: required
+ - os: osx
+ env: ARCH=amd64 SHARED=ON EXAMPLES=ON
before_script:
- - export CFLAGS="-std=gnu99 $CFLAGS"
before_install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
sudo apt-get install -y gcc-multilib
libopenal-dev
libxcursor-dev libxinerama-dev
- mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev libglew-dev;
- wget 'https://github.com/a3f/GLFW-3.2.1-Debian-binary-package/releases/download/v3.2.1/GLFW-3.2.1-Linux.deb' && sudo dpkg -i GLFW-3.2.1-Linux.deb;
+ mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev
+ libgl1-mesa-dev libglu1-mesa-dev libglew-dev;
+ export RAYLIB_PACKAGE_SUFFIX="-Linux-$ARCH";
+ if [ "$ARCH" == "i386" ]; then export CFLAGS="-m32"; fi;
+ if [ "$ARCH" == "amd64" ]; then export CFLAGS="-m64"; fi;
fi
- - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; brew install glfw; fi
+ - if [ "$TRAVIS_OS_NAME" == "osx" ]; then export RAYLIB_PACKAGE_SUFFIX="-macOS"; fi
- "$CC --version"
script:
- mkdir build
- cd build
- - cmake -DBUILD_EXAMPLES=OFF -DBUILD_GAMES=OFF ..
- - make
-# - make package
-# - sudo make install
-#
-#deploy:
-# provider: releases
-# api_key:
-# secure: XXX
-# file_glob: true
-# file: raylib-*.tar.gz
-# skip_cleanup: true
-# on:
-# branch: master
-# tags: true
+ - cmake -DMACOS_FATLIB=ON -DSTATIC_RAYLIB=ON -DSHARED_RAYLIB=$SHARED -DBUILD_EXAMPLES=$EXAMPLES -DBUILD_GAMES=$EXAMPLES ..
+ - make VERBOSE=1
+ - make package
+
+deploy:
+ provider: releases
+ api_key:
+ secure: LvqUIAN/3dJul+Ra2iK3tSaNG5IwsNMmGIwVMy0DK5IBCxiQPBc9pWGiE30RTBPt6Z+N4BhMEE8DtUl+vnISlMoHWNIIhF2zwC66hs/F7zY7qEITMRSmfiLcqxQysknFOnJB06CATgXcFqlEo9j+t4abrG/f3qcb92J4O2uNz336Au2myTx93Q5MxbyA7KiUuEutFnb2dWiPCY4d+sGeXEfsiD2R7aj/8MaWOkoGdZVrTkI9juMgvpImkjQBArvqdjUMeT3MsRrwgOIq5v2GFV9dOl8k1WzPeT8B2JHh00ed/o1/wuFq/cLLOxtYo2+Pv3+xatOrlexoX0WkDm7C9/L1W5U4rLexU3CQ9mMBmHPnp6k/WXZ5QXEE4uUF0+LpN3XlIXzFpdZmZiVV8VLxg2WvyncMmivYiu7/MTkyfZxyKkzwl7sZZslzHA9kOGedGaN7b7/2B77OFHoQK8lKfdFml7jJnarh+89nenNZYMab0E8qkOJOyb2bYlDTa0/2nyxGiyymYgq6YHLNrDbhqB/1LzdgzjMliQ8ri5q9Ux2vjfcqOzhfAmcwFwnY/D6yXJWYi0DWpHZdpKl3du6dYDrypW91/yDWbwiJ/YhrE7ZunzrcB6GH/QkbuzWxdCth39rQAHih8DG01co/K3Gvi4yGjvIH5tFUpyEolMnpMiA=
+ file_glob: true
+ file: raylib-*.tar.gz
+ skip_cleanup: true
+ on:
+ repo: raysan5/raylib
+ branch: develop
+ tags: true
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0dfa0857..057481bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,14 @@ cmake_minimum_required(VERSION 3.0)
set(BUILD_EXAMPLES ON CACHE BOOL "Build the examples.")
set(BUILD_GAMES ON CACHE BOOL "Build the example games.")
+if(CMAKE_VERSION VERSION_LESS "3.1")
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
+ endif()
+else()
+ set (CMAKE_C_STANDARD 99)
+endif()
+
add_subdirectory(src release)
if (${BUILD_EXAMPLES})
diff --git a/README.md b/README.md
index 6fe325d4..db8e9698 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,10 @@ no fancy interface, no visual helpers, no auto-debugging... just coding in the m
pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
[![Build Status](https://travis-ci.org/raysan5/raylib.svg?branch=develop)](https://travis-ci.org/raysan5/raylib)
+[![https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true](https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true)](https://ci.appveyor.com/project/raysan5/raylib)
+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/raylib/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE.md)
+[![Twitter URL](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow)](https://twitter.com/raysan5)
features
--------
@@ -27,7 +31,7 @@ features
* Audio loading and playing with streaming support (WAV, OGG, FLAC, XM, MOD)
* Multiple platforms support: Windows, Linux, Mac, **Android**, **Raspberry Pi** and **HTML5**
* VR stereo rendering support with configurable HMD device parameters
- * Minimal external dependencies (GLFW3, OpenGL, OpenAL)
+ * Minimal external dependencies (OpenGL, OpenAL)
* Complete bindings to LUA ([raylib-lua](https://github.com/raysan5/raylib-lua)) and Go ([raylib-go](https://github.com/gen2brain/raylib-go))
raylib uses on its core module the outstanding [GLFW3](http://www.glfw.org/) library. The best option I found for
@@ -40,10 +44,14 @@ to accomodate to Android, Raspberry Pi and HTML5.
*On Raspberry Pi, Videocore API and EGL libraries are used for window/context management and raw inputs reading.*
-building
---------
+build and installation
+----------------------
+
+Binary releases for Windows, Linux and macOS are available at the [Github Releases](https://github.com/raysan5/raylib/releases) page. Raylib is also available via following package managers:
+
+ * Homebrew: `brew install raylib`
-For detailed building instructions, check [raylib Wiki](https://github.com/raysan5/raylib/wiki).
+To build raylib yourself, check out the [raylib Wiki](https://github.com/raysan5/raylib/wiki) for detailed instructions.
raylib has been developed using exclusively two tools:
@@ -61,6 +69,7 @@ contact
* Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
* Twitch: [http://www.twitch.tv/raysan5](http://www.twitch.tv/raysan5)
* Patreon: [https://www.patreon.com/raysan5](https://www.patreon.com/raysan5)
+ * YouTube: [https://www.youtube.com/channel/raylib](https://www.youtube.com/channel/UC8WIBkhYb5sBNqXO1mZ7WSQ)
If you are using raylib and you enjoy it, please, [let me know][raysan5].
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..bee59fa5
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,64 @@
+#os: Visual Studio 2015
+
+clone_depth: 5
+
+cache:
+ - C:\ProgramData\chocolatey\bin -> appveyor.yml
+ - C:\ProgramData\chocolatey\lib -> appveyor.yml
+
+init:
+ - cmake -E remove c:\programdata\chocolatey\bin\cpack.exe
+ - set PATH=%PATH:C:\Program Files (x86)\Git\usr\bin;=%
+ - set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
+ - if [%BITS%]==[32] set MINGW=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32
+ - if [%BITS%]==[64] set MINGW=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64
+ - if [%COMPILER%]==[mingw] set PATH=%MINGW%\bin;%PATH%
+ - set RAYLIB_PACKAGE_SUFFIX=-Win%BITS%-%COMPILER%
+ - set VERBOSE=1
+
+environment:
+ matrix:
+ - compiler: mingw
+ bits: 32
+ - compiler: mingw
+ bits: 64
+ - compiler: msvc15
+ bits: 32
+ - compiler: msvc15
+ bits: 64
+
+before_build:
+ - appveyor DownloadFile http://openal-soft.org/openal-binaries/openal-soft-1.17.2-bin.zip
+ - 7z x openal-soft-1.17.2-bin.zip
+ - move openal-soft-1.17.2-bin src\external\openal
+ - if [%compiler%]==[mingw] set CFLAGS=-m%BITS% & set LDFLAGS=-m%BITS% & set GENERATOR="MinGW Makefiles"
+ - if [%COMPILER%]==[msvc15] if [%BITS%]==[32] set GENERATOR="Visual Studio 14 2015"
+ - if [%COMPILER%]==[msvc15] if [%BITS%]==[64] set GENERATOR="Visual Studio 14 2015 Win64"
+ - mkdir build
+ - cd build
+
+build_script:
+ - cmake -G %GENERATOR% -DSTATIC_RAYLIB=ON -DSHARED_RAYLIB=OFF -DBUILD_EXAMPLES=OFF -DBUILD_GAMES=OFF ..
+ - cmake --build . --target install
+
+after_build:
+ - cmake --build . --target package
+
+before_test:
+
+test_script:
+
+artifacts:
+ - path: 'build\*.zip'
+
+deploy:
+ - provider: GitHub
+ auth_token:
+ secure: OxKnnT3tlkPl9365cOO84rDWU4UkHIYJc0D3r3Tv7rB3HaR2BBhlhCnl7g3nuOJy
+ artifact: /.*\.zip/
+ draft: false
+ prerelease: false
+ force_update: true
+ on:
+ branch: develop
+ appveyor_repo_tag: true # deploy on tag push only
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 354a1373..96ce37e0 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -7,9 +7,20 @@ include("../utils.cmake")
# TODO `build` directory should maybe be something else...
# TODO place somewhere else?
include_directories("../build/release")
+include_directories("../src/external")
+include_directories("../src/external/glfw/include")
# Get the sources together
-set(example_dirs audio core models others physac shaders text texutures)
+set(example_dirs audio core models others shaders text texutures)
+set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=199309L)
+ include(CheckSymbolExists)
+ check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
+ check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC)
+set(CMAKE_REQUIRED_DEFINITIONS)
+if(HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
+ set(example_dirs ${example_dirs} physac)
+endif()
+
set(example_sources)
set(example_resources)
foreach(example_dir ${example_dirs})
@@ -22,6 +33,14 @@ foreach(example_dir ${example_dirs})
list(APPEND example_resources ${resources})
endforeach()
+include(CheckIncludeFiles)
+check_include_files(OVR_CAPI_GL.h HAVE_OCULUS_CAPI)
+if(NOT HAVE_OCULUS_CAPI)
+ list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/oculus_rift.c)
+endif()
+list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c)
+
+
# Do each example
foreach(example_source ${example_sources})
# Create the basename for the example
diff --git a/examples/Makefile b/examples/Makefile
index edcff807..c5629090 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -54,12 +54,16 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
LIBPATH=linux
- else
+ endif
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ LIBPATH=linux
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
LIBPATH=osx
endif
- endif
endif
endif
@@ -90,6 +94,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),OSX)
RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/osx
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/freebsd
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
RAYLIB_RELEASE = $(RAYLIB_PATH)/release/libs/html5
@@ -106,6 +113,10 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
ifeq ($(RPI_CROSS_COMPILE),YES)
@@ -178,6 +189,13 @@ endif
# Define library paths containing required libs
LDFLAGS = -L. -L$(RAYLIB_RELEASE) -L$(RAYLIB_PATH)/src
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib
+ endif
+endif
+
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
endif
@@ -215,11 +233,19 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# NOTE: Required packages: libglfw3-dev libopenal-dev libegl1-mesa-dev
LDLIBS = -lraylib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # Libraries for FreeBSD desktop compiling
+ # NOTE: Required packages: glfw openal-soft mesa-libs
+ LDLIBS = -lraylib -lglfw -lGL -lopenal -lpthread -lm
+
+ # On XWindow requires also below libraries
+ LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
# NOTE: Required packages: libopenal1
- LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
+ LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -lopenal
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
@@ -241,7 +267,6 @@ EXAMPLES = \
core/core_input_gamepad \
core/core_random_values \
core/core_color_select \
- core/core_drop_files \
core/core_storage_values \
core/core_gestures_detection \
core/core_3d_mode \
@@ -266,6 +291,7 @@ EXAMPLES = \
textures/textures_image_processing \
textures/textures_image_drawing \
textures/textures_image_generation \
+ textures/textures_image_text \
text/text_sprite_fonts \
text/text_bmfont_ttf \
text/text_raylib_fonts \
@@ -299,6 +325,10 @@ EXAMPLES = \
physac/physics_restitution \
physac/physics_shatter \
fix_dylib \
+
+ifneq ($(PLATFORM),PLATFORM_RPI)
+ EXAMPLES += core/core_drop_files
+endif
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
@@ -333,6 +363,10 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
find . -type f -perm +ugo+x -delete
rm -f *.o
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ find . -type f -perm +ugo+x -delete
+ rm -f *.o
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
find . -type f -executable -delete
@@ -342,4 +376,3 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o *.html *.js
endif
@echo Cleaning done
-
diff --git a/examples/models/models_yaw_pitch_roll.c b/examples/models/models_yaw_pitch_roll.c
index 2bae2bf8..625fc554 100644
--- a/examples/models/models_yaw_pitch_roll.c
+++ b/examples/models/models_yaw_pitch_roll.c
@@ -119,17 +119,17 @@ int main()
BeginBlendMode(BLEND_ALPHA);
- DrawTexturePro(texBackground, (Rectangle){0,0,texBackground.width, texBackground.height},
+ DrawTexturePro(texBackground, (Rectangle){ 0, 0, texBackground.width, texBackground.height },
(Rectangle){ centerX, centerY, texBackground.width*scaleFactor, texBackground.height*scaleFactor},
- (Vector2){texBackground.width/2*scaleFactor, texBackground.height/2*scaleFactor + pitchOffset*scaleFactor}, roll, WHITE);
+ (Vector2){ texBackground.width/2*scaleFactor, texBackground.height/2*scaleFactor + pitchOffset*scaleFactor }, roll, WHITE);
DrawTexturePro(texPitch, (Rectangle){ 0, 0, texPitch.width, texPitch.height },
(Rectangle){ centerX, centerY, texPitch.width*scaleFactor, texPitch.height*scaleFactor },
(Vector2){ texPitch.width/2*scaleFactor, texPitch.height/2*scaleFactor + pitchOffset*scaleFactor }, roll, WHITE);
- DrawTexturePro(texPlane, (Rectangle){0,0,texPlane.width, texPlane.height },
+ DrawTexturePro(texPlane, (Rectangle){ 0, 0, texPlane.width, texPlane.height },
(Rectangle){ centerX, centerY, texPlane.width*scaleFactor, texPlane.height*scaleFactor },
- (Vector2){texPlane.width/2*scaleFactor, texPlane.height/2*scaleFactor }, 0, WHITE);
+ (Vector2){ texPlane.width/2*scaleFactor, texPlane.height/2*scaleFactor }, 0, WHITE);
EndBlendMode();
@@ -144,9 +144,9 @@ int main()
End3dMode();
// Draw 2D GUI stuff
- DrawAngleGauge(texAngleGauge, 80, 80, roll, "roll", RED);
- DrawAngleGauge(texAngleGauge, 190, 80, pitch, "pitch", GREEN);
- DrawAngleGauge(texAngleGauge, 300, 80, yaw, "yaw", SKYBLUE);
+ DrawAngleGauge(texAngleGauge, 80, 70, roll, "roll", RED);
+ DrawAngleGauge(texAngleGauge, 190, 70, pitch, "pitch", GREEN);
+ DrawAngleGauge(texAngleGauge, 300, 70, yaw, "yaw", SKYBLUE);
DrawRectangle(30, 360, 260, 70, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(30, 360, 260, 70, Fade(DARKBLUE, 0.5f));
diff --git a/examples/models/resources/angle_gauge.png b/examples/models/resources/angle_gauge.png
index 120f3601..f7871de6 100644
--- a/examples/models/resources/angle_gauge.png
+++ b/examples/models/resources/angle_gauge.png
Binary files differ
diff --git a/examples/models/resources/plane.png b/examples/models/resources/plane.png
index 9f28ddb0..58951ea3 100644
--- a/examples/models/resources/plane.png
+++ b/examples/models/resources/plane.png
Binary files differ
diff --git a/examples/others/audio_standalone.c b/examples/others/audio_standalone.c
index 0a09c988..97c3fd0d 100644
--- a/examples/others/audio_standalone.c
+++ b/examples/others/audio_standalone.c
@@ -26,14 +26,11 @@
********************************************************************************************/
#include <stdio.h>
+#include "audio.h"
#if defined(_WIN32)
#include <conio.h> // Windows only, no stardard library
-#endif
-
-#include "audio.h"
-
-#if defined(__linux__)
+#else
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
diff --git a/examples/others/resources/shaders/glsl100/standard.vs b/examples/others/resources/shaders/glsl100/standard.vs
index 49c5a3eb..2b958938 100644
--- a/examples/others/resources/shaders/glsl100/standard.vs
+++ b/examples/others/resources/shaders/glsl100/standard.vs
@@ -10,7 +10,7 @@ varying vec2 fragTexCoord;
varying vec4 fragColor;
varying vec3 fragNormal;
-uniform mat4 mvpMatrix;
+uniform mat4 mvp;
void main()
{
@@ -19,5 +19,5 @@ void main()
fragColor = vertexColor;
fragNormal = vertexNormal;
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
} \ No newline at end of file
diff --git a/examples/others/resources/shaders/glsl330/standard.vs b/examples/others/resources/shaders/glsl330/standard.vs
index fc0a5ff4..7fbdbf5e 100644
--- a/examples/others/resources/shaders/glsl330/standard.vs
+++ b/examples/others/resources/shaders/glsl330/standard.vs
@@ -10,7 +10,7 @@ out vec2 fragTexCoord;
out vec4 fragColor;
out vec3 fragNormal;
-uniform mat4 mvpMatrix;
+uniform mat4 mvp;
void main()
{
@@ -19,5 +19,5 @@ void main()
fragColor = vertexColor;
fragNormal = vertexNormal;
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/base.fs b/examples/shaders/resources/shaders/glsl120/base.fs
new file mode 100644
index 00000000..18799f95
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/base.fs
@@ -0,0 +1,22 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+uniform vec2 resolution = vec2(800, 450);
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+
+ // NOTE: Implement here your fragment shader code
+
+ gl_FragColor = texelColor*colDiffuse;
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/base.vs b/examples/shaders/resources/shaders/glsl120/base.vs
new file mode 100644
index 00000000..674153d8
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/base.vs
@@ -0,0 +1,26 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 mvp;
+
+// Output vertex attributes (to fragment shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ // Send vertex attributes to fragment shader
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+
+ // Calculate final vertex position
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/bloom.fs b/examples/shaders/resources/shaders/glsl120/bloom.fs
new file mode 100644
index 00000000..c28836b0
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/bloom.fs
@@ -0,0 +1,37 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+const vec2 size = vec2(800, 450); // render size
+const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance
+const float quality = 2.5; // lower = smaller glow, better quality
+
+void main()
+{
+ vec4 sum = vec4(0);
+ vec2 sizeFactor = vec2(1)/size*quality;
+
+ // Texel color fetching from texture sampler
+ vec4 source = texture2D(texture0, fragTexCoord);
+
+ const int range = 2; // should be = (samples - 1)/2;
+
+ for (int x = -range; x <= range; x++)
+ {
+ for (int y = -range; y <= range; y++)
+ {
+ sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor);
+ }
+ }
+
+ // Calculate final fragment color
+ gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse;
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/blur.fs b/examples/shaders/resources/shaders/glsl120/blur.fs
new file mode 100644
index 00000000..99cddfc9
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/blur.fs
@@ -0,0 +1,32 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
+
+vec3 offset = vec3(0.0, 1.3846153846, 3.2307692308);
+vec3 weight = vec3(0.2270270270, 0.3162162162, 0.0702702703);
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec3 tc = texture2D(texture0, fragTexCoord).rgb*weight.x;
+
+ tc += texture2D(texture0, fragTexCoord + vec2(offset.y)/renderWidth, 0.0).rgb*weight.y;
+ tc += texture2D(texture0, fragTexCoord - vec2(offset.y)/renderWidth, 0.0).rgb*weight.y;
+
+ tc += texture2D(texture0, fragTexCoord + vec2(offset.z)/renderWidth, 0.0).rgb*weight.z;
+ tc += texture2D(texture0, fragTexCoord - vec2(offset.z)/renderWidth, 0.0).rgb*weight.z;
+
+ gl_FragColor = vec4(tc, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/cross_hatching.fs b/examples/shaders/resources/shaders/glsl120/cross_hatching.fs
new file mode 100644
index 00000000..46514120
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/cross_hatching.fs
@@ -0,0 +1,45 @@
+# version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+float hatchOffsetY = 5.0;
+float lumThreshold01 = 0.9;
+float lumThreshold02 = 0.7;
+float lumThreshold03 = 0.5;
+float lumThreshold04 = 0.3;
+
+void main()
+{
+ vec3 tc = vec3(1.0, 1.0, 1.0);
+ float lum = length(texture2D(texture0, fragTexCoord).rgb);
+
+ if (lum < lumThreshold01)
+ {
+ if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ if (lum < lumThreshold02)
+ {
+ if (mod(gl_FragCoord .x - gl_FragCoord .y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ if (lum < lumThreshold03)
+ {
+ if (mod(gl_FragCoord .x + gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ if (lum < lumThreshold04)
+ {
+ if (mod(gl_FragCoord .x - gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0);
+ }
+
+ gl_FragColor = vec4(tc, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/cross_stitching.fs b/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
new file mode 100644
index 00000000..dee4617e
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
@@ -0,0 +1,55 @@
+# version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
+
+float stitchingSize = 6.0;
+int invert = 0;
+
+vec4 PostFX(sampler2D tex, vec2 uv)
+{
+ vec4 c = vec4(0.0);
+ float size = stitchingSize;
+ vec2 cPos = uv * vec2(renderWidth, renderHeight);
+ vec2 tlPos = floor(cPos / vec2(size, size));
+ tlPos *= size;
+
+ int remX = int(mod(cPos.x, size));
+ int remY = int(mod(cPos.y, size));
+
+ if (remX == 0 && remY == 0) tlPos = cPos;
+
+ vec2 blPos = tlPos;
+ blPos.y += (size - 1.0);
+
+ if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
+ {
+ if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
+ else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ }
+ else
+ {
+ if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ else c = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+
+ return c;
+}
+
+void main()
+{
+ vec3 tc = PostFX(texture0, fragTexCoord).rgb;
+
+ gl_FragColor = vec4(tc, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/distortion.fs b/examples/shaders/resources/shaders/glsl120/distortion.fs
new file mode 100644
index 00000000..f9d7f1e5
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/distortion.fs
@@ -0,0 +1,52 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+
+// Input uniform values
+uniform sampler2D texture0;
+
+// NOTE: Default parameters for Oculus Rift DK2 device
+const vec2 LeftLensCenter = vec2(0.2863248, 0.5);
+const vec2 RightLensCenter = vec2(0.7136753, 0.5);
+const vec2 LeftScreenCenter = vec2(0.25, 0.5);
+const vec2 RightScreenCenter = vec2(0.75, 0.5);
+const vec2 Scale = vec2(0.25, 0.45);
+const vec2 ScaleIn = vec2(4.0, 2.5);
+const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0);
+const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
+
+void main()
+{
+ // The following two variables need to be set per eye
+ vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter;
+ vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter;
+
+ // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter)
+ vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1]
+ float rSq = theta.x*theta.x + theta.y*theta.y;
+ vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq);
+ //vec2 tc = LensCenter + Scale*theta1;
+
+ // Detect whether blue texture coordinates are out of range since these will scaled out the furthest
+ vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq);
+ vec2 tcBlue = LensCenter + Scale*thetaBlue;
+
+ if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ else
+ {
+ // Do blue texture lookup
+ float blue = texture2D(texture0, tcBlue).b;
+
+ // Do green lookup (no scaling)
+ vec2 tcGreen = LensCenter + Scale*theta1;
+ float green = texture2D(texture0, tcGreen).g;
+
+ // Do red scale and lookup
+ vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq);
+ vec2 tcRed = LensCenter + Scale*thetaRed;
+ float red = texture2D(texture0, tcRed).r;
+
+ gl_FragColor = vec4(red, green, blue, 1.0);
+ }
+}
diff --git a/examples/shaders/resources/shaders/glsl120/dream_vision.fs b/examples/shaders/resources/shaders/glsl120/dream_vision.fs
new file mode 100644
index 00000000..4ca2a863
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/dream_vision.fs
@@ -0,0 +1,35 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ vec4 color = texture2D(texture0, fragTexCoord);
+
+ color += texture2D(texture0, fragTexCoord + 0.001);
+ color += texture2D(texture0, fragTexCoord + 0.003);
+ color += texture2D(texture0, fragTexCoord + 0.005);
+ color += texture2D(texture0, fragTexCoord + 0.007);
+ color += texture2D(texture0, fragTexCoord + 0.009);
+ color += texture2D(texture0, fragTexCoord + 0.011);
+
+ color += texture2D(texture0, fragTexCoord - 0.001);
+ color += texture2D(texture0, fragTexCoord - 0.003);
+ color += texture2D(texture0, fragTexCoord - 0.005);
+ color += texture2D(texture0, fragTexCoord - 0.007);
+ color += texture2D(texture0, fragTexCoord - 0.009);
+ color += texture2D(texture0, fragTexCoord - 0.011);
+
+ color.rgb = vec3((color.r + color.g + color.b)/3.0);
+ color = color/9.5;
+
+ gl_FragColor = color;
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/fisheye.fs b/examples/shaders/resources/shaders/glsl120/fisheye.fs
new file mode 100644
index 00000000..6f376ba3
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/fisheye.fs
@@ -0,0 +1,41 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+const float PI = 3.1415926535;
+
+void main()
+{
+ float aperture = 178.0;
+ float apertureHalf = 0.5 * aperture * (PI / 180.0);
+ float maxFactor = sin(apertureHalf);
+
+ vec2 uv = vec2(0.0);
+ vec2 xy = 2.0 * fragTexCoord.xy - 1.0;
+ float d = length(xy);
+
+ if (d < (2.0 - maxFactor))
+ {
+ d = length(xy * maxFactor);
+ float z = sqrt(1.0 - d * d);
+ float r = atan(d, z) / PI;
+ float phi = atan(xy.y, xy.x);
+
+ uv.x = r * cos(phi) + 0.5;
+ uv.y = r * sin(phi) + 0.5;
+ }
+ else
+ {
+ uv = fragTexCoord.xy;
+ }
+
+ gl_FragColor = texture2D(texture0, uv);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/grayscale.fs b/examples/shaders/resources/shaders/glsl120/grayscale.fs
new file mode 100644
index 00000000..4de60d22
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/grayscale.fs
@@ -0,0 +1,23 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor;
+
+ // Convert texel color to grayscale using NTSC conversion weights
+ float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));
+
+ // Calculate final fragment color
+ gl_FragColor = vec4(gray, gray, gray, texelColor.a);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/pixelizer.fs b/examples/shaders/resources/shaders/glsl120/pixelizer.fs
new file mode 100644
index 00000000..6f741faf
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/pixelizer.fs
@@ -0,0 +1,30 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
+
+float pixelWidth = 5.0;
+float pixelHeight = 5.0;
+
+void main()
+{
+ float dx = pixelWidth*(1.0/renderWidth);
+ float dy = pixelHeight*(1.0/renderHeight);
+
+ vec2 coord = vec2(dx*floor(fragTexCoord.x/dx), dy*floor(fragTexCoord.y/dy));
+
+ vec3 tc = texture2D(texture0, coord).rgb;
+
+ gl_FragColor = vec4(tc, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/posterization.fs b/examples/shaders/resources/shaders/glsl120/posterization.fs
new file mode 100644
index 00000000..475b93a1
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/posterization.fs
@@ -0,0 +1,27 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+float gamma = 0.6;
+float numColors = 8.0;
+
+void main()
+{
+ vec3 color = texture2D(texture0, fragTexCoord.xy).rgb;
+
+ color = pow(color, vec3(gamma, gamma, gamma));
+ color = color*numColors;
+ color = floor(color);
+ color = color/numColors;
+ color = pow(color, vec3(1.0/gamma));
+
+ gl_FragColor = vec4(color, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/predator.fs b/examples/shaders/resources/shaders/glsl120/predator.fs
new file mode 100644
index 00000000..2999cc8d
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/predator.fs
@@ -0,0 +1,29 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+ vec3 color = texture2D(texture0, fragTexCoord).rgb;
+ vec3 colors[3];
+ colors[0] = vec3(0.0, 0.0, 1.0);
+ colors[1] = vec3(1.0, 1.0, 0.0);
+ colors[2] = vec3(1.0, 0.0, 0.0);
+
+ float lum = (color.r + color.g + color.b)/3.0;
+
+ vec3 tc = vec3(0.0, 0.0, 0.0);
+
+ if (lum < 0.5) tc = mix(colors[0], colors[1], lum/0.5);
+ else tc = mix(colors[1], colors[2], (lum - 0.5)/0.5);
+
+ gl_FragColor = vec4(tc, 1.0);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/scanlines.fs b/examples/shaders/resources/shaders/glsl120/scanlines.fs
new file mode 100644
index 00000000..929c79eb
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/scanlines.fs
@@ -0,0 +1,42 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+float offset = 0.0;
+float frequency = 450.0/3.0;
+
+uniform float time;
+
+void main()
+{
+/*
+ // Scanlines method 1
+ float tval = 0; //time
+ vec2 uv = 0.5 + (fragTexCoord - 0.5)*(0.9 + 0.01*sin(0.5*tval));
+
+ vec4 color = texture2D(texture0, fragTexCoord);
+
+ color = clamp(color*0.5 + 0.5*color*color*1.2, 0.0, 1.0);
+ color *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0 - uv.x)*(1.0 - uv.y);
+ color *= vec4(0.8, 1.0, 0.7, 1);
+ color *= 0.9 + 0.1*sin(10.0*tval + uv.y*1000.0);
+ color *= 0.97 + 0.03*sin(110.0*tval);
+
+ fragColor = color;
+*/
+ // Scanlines method 2
+ float globalPos = (fragTexCoord.y + offset) * frequency;
+ float wavePos = cos((fract(globalPos) - 0.5)*3.14);
+
+ vec4 color = texture2D(texture0, fragTexCoord);
+
+ gl_FragColor = mix(vec4(0.0, 0.3, 0.0, 0.0), color, wavePos);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/sobel.fs b/examples/shaders/resources/shaders/glsl120/sobel.fs
new file mode 100644
index 00000000..a3f3f2bf
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/sobel.fs
@@ -0,0 +1,38 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+vec2 resolution = vec2(800.0, 450.0);
+
+void main()
+{
+ float x = 1.0/resolution.x;
+ float y = 1.0/resolution.y;
+
+ vec4 horizEdge = vec4(0.0);
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
+
+ vec4 vertEdge = vec4(0.0);
+ vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
+ vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0;
+ vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
+ vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
+ vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0;
+ vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
+
+ vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb));
+
+ gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a);
+} \ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/swirl.fs b/examples/shaders/resources/shaders/glsl120/swirl.fs
new file mode 100644
index 00000000..0618e013
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/swirl.fs
@@ -0,0 +1,44 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+// NOTE: Render size values should be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
+
+float radius = 250.0;
+float angle = 0.8;
+
+uniform vec2 center;
+
+void main()
+{
+ vec2 texSize = vec2(renderWidth, renderHeight);
+ vec2 tc = fragTexCoord*texSize;
+ tc -= center;
+
+ float dist = length(tc);
+
+ if (dist < radius)
+ {
+ float percent = (radius - dist)/radius;
+ float theta = percent*percent*angle*8.0;
+ float s = sin(theta);
+ float c = cos(theta);
+
+ tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
+ }
+
+ tc += center;
+ vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;;
+
+ gl_FragColor = vec4(color.rgb, 1.0);;
+} \ No newline at end of file
diff --git a/examples/shaders/shaders_postprocessing.c b/examples/shaders/shaders_postprocessing.c
index 4aac5f91..b8b5f6ae 100644
--- a/examples/shaders/shaders_postprocessing.c
+++ b/examples/shaders/shaders_postprocessing.c
@@ -20,10 +20,8 @@
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
- #define DEFAULT_VERTEX_SHADER "resources/shaders/glsl330/base.vs"
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
- #define DEFAULT_VERTEX_SHADER "resources/shaders/glsl100/base.vs"
#endif
#define MAX_POSTPRO_SHADERS 12
@@ -85,18 +83,19 @@ int main()
// NOTE 2: We load the correct shader depending on GLSL version
Shader shaders[MAX_POSTPRO_SHADERS];
- shaders[FX_GRAYSCALE] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
- shaders[FX_POSTERIZATION] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION));
- shaders[FX_DREAM_VISION] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/dream_vision.fs", GLSL_VERSION));
- shaders[FX_PIXELIZER] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/pixelizer.fs", GLSL_VERSION));
- shaders[FX_CROSS_HATCHING] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/cross_hatching.fs", GLSL_VERSION));
- shaders[FX_CROSS_STITCHING] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/cross_stitching.fs", GLSL_VERSION));
- shaders[FX_PREDATOR_VIEW] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/predator.fs", GLSL_VERSION));
- shaders[FX_SCANLINES] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/scanlines.fs", GLSL_VERSION));
- shaders[FX_FISHEYE] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/fisheye.fs", GLSL_VERSION));
- shaders[FX_SOBEL] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION));
- shaders[FX_BLOOM] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION));
- shaders[FX_BLUR] = LoadShader(DEFAULT_VERTEX_SHADER, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION));
+ // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
+ shaders[FX_GRAYSCALE] = LoadShader(0, FormatText("resources/shaders/glsl%i/grayscale.fs", GLSL_VERSION));
+ shaders[FX_POSTERIZATION] = LoadShader(0, FormatText("resources/shaders/glsl%i/posterization.fs", GLSL_VERSION));
+ shaders[FX_DREAM_VISION] = LoadShader(0, FormatText("resources/shaders/glsl%i/dream_vision.fs", GLSL_VERSION));
+ shaders[FX_PIXELIZER] = LoadShader(0, FormatText("resources/shaders/glsl%i/pixelizer.fs", GLSL_VERSION));
+ shaders[FX_CROSS_HATCHING] = LoadShader(0, FormatText("resources/shaders/glsl%i/cross_hatching.fs", GLSL_VERSION));
+ shaders[FX_CROSS_STITCHING] = LoadShader(0, FormatText("resources/shaders/glsl%i/cross_stitching.fs", GLSL_VERSION));
+ shaders[FX_PREDATOR_VIEW] = LoadShader(0, FormatText("resources/shaders/glsl%i/predator.fs", GLSL_VERSION));
+ shaders[FX_SCANLINES] = LoadShader(0, FormatText("resources/shaders/glsl%i/scanlines.fs", GLSL_VERSION));
+ shaders[FX_FISHEYE] = LoadShader(0, FormatText("resources/shaders/glsl%i/fisheye.fs", GLSL_VERSION));
+ shaders[FX_SOBEL] = LoadShader(0, FormatText("resources/shaders/glsl%i/sobel.fs", GLSL_VERSION));
+ shaders[FX_BLOOM] = LoadShader(0, FormatText("resources/shaders/glsl%i/bloom.fs", GLSL_VERSION));
+ shaders[FX_BLUR] = LoadShader(0, FormatText("resources/shaders/glsl%i/blur.fs", GLSL_VERSION));
int currentShader = FX_GRAYSCALE;
@@ -177,4 +176,4 @@ int main()
//--------------------------------------------------------------------------------------
return 0;
-} \ No newline at end of file
+}
diff --git a/examples/text/text_ttf_loading.c b/examples/text/text_ttf_loading.c
index c9c2fb27..fedfbfb8 100644
--- a/examples/text/text_ttf_loading.c
+++ b/examples/text/text_ttf_loading.c
@@ -32,7 +32,7 @@ int main()
GenTextureMipmaps(&font.texture);
float fontSize = font.baseSize;
- Vector2 fontPosition = { 40, screenHeight/2 + 50 };
+ Vector2 fontPosition = { 40, screenHeight/2 - 50 };
Vector2 textSize;
SetTextureFilter(font.texture, FILTER_POINT);
diff --git a/examples/textures/resources/KAISG.ttf b/examples/textures/resources/KAISG.ttf
new file mode 100644
index 00000000..04478b25
--- /dev/null
+++ b/examples/textures/resources/KAISG.ttf
Binary files differ
diff --git a/examples/textures/textures_image_text.c b/examples/textures/textures_image_text.c
new file mode 100644
index 00000000..1d4231f7
--- /dev/null
+++ b/examples/textures/textures_image_text.c
@@ -0,0 +1,83 @@
+/*******************************************************************************************
+*
+* raylib [texture] example - Image text drawing using TTF generated spritefont
+*
+* This example has been created using raylib 1.8 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2017 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
+
+ // TTF SpriteFont loading with custom generation parameters
+ SpriteFont font = LoadSpriteFontEx("resources/KAISG.ttf", 64, 0, 0);
+
+ Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
+
+ // Draw over image using custom font
+ ImageDrawTextEx(&parrots, (Vector2){ 20, 20 }, font, "[Parrots font drawing]", font.baseSize, 0, WHITE);
+
+ Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
+ UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
+
+ Vector2 position = { screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 20 };
+
+ bool showFont = false;
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ if (IsKeyDown(KEY_SPACE)) showFont = true;
+ else showFont = false;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ if (!showFont)
+ {
+ // Draw texture with text already drawn inside
+ DrawTextureV(texture, position, WHITE);
+
+ // Draw text directly using sprite font
+ DrawTextEx(font, "[Parrots font drawing]", (Vector2){ position.x + 20,
+ position.y + 20 + 280 }, font.baseSize, 0, WHITE);
+ }
+ else DrawTexture(font.texture, screenWidth/2 - font.texture.width/2, 50, BLACK);
+
+ DrawText("PRESS SPACE to SEE USED SPRITEFONT ", 290, 420, 10, DARKGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(texture); // Texture unloading
+
+ UnloadSpriteFont(font); // Unload custom spritefont
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/examples/textures/textures_image_text.png b/examples/textures/textures_image_text.png
new file mode 100644
index 00000000..dafbabfb
--- /dev/null
+++ b/examples/textures/textures_image_text.png
Binary files differ
diff --git a/games/koala_seasons/Makefile b/games/koala_seasons/Makefile
index 90676e35..3ca03a48 100644
--- a/games/koala_seasons/Makefile
+++ b/games/koala_seasons/Makefile
@@ -151,7 +151,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
- CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s TOTAL_MEMORY=16777216 --preload-file resources
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling -s ALLOW_MEMORY_GROWTH=1 --preload-file resources
endif
# Define include paths for required headers
@@ -218,7 +218,7 @@ endif
ifeq ($(PLATFORM_OS),WINDOWS)
# resources file contains raylib icon for windows .exe
# -Wl,--subsystem,windows hides the console window
- CFLAGS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
+ LDLIBS += $(RAYLIB_PATH)/src/resources -Wl,--subsystem,windows
endif
# Define output extension to generate a .html file using provided shell
@@ -253,7 +253,7 @@ all:
# Project target defined by PROJECT_NAME
$(PROJECT_NAME): $(OBJS)
- $(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+ $(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(WEB_SHELL)
# Compile source files
# NOTE: This pattern will compile every module defined on $(OBJS)
diff --git a/games/koala_seasons/resources/graphics/atlas02.png b/games/koala_seasons/resources/graphics/atlas02.png
index c9c96d2d..c9437059 100644
--- a/games/koala_seasons/resources/graphics/atlas02.png
+++ b/games/koala_seasons/resources/graphics/atlas02.png
Binary files differ
diff --git a/games/koala_seasons/resources/shaders/glsl100/base.vs b/games/koala_seasons/resources/shaders/glsl100/base.vs
index b05d3463..93e8c860 100644
--- a/games/koala_seasons/resources/shaders/glsl100/base.vs
+++ b/games/koala_seasons/resources/shaders/glsl100/base.vs
@@ -6,7 +6,7 @@ attribute vec2 vertexTexCoord;
attribute vec4 vertexColor;
// Input uniform values
-uniform mat4 mvpMatrix;
+uniform mat4 mvp;
// Output vertex attributes (to fragment shader)
varying vec2 fragTexCoord;
@@ -21,5 +21,5 @@ void main()
fragColor = vertexColor;
// Calculate final vertex position
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
} \ No newline at end of file
diff --git a/games/koala_seasons/screens/screen_title.c b/games/koala_seasons/screens/screen_title.c
index fd166196..0459906d 100644
--- a/games/koala_seasons/screens/screen_title.c
+++ b/games/koala_seasons/screens/screen_title.c
@@ -858,8 +858,8 @@ void DrawTitleScreen(void)
DrawTexturePro(atlas02, gameplay_background, (Rectangle){0, 0, gameplay_background.width*2, gameplay_background.height*2}, (Vector2){0, 0}, 0, color02);
// Draw parallax
- //DrawParallaxBack();
- //DrawParallaxMiddle();
+ DrawParallaxBack();
+ DrawParallaxMiddle();
for (int i = 0; i < MAX_particle; i++)
{
@@ -984,8 +984,6 @@ void DrawTitleScreen(void)
if (musicActive)DrawTexturePro(atlas01, title_speaker_on, (Rectangle){speakerButton.x, speakerButton.y, title_speaker_on.width, title_speaker_on.height}, (Vector2){0,0}, 0, WHITE);
else DrawTexturePro(atlas01, title_speaker_off, (Rectangle){speakerButton.x, speakerButton.y, title_speaker_off.width, title_speaker_off.height}, (Vector2){0,0}, 0, WHITE);
*/
-
- DrawParallaxFront();
}
// Title Screen Unload logic
@@ -1003,10 +1001,7 @@ int FinishTitleScreen(void)
static void DrawParallaxFront(void)
{
Rectangle ground01 = gameplay_back_ground01;
-
- DrawTexturePro(atlas02, gameplay_back_tree01_layer01, (Rectangle){0, 0, gameplay_back_tree01_layer01.width*2, gameplay_back_tree01_layer01.height*2}, (Vector2){0,0}, 0, WHITE);
- /*
//DrawTexturePro(atlas02, gameplay_back_tree01_layer03, (Rectangle){0, 21, gameplay_back_tree01_layer03.width*2, gameplay_back_tree01_layer03.height*2}, (Vector2){0,0}, 0, color02);
DrawTexturePro(atlas02, gameplay_back_tree01_layer01, (Rectangle){(int)parallaxFrontOffset, 60, gameplay_back_tree01_layer01.width*2, gameplay_back_tree01_layer01.height*2}, (Vector2){0,0}, 0, color02);
DrawTexturePro(atlas02, gameplay_back_tree02_layer01, (Rectangle){(int)parallaxFrontOffset + 140, 60, gameplay_back_tree02_layer01.width*2, gameplay_back_tree02_layer01.height*2}, (Vector2){0,0}, 0, color02);
@@ -1018,7 +1013,6 @@ static void DrawParallaxFront(void)
DrawTexturePro(atlas02, gameplay_back_tree08_layer01, (Rectangle){(int)parallaxFrontOffset + 140*7, 60, gameplay_back_tree08_layer01.width*2, gameplay_back_tree08_layer01.height*2}, (Vector2){0,0}, 0, color02);
DrawTexturePro(atlas02, gameplay_back_ground01, (Rectangle){0, 559, ground01.width*2, ground01.height*2}, (Vector2){0,0}, 0, color01);
DrawTexturePro(atlas02, (Rectangle){ground01.x, ground01.y + ground01.height, ground01.width, -ground01.height}, (Rectangle){0, -33, ground01.width*2, ground01.height*2}, (Vector2){0,0}, 0, color01);
- */
}
static void DrawParallaxMiddle(void)
diff --git a/games/wave_collector/wave_collector.c b/games/wave_collector/wave_collector.c
index d4ce33d9..e28c0b84 100644
--- a/games/wave_collector/wave_collector.c
+++ b/games/wave_collector/wave_collector.c
@@ -63,7 +63,7 @@ static void UpdateDrawFrame(void); // Update and Draw one frame
#if defined(PLATFORM_ANDROID)
void android_main(struct android_app *app)
#else
-int main(void)
+int main(int argc, char *argv[])
#endif
{
// Initialization
@@ -315,4 +315,4 @@ static void UpdateDrawFrame(void)
EndDrawing();
//----------------------------------------------------------------------------------
-} \ No newline at end of file
+}
diff --git a/project/vs2015/examples/core_basic_window.vcxproj b/project/vs2015/examples/core_basic_window.vcxproj
index 2e8ed67f..9a8fefdb 100644
--- a/project/vs2015/examples/core_basic_window.vcxproj
+++ b/project/vs2015/examples/core_basic_window.vcxproj
@@ -61,12 +61,12 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalLibraryDirectories>$(SolutionDir)external\glfw3\lib\win32;$(SolutionDir)external\openal_soft\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
@@ -79,7 +79,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
@@ -89,7 +89,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(SolutionDir)external\glfw3\lib\win32;$(SolutionDir)external\openal_soft\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/project/vs2015/examples/core_basic_window_cpp.vcxproj b/project/vs2015/examples/core_basic_window_cpp.vcxproj
index 49c21228..71eb50f2 100644
--- a/project/vs2015/examples/core_basic_window_cpp.vcxproj
+++ b/project/vs2015/examples/core_basic_window_cpp.vcxproj
@@ -60,14 +60,14 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>$(SolutionDir)external\glfw3\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -80,14 +80,14 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsCpp</CompileAs>
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalLibraryDirectories>$(SolutionDir)external\glfw3\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
diff --git a/project/vs2015/external/glfw3/include/GLFW/glfw3native.h b/project/vs2015/external/glfw3/include/GLFW/glfw3native.h
deleted file mode 100644
index 30e1a570..00000000
--- a/project/vs2015/external/glfw3/include/GLFW/glfw3native.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/*************************************************************************
- * GLFW 3.2 - www.glfw.org
- * A library for OpenGL, window and input
- *------------------------------------------------------------------------
- * Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
- *
- * 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.
- *
- *************************************************************************/
-
-#ifndef _glfw3_native_h_
-#define _glfw3_native_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*************************************************************************
- * Doxygen documentation
- *************************************************************************/
-
-/*! @file glfw3native.h
- * @brief The header of the native access functions.
- *
- * This is the header file of the native access functions. See @ref native for
- * more information.
- */
-/*! @defgroup native Native access
- *
- * **By using the native access functions you assert that you know what you're
- * doing and how to fix problems caused by using them. If you don't, you
- * shouldn't be using them.**
- *
- * Before the inclusion of @ref glfw3native.h, you may define exactly one
- * window system API macro and zero or more context creation API macros.
- *
- * The chosen backends must match those the library was compiled for. Failure
- * to do this will cause a link-time error.
- *
- * The available window API macros are:
- * * `GLFW_EXPOSE_NATIVE_WIN32`
- * * `GLFW_EXPOSE_NATIVE_COCOA`
- * * `GLFW_EXPOSE_NATIVE_X11`
- * * `GLFW_EXPOSE_NATIVE_WAYLAND`
- * * `GLFW_EXPOSE_NATIVE_MIR`
- *
- * The available context API macros are:
- * * `GLFW_EXPOSE_NATIVE_WGL`
- * * `GLFW_EXPOSE_NATIVE_NSGL`
- * * `GLFW_EXPOSE_NATIVE_GLX`
- * * `GLFW_EXPOSE_NATIVE_EGL`
- *
- * These macros select which of the native access functions that are declared
- * and which platform-specific headers to include. It is then up your (by
- * definition platform-specific) code to handle which of these should be
- * defined.
- */
-
-
-/*************************************************************************
- * System headers and types
- *************************************************************************/
-
-#if defined(GLFW_EXPOSE_NATIVE_WIN32)
- // 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
- #undef APIENTRY
- #include <windows.h>
-#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
- #include <ApplicationServices/ApplicationServices.h>
- #if defined(__OBJC__)
- #import <Cocoa/Cocoa.h>
- #else
- typedef void* id;
- #endif
-#elif defined(GLFW_EXPOSE_NATIVE_X11)
- #include <X11/Xlib.h>
- #include <X11/extensions/Xrandr.h>
-#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
- #include <wayland-client.h>
-#elif defined(GLFW_EXPOSE_NATIVE_MIR)
- #include <mir_toolkit/mir_client_library.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)
- #include <GL/glx.h>
-#endif
-#if defined(GLFW_EXPOSE_NATIVE_EGL)
- #include <EGL/egl.h>
-#endif
-
-
-/*************************************************************************
- * Functions
- *************************************************************************/
-
-#if defined(GLFW_EXPOSE_NATIVE_WIN32)
-/*! @brief Returns the adapter device name of the specified monitor.
- *
- * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
- * of the specified monitor, or `NULL` if an [error](@ref error_handling)
- * occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
-
-/*! @brief Returns the display device name of the specified monitor.
- *
- * @return The UTF-8 encoded display device name (for example
- * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `HWND` of the specified window.
- *
- * @return The `HWND` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_WGL)
-/*! @brief Returns the `HGLRC` of the specified window.
- *
- * @return The `HGLRC` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_COCOA)
-/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
- *
- * @return The `CGDirectDisplayID` of the specified monitor, or
- * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `NSWindow` of the specified window.
- *
- * @return The `NSWindow` of the specified window, or `nil` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_NSGL)
-/*! @brief Returns the `NSOpenGLContext` of the specified window.
- *
- * @return The `NSOpenGLContext` of the specified window, or `nil` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_X11)
-/*! @brief Returns the `Display` used by GLFW.
- *
- * @return The `Display` used by GLFW, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI Display* glfwGetX11Display(void);
-
-/*! @brief Returns the `RRCrtc` of the specified monitor.
- *
- * @return The `RRCrtc` of the specified monitor, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
-
-/*! @brief Returns the `RROutput` of the specified monitor.
- *
- * @return The `RROutput` of the specified monitor, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.1.
- *
- * @ingroup native
- */
-GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `Window` of the specified window.
- *
- * @return The `Window` of the specified window, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_GLX)
-/*! @brief Returns the `GLXContext` of the specified window.
- *
- * @return The `GLXContext` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
-
-/*! @brief Returns the `GLXWindow` of the specified window.
- *
- * @return The `GLXWindow` of the specified window, or `None` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
-/*! @brief Returns the `struct wl_display*` used by GLFW.
- *
- * @return The `struct wl_display*` used by GLFW, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
-
-/*! @brief Returns the `struct wl_output*` of the specified monitor.
- *
- * @return The `struct wl_output*` of the specified monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the main `struct wl_surface*` of the specified window.
- *
- * @return The main `struct wl_surface*` of the specified window, or `NULL` if
- * an [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_MIR)
-/*! @brief Returns the `MirConnection*` used by GLFW.
- *
- * @return The `MirConnection*` used by GLFW, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI MirConnection* glfwGetMirDisplay(void);
-
-/*! @brief Returns the Mir output ID of the specified monitor.
- *
- * @return The Mir output ID of the specified monitor, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
-
-/*! @brief Returns the `MirSurface*` of the specified window.
- *
- * @return The `MirSurface*` of the specified window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.2.
- *
- * @ingroup native
- */
-GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
-#endif
-
-#if defined(GLFW_EXPOSE_NATIVE_EGL)
-/*! @brief Returns the `EGLDisplay` used by GLFW.
- *
- * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
-
-/*! @brief Returns the `EGLContext` of the specified window.
- *
- * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
-
-/*! @brief Returns the `EGLSurface` of the specified window.
- *
- * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
- * [error](@ref error_handling) occurred.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @since Added in version 3.0.
- *
- * @ingroup native
- */
-GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _glfw3_native_h_ */
-
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3.dll b/project/vs2015/external/glfw3/lib/win32/glfw3.dll
deleted file mode 100644
index 3e2a7f35..00000000
--- a/project/vs2015/external/glfw3/lib/win32/glfw3.dll
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3.lib b/project/vs2015/external/glfw3/lib/win32/glfw3.lib
deleted file mode 100644
index bec8cfc9..00000000
--- a/project/vs2015/external/glfw3/lib/win32/glfw3.lib
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib b/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib
deleted file mode 100644
index 8e87d64a..00000000
--- a/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/external/openal_soft/COPYING b/project/vs2015/external/openal_soft/COPYING
deleted file mode 100644
index d0c89786..00000000
--- a/project/vs2015/external/openal_soft/COPYING
+++ /dev/null
@@ -1,484 +0,0 @@
-
- GNU LIBRARY GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
-
- Copyright (C) 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL. It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it. You can use it for
-your libraries, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
- Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library. If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software. To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
- Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs. This
-license, the GNU Library General Public License, applies to certain
-designated libraries. This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
- The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it. Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program. However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
- Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries. We
-concluded that weaker conditions might promote sharing better.
-
- However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves. This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them. (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.) The hope is that this
-will lead to faster development of free libraries.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, while the latter only
-works together with the library.
-
- Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
- GNU LIBRARY GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License"). Each licensee is
-addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- c) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- d) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
diff --git a/project/vs2015/external/openal_soft/include/AL/al.h b/project/vs2015/external/openal_soft/include/AL/al.h
deleted file mode 100644
index 413b3833..00000000
--- a/project/vs2015/external/openal_soft/include/AL/al.h
+++ /dev/null
@@ -1,656 +0,0 @@
-#ifndef AL_AL_H
-#define AL_AL_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#ifndef AL_API
- #if defined(AL_LIBTYPE_STATIC)
- #define AL_API
- #elif defined(_WIN32)
- #define AL_API __declspec(dllimport)
- #else
- #define AL_API extern
- #endif
-#endif
-
-#if defined(_WIN32)
- #define AL_APIENTRY __cdecl
-#else
- #define AL_APIENTRY
-#endif
-
-
-/** Deprecated macro. */
-#define OPENAL
-#define ALAPI AL_API
-#define ALAPIENTRY AL_APIENTRY
-#define AL_INVALID (-1)
-#define AL_ILLEGAL_ENUM AL_INVALID_ENUM
-#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
-
-/** Supported AL version. */
-#define AL_VERSION_1_0
-#define AL_VERSION_1_1
-
-/** 8-bit boolean */
-typedef char ALboolean;
-
-/** character */
-typedef char ALchar;
-
-/** signed 8-bit 2's complement integer */
-typedef signed char ALbyte;
-
-/** unsigned 8-bit integer */
-typedef unsigned char ALubyte;
-
-/** signed 16-bit 2's complement integer */
-typedef short ALshort;
-
-/** unsigned 16-bit integer */
-typedef unsigned short ALushort;
-
-/** signed 32-bit 2's complement integer */
-typedef int ALint;
-
-/** unsigned 32-bit integer */
-typedef unsigned int ALuint;
-
-/** non-negative 32-bit binary integer size */
-typedef int ALsizei;
-
-/** enumerated 32-bit value */
-typedef int ALenum;
-
-/** 32-bit IEEE754 floating-point */
-typedef float ALfloat;
-
-/** 64-bit IEEE754 floating-point */
-typedef double ALdouble;
-
-/** void type (for opaque pointers only) */
-typedef void ALvoid;
-
-
-/* Enumerant values begin at column 50. No tabs. */
-
-/** "no distance model" or "no buffer" */
-#define AL_NONE 0
-
-/** Boolean False. */
-#define AL_FALSE 0
-
-/** Boolean True. */
-#define AL_TRUE 1
-
-
-/**
- * Relative source.
- * Type: ALboolean
- * Range: [AL_TRUE, AL_FALSE]
- * Default: AL_FALSE
- *
- * Specifies if the Source has relative coordinates.
- */
-#define AL_SOURCE_RELATIVE 0x202
-
-
-/**
- * Inner cone angle, in degrees.
- * Type: ALint, ALfloat
- * Range: [0 - 360]
- * Default: 360
- *
- * The angle covered by the inner cone, where the source will not attenuate.
- */
-#define AL_CONE_INNER_ANGLE 0x1001
-
-/**
- * Outer cone angle, in degrees.
- * Range: [0 - 360]
- * Default: 360
- *
- * The angle covered by the outer cone, where the source will be fully
- * attenuated.
- */
-#define AL_CONE_OUTER_ANGLE 0x1002
-
-/**
- * Source pitch.
- * Type: ALfloat
- * Range: [0.5 - 2.0]
- * Default: 1.0
- *
- * A multiplier for the frequency (sample rate) of the source's buffer.
- */
-#define AL_PITCH 0x1003
-
-/**
- * Source or listener position.
- * Type: ALfloat[3], ALint[3]
- * Default: {0, 0, 0}
- *
- * The source or listener location in three dimensional space.
- *
- * OpenAL, like OpenGL, uses a right handed coordinate system, where in a
- * frontal default view X (thumb) points right, Y points up (index finger), and
- * Z points towards the viewer/camera (middle finger).
- *
- * To switch from a left handed coordinate system, flip the sign on the Z
- * coordinate.
- */
-#define AL_POSITION 0x1004
-
-/**
- * Source direction.
- * Type: ALfloat[3], ALint[3]
- * Default: {0, 0, 0}
- *
- * Specifies the current direction in local space.
- * A zero-length vector specifies an omni-directional source (cone is ignored).
- */
-#define AL_DIRECTION 0x1005
-
-/**
- * Source or listener velocity.
- * Type: ALfloat[3], ALint[3]
- * Default: {0, 0, 0}
- *
- * Specifies the current velocity in local space.
- */
-#define AL_VELOCITY 0x1006
-
-/**
- * Source looping.
- * Type: ALboolean
- * Range: [AL_TRUE, AL_FALSE]
- * Default: AL_FALSE
- *
- * Specifies whether source is looping.
- */
-#define AL_LOOPING 0x1007
-
-/**
- * Source buffer.
- * Type: ALuint
- * Range: any valid Buffer.
- *
- * Specifies the buffer to provide sound samples.
- */
-#define AL_BUFFER 0x1009
-
-/**
- * Source or listener gain.
- * Type: ALfloat
- * Range: [0.0 - ]
- *
- * A value of 1.0 means unattenuated. Each division by 2 equals an attenuation
- * of about -6dB. Each multiplicaton by 2 equals an amplification of about
- * +6dB.
- *
- * A value of 0.0 is meaningless with respect to a logarithmic scale; it is
- * silent.
- */
-#define AL_GAIN 0x100A
-
-/**
- * Minimum source gain.
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- *
- * The minimum gain allowed for a source, after distance and cone attenation is
- * applied (if applicable).
- */
-#define AL_MIN_GAIN 0x100D
-
-/**
- * Maximum source gain.
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- *
- * The maximum gain allowed for a source, after distance and cone attenation is
- * applied (if applicable).
- */
-#define AL_MAX_GAIN 0x100E
-
-/**
- * Listener orientation.
- * Type: ALfloat[6]
- * Default: {0.0, 0.0, -1.0, 0.0, 1.0, 0.0}
- *
- * Effectively two three dimensional vectors. The first vector is the front (or
- * "at") and the second is the top (or "up").
- *
- * Both vectors are in local space.
- */
-#define AL_ORIENTATION 0x100F
-
-/**
- * Source state (query only).
- * Type: ALint
- * Range: [AL_INITIAL, AL_PLAYING, AL_PAUSED, AL_STOPPED]
- */
-#define AL_SOURCE_STATE 0x1010
-
-/** Source state value. */
-#define AL_INITIAL 0x1011
-#define AL_PLAYING 0x1012
-#define AL_PAUSED 0x1013
-#define AL_STOPPED 0x1014
-
-/**
- * Source Buffer Queue size (query only).
- * Type: ALint
- *
- * The number of buffers queued using alSourceQueueBuffers, minus the buffers
- * removed with alSourceUnqueueBuffers.
- */
-#define AL_BUFFERS_QUEUED 0x1015
-
-/**
- * Source Buffer Queue processed count (query only).
- * Type: ALint
- *
- * The number of queued buffers that have been fully processed, and can be
- * removed with alSourceUnqueueBuffers.
- *
- * Looping sources will never fully process buffers because they will be set to
- * play again for when the source loops.
- */
-#define AL_BUFFERS_PROCESSED 0x1016
-
-/**
- * Source reference distance.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: 1.0
- *
- * The distance in units that no attenuation occurs.
- *
- * At 0.0, no distance attenuation ever occurs on non-linear attenuation models.
- */
-#define AL_REFERENCE_DISTANCE 0x1020
-
-/**
- * Source rolloff factor.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: 1.0
- *
- * Multiplier to exaggerate or diminish distance attenuation.
- *
- * At 0.0, no distance attenuation ever occurs.
- */
-#define AL_ROLLOFF_FACTOR 0x1021
-
-/**
- * Outer cone gain.
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- * Default: 0.0
- *
- * The gain attenuation applied when the listener is outside of the source's
- * outer cone.
- */
-#define AL_CONE_OUTER_GAIN 0x1022
-
-/**
- * Source maximum distance.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: +inf
- *
- * The distance above which the source is not attenuated any further with a
- * clamped distance model, or where attenuation reaches 0.0 gain for linear
- * distance models with a default rolloff factor.
- */
-#define AL_MAX_DISTANCE 0x1023
-
-/** Source buffer position, in seconds */
-#define AL_SEC_OFFSET 0x1024
-/** Source buffer position, in sample frames */
-#define AL_SAMPLE_OFFSET 0x1025
-/** Source buffer position, in bytes */
-#define AL_BYTE_OFFSET 0x1026
-
-/**
- * Source type (query only).
- * Type: ALint
- * Range: [AL_STATIC, AL_STREAMING, AL_UNDETERMINED]
- *
- * A Source is Static if a Buffer has been attached using AL_BUFFER.
- *
- * A Source is Streaming if one or more Buffers have been attached using
- * alSourceQueueBuffers.
- *
- * A Source is Undetermined when it has the NULL buffer attached using
- * AL_BUFFER.
- */
-#define AL_SOURCE_TYPE 0x1027
-
-/** Source type value. */
-#define AL_STATIC 0x1028
-#define AL_STREAMING 0x1029
-#define AL_UNDETERMINED 0x1030
-
-/** Buffer format specifier. */
-#define AL_FORMAT_MONO8 0x1100
-#define AL_FORMAT_MONO16 0x1101
-#define AL_FORMAT_STEREO8 0x1102
-#define AL_FORMAT_STEREO16 0x1103
-
-/** Buffer frequency (query only). */
-#define AL_FREQUENCY 0x2001
-/** Buffer bits per sample (query only). */
-#define AL_BITS 0x2002
-/** Buffer channel count (query only). */
-#define AL_CHANNELS 0x2003
-/** Buffer data size (query only). */
-#define AL_SIZE 0x2004
-
-/**
- * Buffer state.
- *
- * Not for public use.
- */
-#define AL_UNUSED 0x2010
-#define AL_PENDING 0x2011
-#define AL_PROCESSED 0x2012
-
-
-/** No error. */
-#define AL_NO_ERROR 0
-
-/** Invalid name paramater passed to AL call. */
-#define AL_INVALID_NAME 0xA001
-
-/** Invalid enum parameter passed to AL call. */
-#define AL_INVALID_ENUM 0xA002
-
-/** Invalid value parameter passed to AL call. */
-#define AL_INVALID_VALUE 0xA003
-
-/** Illegal AL call. */
-#define AL_INVALID_OPERATION 0xA004
-
-/** Not enough memory. */
-#define AL_OUT_OF_MEMORY 0xA005
-
-
-/** Context string: Vendor ID. */
-#define AL_VENDOR 0xB001
-/** Context string: Version. */
-#define AL_VERSION 0xB002
-/** Context string: Renderer ID. */
-#define AL_RENDERER 0xB003
-/** Context string: Space-separated extension list. */
-#define AL_EXTENSIONS 0xB004
-
-
-/**
- * Doppler scale.
- * Type: ALfloat
- * Range: [0.0 - ]
- * Default: 1.0
- *
- * Scale for source and listener velocities.
- */
-#define AL_DOPPLER_FACTOR 0xC000
-AL_API void AL_APIENTRY alDopplerFactor(ALfloat value);
-
-/**
- * Doppler velocity (deprecated).
- *
- * A multiplier applied to the Speed of Sound.
- */
-#define AL_DOPPLER_VELOCITY 0xC001
-AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value);
-
-/**
- * Speed of Sound, in units per second.
- * Type: ALfloat
- * Range: [0.0001 - ]
- * Default: 343.3
- *
- * The speed at which sound waves are assumed to travel, when calculating the
- * doppler effect.
- */
-#define AL_SPEED_OF_SOUND 0xC003
-AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value);
-
-/**
- * Distance attenuation model.
- * Type: ALint
- * Range: [AL_NONE, AL_INVERSE_DISTANCE, AL_INVERSE_DISTANCE_CLAMPED,
- * AL_LINEAR_DISTANCE, AL_LINEAR_DISTANCE_CLAMPED,
- * AL_EXPONENT_DISTANCE, AL_EXPONENT_DISTANCE_CLAMPED]
- * Default: AL_INVERSE_DISTANCE_CLAMPED
- *
- * The model by which sources attenuate with distance.
- *
- * None - No distance attenuation.
- * Inverse - Doubling the distance halves the source gain.
- * Linear - Linear gain scaling between the reference and max distances.
- * Exponent - Exponential gain dropoff.
- *
- * Clamped variations work like the non-clamped counterparts, except the
- * distance calculated is clamped between the reference and max distances.
- */
-#define AL_DISTANCE_MODEL 0xD000
-AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel);
-
-/** Distance model value. */
-#define AL_INVERSE_DISTANCE 0xD001
-#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
-#define AL_LINEAR_DISTANCE 0xD003
-#define AL_LINEAR_DISTANCE_CLAMPED 0xD004
-#define AL_EXPONENT_DISTANCE 0xD005
-#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
-
-/** Renderer State management. */
-AL_API void AL_APIENTRY alEnable(ALenum capability);
-AL_API void AL_APIENTRY alDisable(ALenum capability);
-AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability);
-
-/** State retrieval. */
-AL_API const ALchar* AL_APIENTRY alGetString(ALenum param);
-AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values);
-AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values);
-AL_API void AL_APIENTRY alGetFloatv(ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetDoublev(ALenum param, ALdouble *values);
-AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum param);
-AL_API ALint AL_APIENTRY alGetInteger(ALenum param);
-AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param);
-AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param);
-
-/**
- * Error retrieval.
- *
- * Obtain the first error generated in the AL context since the last check.
- */
-AL_API ALenum AL_APIENTRY alGetError(void);
-
-/**
- * Extension support.
- *
- * Query for the presence of an extension, and obtain any appropriate function
- * pointers and enum values.
- */
-AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname);
-AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname);
-AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename);
-
-
-/** Set Listener parameters */
-AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value);
-AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values);
-AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value);
-AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3);
-AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values);
-
-/** Get Listener parameters */
-AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value);
-AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value);
-AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3);
-AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint *values);
-
-
-/** Create Source objects. */
-AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources);
-/** Delete Source objects. */
-AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources);
-/** Verify a handle is a valid Source. */
-AL_API ALboolean AL_APIENTRY alIsSource(ALuint source);
-
-/** Set Source parameters. */
-AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value);
-AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values);
-AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value);
-AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
-AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values);
-
-/** Get Source parameters. */
-AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value);
-AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value);
-AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values);
-
-
-/** Play, replay, or resume (if paused) a list of Sources */
-AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources);
-/** Stop a list of Sources */
-AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources);
-/** Rewind a list of Sources */
-AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources);
-/** Pause a list of Sources */
-AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources);
-
-/** Play, replay, or resume a Source */
-AL_API void AL_APIENTRY alSourcePlay(ALuint source);
-/** Stop a Source */
-AL_API void AL_APIENTRY alSourceStop(ALuint source);
-/** Rewind a Source (set playback postiton to beginning) */
-AL_API void AL_APIENTRY alSourceRewind(ALuint source);
-/** Pause a Source */
-AL_API void AL_APIENTRY alSourcePause(ALuint source);
-
-/** Queue buffers onto a source */
-AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers);
-/** Unqueue processed buffers from a source */
-AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers);
-
-
-/** Create Buffer objects */
-AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers);
-/** Delete Buffer objects */
-AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers);
-/** Verify a handle is a valid Buffer */
-AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer);
-
-/** Specifies the data to be copied into a buffer */
-AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq);
-
-/** Set Buffer parameters, */
-AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value);
-AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values);
-AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value);
-AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3);
-AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values);
-
-/** Get Buffer parameters. */
-AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value);
-AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values);
-AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value);
-AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values);
-
-/** Pointer-to-function type, useful for dynamically getting AL entry points. */
-typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability);
-typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability);
-typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability);
-typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)(ALenum param);
-typedef void (AL_APIENTRY *LPALGETBOOLEANV)(ALenum param, ALboolean *values);
-typedef void (AL_APIENTRY *LPALGETINTEGERV)(ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALGETFLOATV)(ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETDOUBLEV)(ALenum param, ALdouble *values);
-typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)(ALenum param);
-typedef ALint (AL_APIENTRY *LPALGETINTEGER)(ALenum param);
-typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)(ALenum param);
-typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)(ALenum param);
-typedef ALenum (AL_APIENTRY *LPALGETERROR)(void);
-typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar *extname);
-typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)(const ALchar *fname);
-typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)(const ALchar *ename);
-typedef void (AL_APIENTRY *LPALLISTENERF)(ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALLISTENER3F)(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-typedef void (AL_APIENTRY *LPALLISTENERFV)(ALenum param, const ALfloat *values);
-typedef void (AL_APIENTRY *LPALLISTENERI)(ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALLISTENER3I)(ALenum param, ALint value1, ALint value2, ALint value3);
-typedef void (AL_APIENTRY *LPALLISTENERIV)(ALenum param, const ALint *values);
-typedef void (AL_APIENTRY *LPALGETLISTENERF)(ALenum param, ALfloat *value);
-typedef void (AL_APIENTRY *LPALGETLISTENER3F)(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-typedef void (AL_APIENTRY *LPALGETLISTENERFV)(ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETLISTENERI)(ALenum param, ALint *value);
-typedef void (AL_APIENTRY *LPALGETLISTENER3I)(ALenum param, ALint *value1, ALint *value2, ALint *value3);
-typedef void (AL_APIENTRY *LPALGETLISTENERIV)(ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALGENSOURCES)(ALsizei n, ALuint *sources);
-typedef void (AL_APIENTRY *LPALDELETESOURCES)(ALsizei n, const ALuint *sources);
-typedef ALboolean (AL_APIENTRY *LPALISSOURCE)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEF)(ALuint source, ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALSOURCE3F)(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-typedef void (AL_APIENTRY *LPALSOURCEFV)(ALuint source, ALenum param, const ALfloat *values);
-typedef void (AL_APIENTRY *LPALSOURCEI)(ALuint source, ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
-typedef void (AL_APIENTRY *LPALSOURCEIV)(ALuint source, ALenum param, const ALint *values);
-typedef void (AL_APIENTRY *LPALGETSOURCEF)(ALuint source, ALenum param, ALfloat *value);
-typedef void (AL_APIENTRY *LPALGETSOURCE3F)(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-typedef void (AL_APIENTRY *LPALGETSOURCEFV)(ALuint source, ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETSOURCEI)(ALuint source, ALenum param, ALint *value);
-typedef void (AL_APIENTRY *LPALGETSOURCE3I)(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-typedef void (AL_APIENTRY *LPALGETSOURCEIV)(ALuint source, ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALSOURCEPLAYV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCESTOPV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCEREWINDV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)(ALsizei n, const ALuint *sources);
-typedef void (AL_APIENTRY *LPALSOURCEPLAY)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCESTOP)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEREWIND)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEPAUSE)(ALuint source);
-typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint source, ALsizei nb, const ALuint *buffers);
-typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint source, ALsizei nb, ALuint *buffers);
-typedef void (AL_APIENTRY *LPALGENBUFFERS)(ALsizei n, ALuint *buffers);
-typedef void (AL_APIENTRY *LPALDELETEBUFFERS)(ALsizei n, const ALuint *buffers);
-typedef ALboolean (AL_APIENTRY *LPALISBUFFER)(ALuint buffer);
-typedef void (AL_APIENTRY *LPALBUFFERDATA)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq);
-typedef void (AL_APIENTRY *LPALBUFFERF)(ALuint buffer, ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALBUFFER3F)(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3);
-typedef void (AL_APIENTRY *LPALBUFFERFV)(ALuint buffer, ALenum param, const ALfloat *values);
-typedef void (AL_APIENTRY *LPALBUFFERI)(ALuint buffer, ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALBUFFER3I)(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3);
-typedef void (AL_APIENTRY *LPALBUFFERIV)(ALuint buffer, ALenum param, const ALint *values);
-typedef void (AL_APIENTRY *LPALGETBUFFERF)(ALuint buffer, ALenum param, ALfloat *value);
-typedef void (AL_APIENTRY *LPALGETBUFFER3F)(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3);
-typedef void (AL_APIENTRY *LPALGETBUFFERFV)(ALuint buffer, ALenum param, ALfloat *values);
-typedef void (AL_APIENTRY *LPALGETBUFFERI)(ALuint buffer, ALenum param, ALint *value);
-typedef void (AL_APIENTRY *LPALGETBUFFER3I)(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3);
-typedef void (AL_APIENTRY *LPALGETBUFFERIV)(ALuint buffer, ALenum param, ALint *values);
-typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)(ALfloat value);
-typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)(ALfloat value);
-typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)(ALfloat value);
-typedef void (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel);
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-#endif /* AL_AL_H */
diff --git a/project/vs2015/external/openal_soft/include/AL/alc.h b/project/vs2015/external/openal_soft/include/AL/alc.h
deleted file mode 100644
index 294e8b33..00000000
--- a/project/vs2015/external/openal_soft/include/AL/alc.h
+++ /dev/null
@@ -1,237 +0,0 @@
-#ifndef AL_ALC_H
-#define AL_ALC_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#ifndef ALC_API
- #if defined(AL_LIBTYPE_STATIC)
- #define ALC_API
- #elif defined(_WIN32)
- #define ALC_API __declspec(dllimport)
- #else
- #define ALC_API extern
- #endif
-#endif
-
-#if defined(_WIN32)
- #define ALC_APIENTRY __cdecl
-#else
- #define ALC_APIENTRY
-#endif
-
-
-/** Deprecated macro. */
-#define ALCAPI ALC_API
-#define ALCAPIENTRY ALC_APIENTRY
-#define ALC_INVALID 0
-
-/** Supported ALC version? */
-#define ALC_VERSION_0_1 1
-
-/** Opaque device handle */
-typedef struct ALCdevice_struct ALCdevice;
-/** Opaque context handle */
-typedef struct ALCcontext_struct ALCcontext;
-
-/** 8-bit boolean */
-typedef char ALCboolean;
-
-/** character */
-typedef char ALCchar;
-
-/** signed 8-bit 2's complement integer */
-typedef signed char ALCbyte;
-
-/** unsigned 8-bit integer */
-typedef unsigned char ALCubyte;
-
-/** signed 16-bit 2's complement integer */
-typedef short ALCshort;
-
-/** unsigned 16-bit integer */
-typedef unsigned short ALCushort;
-
-/** signed 32-bit 2's complement integer */
-typedef int ALCint;
-
-/** unsigned 32-bit integer */
-typedef unsigned int ALCuint;
-
-/** non-negative 32-bit binary integer size */
-typedef int ALCsizei;
-
-/** enumerated 32-bit value */
-typedef int ALCenum;
-
-/** 32-bit IEEE754 floating-point */
-typedef float ALCfloat;
-
-/** 64-bit IEEE754 floating-point */
-typedef double ALCdouble;
-
-/** void type (for opaque pointers only) */
-typedef void ALCvoid;
-
-
-/* Enumerant values begin at column 50. No tabs. */
-
-/** Boolean False. */
-#define ALC_FALSE 0
-
-/** Boolean True. */
-#define ALC_TRUE 1
-
-/** Context attribute: <int> Hz. */
-#define ALC_FREQUENCY 0x1007
-
-/** Context attribute: <int> Hz. */
-#define ALC_REFRESH 0x1008
-
-/** Context attribute: AL_TRUE or AL_FALSE. */
-#define ALC_SYNC 0x1009
-
-/** Context attribute: <int> requested Mono (3D) Sources. */
-#define ALC_MONO_SOURCES 0x1010
-
-/** Context attribute: <int> requested Stereo Sources. */
-#define ALC_STEREO_SOURCES 0x1011
-
-/** No error. */
-#define ALC_NO_ERROR 0
-
-/** Invalid device handle. */
-#define ALC_INVALID_DEVICE 0xA001
-
-/** Invalid context handle. */
-#define ALC_INVALID_CONTEXT 0xA002
-
-/** Invalid enum parameter passed to an ALC call. */
-#define ALC_INVALID_ENUM 0xA003
-
-/** Invalid value parameter passed to an ALC call. */
-#define ALC_INVALID_VALUE 0xA004
-
-/** Out of memory. */
-#define ALC_OUT_OF_MEMORY 0xA005
-
-
-/** Runtime ALC version. */
-#define ALC_MAJOR_VERSION 0x1000
-#define ALC_MINOR_VERSION 0x1001
-
-/** Context attribute list properties. */
-#define ALC_ATTRIBUTES_SIZE 0x1002
-#define ALC_ALL_ATTRIBUTES 0x1003
-
-/** String for the default device specifier. */
-#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
-/**
- * String for the given device's specifier.
- *
- * If device handle is NULL, it is instead a null-char separated list of
- * strings of known device specifiers (list ends with an empty string).
- */
-#define ALC_DEVICE_SPECIFIER 0x1005
-/** String for space-separated list of ALC extensions. */
-#define ALC_EXTENSIONS 0x1006
-
-
-/** Capture extension */
-#define ALC_EXT_CAPTURE 1
-/**
- * String for the given capture device's specifier.
- *
- * If device handle is NULL, it is instead a null-char separated list of
- * strings of known capture device specifiers (list ends with an empty string).
- */
-#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
-/** String for the default capture device specifier. */
-#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
-/** Number of sample frames available for capture. */
-#define ALC_CAPTURE_SAMPLES 0x312
-
-
-/** Enumerate All extension */
-#define ALC_ENUMERATE_ALL_EXT 1
-/** String for the default extended device specifier. */
-#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
-/**
- * String for the given extended device's specifier.
- *
- * If device handle is NULL, it is instead a null-char separated list of
- * strings of known extended device specifiers (list ends with an empty string).
- */
-#define ALC_ALL_DEVICES_SPECIFIER 0x1013
-
-
-/** Context management. */
-ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist);
-ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context);
-ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context);
-ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context);
-ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context);
-ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void);
-ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context);
-
-/** Device management. */
-ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename);
-ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device);
-
-
-/**
- * Error support.
- *
- * Obtain the most recent Device error.
- */
-ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device);
-
-/**
- * Extension support.
- *
- * Query for the presence of an extension, and obtain any appropriate
- * function pointers and enum values.
- */
-ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname);
-ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname);
-ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname);
-
-/** Query function. */
-ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param);
-ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
-
-/** Capture function. */
-ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
-ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
-
-/** Pointer-to-function type, useful for dynamically getting ALC entry points. */
-typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist);
-typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context);
-typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context);
-typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context);
-typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context);
-typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void);
-typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context);
-typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename);
-typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device);
-typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device);
-typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname);
-typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname);
-typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname);
-typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param);
-typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
-typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
-typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device);
-typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device);
-typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device);
-typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* AL_ALC_H */
diff --git a/project/vs2015/external/openal_soft/include/AL/alext.h b/project/vs2015/external/openal_soft/include/AL/alext.h
deleted file mode 100644
index 6af581aa..00000000
--- a/project/vs2015/external/openal_soft/include/AL/alext.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * OpenAL cross platform audio library
- * Copyright (C) 2008 by authors.
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- * Or go to http://www.gnu.org/copyleft/lgpl.html
- */
-
-#ifndef AL_ALEXT_H
-#define AL_ALEXT_H
-
-#include <stddef.h>
-/* Define int64_t and uint64_t types */
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#include <inttypes.h>
-#elif defined(_WIN32) && defined(__GNUC__)
-#include <stdint.h>
-#elif defined(_WIN32)
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#else
-/* Fallback if nothing above works */
-#include <inttypes.h>
-#endif
-
-#include "alc.h"
-#include "al.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef AL_LOKI_IMA_ADPCM_format
-#define AL_LOKI_IMA_ADPCM_format 1
-#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
-#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001
-#endif
-
-#ifndef AL_LOKI_WAVE_format
-#define AL_LOKI_WAVE_format 1
-#define AL_FORMAT_WAVE_EXT 0x10002
-#endif
-
-#ifndef AL_EXT_vorbis
-#define AL_EXT_vorbis 1
-#define AL_FORMAT_VORBIS_EXT 0x10003
-#endif
-
-#ifndef AL_LOKI_quadriphonic
-#define AL_LOKI_quadriphonic 1
-#define AL_FORMAT_QUAD8_LOKI 0x10004
-#define AL_FORMAT_QUAD16_LOKI 0x10005
-#endif
-
-#ifndef AL_EXT_float32
-#define AL_EXT_float32 1
-#define AL_FORMAT_MONO_FLOAT32 0x10010
-#define AL_FORMAT_STEREO_FLOAT32 0x10011
-#endif
-
-#ifndef AL_EXT_double
-#define AL_EXT_double 1
-#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012
-#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013
-#endif
-
-#ifndef AL_EXT_MULAW
-#define AL_EXT_MULAW 1
-#define AL_FORMAT_MONO_MULAW_EXT 0x10014
-#define AL_FORMAT_STEREO_MULAW_EXT 0x10015
-#endif
-
-#ifndef AL_EXT_ALAW
-#define AL_EXT_ALAW 1
-#define AL_FORMAT_MONO_ALAW_EXT 0x10016
-#define AL_FORMAT_STEREO_ALAW_EXT 0x10017
-#endif
-
-#ifndef ALC_LOKI_audio_channel
-#define ALC_LOKI_audio_channel 1
-#define ALC_CHAN_MAIN_LOKI 0x500001
-#define ALC_CHAN_PCM_LOKI 0x500002
-#define ALC_CHAN_CD_LOKI 0x500003
-#endif
-
-#ifndef AL_EXT_MCFORMATS
-#define AL_EXT_MCFORMATS 1
-#define AL_FORMAT_QUAD8 0x1204
-#define AL_FORMAT_QUAD16 0x1205
-#define AL_FORMAT_QUAD32 0x1206
-#define AL_FORMAT_REAR8 0x1207
-#define AL_FORMAT_REAR16 0x1208
-#define AL_FORMAT_REAR32 0x1209
-#define AL_FORMAT_51CHN8 0x120A
-#define AL_FORMAT_51CHN16 0x120B
-#define AL_FORMAT_51CHN32 0x120C
-#define AL_FORMAT_61CHN8 0x120D
-#define AL_FORMAT_61CHN16 0x120E
-#define AL_FORMAT_61CHN32 0x120F
-#define AL_FORMAT_71CHN8 0x1210
-#define AL_FORMAT_71CHN16 0x1211
-#define AL_FORMAT_71CHN32 0x1212
-#endif
-
-#ifndef AL_EXT_MULAW_MCFORMATS
-#define AL_EXT_MULAW_MCFORMATS 1
-#define AL_FORMAT_MONO_MULAW 0x10014
-#define AL_FORMAT_STEREO_MULAW 0x10015
-#define AL_FORMAT_QUAD_MULAW 0x10021
-#define AL_FORMAT_REAR_MULAW 0x10022
-#define AL_FORMAT_51CHN_MULAW 0x10023
-#define AL_FORMAT_61CHN_MULAW 0x10024
-#define AL_FORMAT_71CHN_MULAW 0x10025
-#endif
-
-#ifndef AL_EXT_IMA4
-#define AL_EXT_IMA4 1
-#define AL_FORMAT_MONO_IMA4 0x1300
-#define AL_FORMAT_STEREO_IMA4 0x1301
-#endif
-
-#ifndef AL_EXT_STATIC_BUFFER
-#define AL_EXT_STATIC_BUFFER 1
-typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
-#endif
-#endif
-
-#ifndef ALC_EXT_EFX
-#define ALC_EXT_EFX 1
-#include "efx.h"
-#endif
-
-#ifndef ALC_EXT_disconnect
-#define ALC_EXT_disconnect 1
-#define ALC_CONNECTED 0x313
-#endif
-
-#ifndef ALC_EXT_thread_local_context
-#define ALC_EXT_thread_local_context 1
-typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context);
-typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context);
-ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
-#endif
-#endif
-
-#ifndef AL_EXT_source_distance_model
-#define AL_EXT_source_distance_model 1
-#define AL_SOURCE_DISTANCE_MODEL 0x200
-#endif
-
-#ifndef AL_SOFT_buffer_sub_data
-#define AL_SOFT_buffer_sub_data 1
-#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
-#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
-typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
-#endif
-#endif
-
-#ifndef AL_SOFT_loop_points
-#define AL_SOFT_loop_points 1
-#define AL_LOOP_POINTS_SOFT 0x2015
-#endif
-
-#ifndef AL_EXT_FOLDBACK
-#define AL_EXT_FOLDBACK 1
-#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK"
-#define AL_FOLDBACK_EVENT_BLOCK 0x4112
-#define AL_FOLDBACK_EVENT_START 0x4111
-#define AL_FOLDBACK_EVENT_STOP 0x4113
-#define AL_FOLDBACK_MODE_MONO 0x4101
-#define AL_FOLDBACK_MODE_STEREO 0x4102
-typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei);
-typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK);
-typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback);
-AL_API void AL_APIENTRY alRequestFoldbackStop(void);
-#endif
-#endif
-
-#ifndef ALC_EXT_DEDICATED
-#define ALC_EXT_DEDICATED 1
-#define AL_DEDICATED_GAIN 0x0001
-#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001
-#define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000
-#endif
-
-#ifndef AL_SOFT_buffer_samples
-#define AL_SOFT_buffer_samples 1
-/* Channel configurations */
-#define AL_MONO_SOFT 0x1500
-#define AL_STEREO_SOFT 0x1501
-#define AL_REAR_SOFT 0x1502
-#define AL_QUAD_SOFT 0x1503
-#define AL_5POINT1_SOFT 0x1504
-#define AL_6POINT1_SOFT 0x1505
-#define AL_7POINT1_SOFT 0x1506
-
-/* Sample types */
-#define AL_BYTE_SOFT 0x1400
-#define AL_UNSIGNED_BYTE_SOFT 0x1401
-#define AL_SHORT_SOFT 0x1402
-#define AL_UNSIGNED_SHORT_SOFT 0x1403
-#define AL_INT_SOFT 0x1404
-#define AL_UNSIGNED_INT_SOFT 0x1405
-#define AL_FLOAT_SOFT 0x1406
-#define AL_DOUBLE_SOFT 0x1407
-#define AL_BYTE3_SOFT 0x1408
-#define AL_UNSIGNED_BYTE3_SOFT 0x1409
-
-/* Storage formats */
-#define AL_MONO8_SOFT 0x1100
-#define AL_MONO16_SOFT 0x1101
-#define AL_MONO32F_SOFT 0x10010
-#define AL_STEREO8_SOFT 0x1102
-#define AL_STEREO16_SOFT 0x1103
-#define AL_STEREO32F_SOFT 0x10011
-#define AL_QUAD8_SOFT 0x1204
-#define AL_QUAD16_SOFT 0x1205
-#define AL_QUAD32F_SOFT 0x1206
-#define AL_REAR8_SOFT 0x1207
-#define AL_REAR16_SOFT 0x1208
-#define AL_REAR32F_SOFT 0x1209
-#define AL_5POINT1_8_SOFT 0x120A
-#define AL_5POINT1_16_SOFT 0x120B
-#define AL_5POINT1_32F_SOFT 0x120C
-#define AL_6POINT1_8_SOFT 0x120D
-#define AL_6POINT1_16_SOFT 0x120E
-#define AL_6POINT1_32F_SOFT 0x120F
-#define AL_7POINT1_8_SOFT 0x1210
-#define AL_7POINT1_16_SOFT 0x1211
-#define AL_7POINT1_32F_SOFT 0x1212
-
-/* Buffer attributes */
-#define AL_INTERNAL_FORMAT_SOFT 0x2008
-#define AL_BYTE_LENGTH_SOFT 0x2009
-#define AL_SAMPLE_LENGTH_SOFT 0x200A
-#define AL_SEC_LENGTH_SOFT 0x200B
-
-typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*);
-typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*);
-typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*);
-typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
-AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
-AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data);
-AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
-#endif
-#endif
-
-#ifndef AL_SOFT_direct_channels
-#define AL_SOFT_direct_channels 1
-#define AL_DIRECT_CHANNELS_SOFT 0x1033
-#endif
-
-#ifndef ALC_SOFT_loopback
-#define ALC_SOFT_loopback 1
-#define ALC_FORMAT_CHANNELS_SOFT 0x1990
-#define ALC_FORMAT_TYPE_SOFT 0x1991
-
-/* Sample types */
-#define ALC_BYTE_SOFT 0x1400
-#define ALC_UNSIGNED_BYTE_SOFT 0x1401
-#define ALC_SHORT_SOFT 0x1402
-#define ALC_UNSIGNED_SHORT_SOFT 0x1403
-#define ALC_INT_SOFT 0x1404
-#define ALC_UNSIGNED_INT_SOFT 0x1405
-#define ALC_FLOAT_SOFT 0x1406
-
-/* Channel configurations */
-#define ALC_MONO_SOFT 0x1500
-#define ALC_STEREO_SOFT 0x1501
-#define ALC_QUAD_SOFT 0x1503
-#define ALC_5POINT1_SOFT 0x1504
-#define ALC_6POINT1_SOFT 0x1505
-#define ALC_7POINT1_SOFT 0x1506
-
-typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*);
-typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum);
-typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName);
-ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type);
-ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
-#endif
-#endif
-
-#ifndef AL_EXT_STEREO_ANGLES
-#define AL_EXT_STEREO_ANGLES 1
-#define AL_STEREO_ANGLES 0x1030
-#endif
-
-#ifndef AL_EXT_SOURCE_RADIUS
-#define AL_EXT_SOURCE_RADIUS 1
-#define AL_SOURCE_RADIUS 0x1031
-#endif
-
-#ifndef AL_SOFT_source_latency
-#define AL_SOFT_source_latency 1
-#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
-#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
-typedef int64_t ALint64SOFT;
-typedef uint64_t ALuint64SOFT;
-typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble);
-typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble);
-typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*);
-typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*);
-typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*);
-typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*);
-typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT);
-typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT);
-typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*);
-typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*);
-typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*);
-typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value);
-AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3);
-AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values);
-AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value);
-AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3);
-AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values);
-AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value);
-AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3);
-AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values);
-AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value);
-AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3);
-AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values);
-#endif
-#endif
-
-#ifndef ALC_EXT_DEFAULT_FILTER_ORDER
-#define ALC_EXT_DEFAULT_FILTER_ORDER 1
-#define ALC_DEFAULT_FILTER_ORDER 0x1100
-#endif
-
-#ifndef AL_SOFT_deferred_updates
-#define AL_SOFT_deferred_updates 1
-#define AL_DEFERRED_UPDATES_SOFT 0xC002
-typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
-typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
-AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
-#endif
-#endif
-
-#ifndef AL_SOFT_block_alignment
-#define AL_SOFT_block_alignment 1
-#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C
-#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D
-#endif
-
-#ifndef AL_SOFT_MSADPCM
-#define AL_SOFT_MSADPCM 1
-#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302
-#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303
-#endif
-
-#ifndef AL_SOFT_source_length
-#define AL_SOFT_source_length 1
-/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
-/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
-/*#define AL_SEC_LENGTH_SOFT 0x200B*/
-#endif
-
-#ifndef ALC_SOFT_pause_device
-#define ALC_SOFT_pause_device 1
-typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
-typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device);
-ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
-#endif
-#endif
-
-#ifndef AL_EXT_BFORMAT
-#define AL_EXT_BFORMAT 1
-#define AL_FORMAT_BFORMAT2D_8 0x20021
-#define AL_FORMAT_BFORMAT2D_16 0x20022
-#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
-#define AL_FORMAT_BFORMAT3D_8 0x20031
-#define AL_FORMAT_BFORMAT3D_16 0x20032
-#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033
-#endif
-
-#ifndef AL_EXT_MULAW_BFORMAT
-#define AL_EXT_MULAW_BFORMAT 1
-#define AL_FORMAT_BFORMAT2D_MULAW 0x10031
-#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
-#endif
-
-#ifndef ALC_SOFT_HRTF
-#define ALC_SOFT_HRTF 1
-#define ALC_HRTF_SOFT 0x1992
-#define ALC_DONT_CARE_SOFT 0x0002
-#define ALC_HRTF_STATUS_SOFT 0x1993
-#define ALC_HRTF_DISABLED_SOFT 0x0000
-#define ALC_HRTF_ENABLED_SOFT 0x0001
-#define ALC_HRTF_DENIED_SOFT 0x0002
-#define ALC_HRTF_REQUIRED_SOFT 0x0003
-#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
-#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
-#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994
-#define ALC_HRTF_SPECIFIER_SOFT 0x1995
-#define ALC_HRTF_ID_SOFT 0x1996
-typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index);
-typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
-#ifdef AL_ALEXT_PROTOTYPES
-ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index);
-ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs);
-#endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/project/vs2015/external/openal_soft/include/AL/efx-creative.h b/project/vs2015/external/openal_soft/include/AL/efx-creative.h
deleted file mode 100644
index 0a04c982..00000000
--- a/project/vs2015/external/openal_soft/include/AL/efx-creative.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* The tokens that would be defined here are already defined in efx.h. This
- * empty file is here to provide compatibility with Windows-based projects
- * that would include it. */
diff --git a/project/vs2015/external/openal_soft/include/AL/efx-presets.h b/project/vs2015/external/openal_soft/include/AL/efx-presets.h
deleted file mode 100644
index 8539fd51..00000000
--- a/project/vs2015/external/openal_soft/include/AL/efx-presets.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/* Reverb presets for EFX */
-
-#ifndef EFX_PRESETS_H
-#define EFX_PRESETS_H
-
-#ifndef EFXEAXREVERBPROPERTIES_DEFINED
-#define EFXEAXREVERBPROPERTIES_DEFINED
-typedef struct {
- float flDensity;
- float flDiffusion;
- float flGain;
- float flGainHF;
- float flGainLF;
- float flDecayTime;
- float flDecayHFRatio;
- float flDecayLFRatio;
- float flReflectionsGain;
- float flReflectionsDelay;
- float flReflectionsPan[3];
- float flLateReverbGain;
- float flLateReverbDelay;
- float flLateReverbPan[3];
- float flEchoTime;
- float flEchoDepth;
- float flModulationTime;
- float flModulationDepth;
- float flAirAbsorptionGainHF;
- float flHFReference;
- float flLFReference;
- float flRoomRolloffFactor;
- int iDecayHFLimit;
-} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
-#endif
-
-/* Default Presets */
-
-#define EFX_REVERB_PRESET_GENERIC \
- { 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PADDEDCELL \
- { 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ROOM \
- { 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_BATHROOM \
- { 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_LIVINGROOM \
- { 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_STONEROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_AUDITORIUM \
- { 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CONCERTHALL \
- { 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CAVE \
- { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_ARENA \
- { 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_HANGAR \
- { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CARPETEDHALLWAY \
- { 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_HALLWAY \
- { 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_STONECORRIDOR \
- { 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ALLEY \
- { 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FOREST \
- { 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY \
- { 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_MOUNTAINS \
- { 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_QUARRY \
- { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PLAIN \
- { 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PARKINGLOT \
- { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_SEWERPIPE \
- { 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_UNDERWATER \
- { 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRUGGED \
- { 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DIZZY \
- { 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PSYCHOTIC \
- { 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-/* Castle Presets */
-
-#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \
- { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \
- { 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \
- { 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \
- { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \
- { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_HALL \
- { 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \
- { 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CASTLE_COURTYARD \
- { 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_CASTLE_ALCOVE \
- { 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
-
-/* Factory Presets */
-
-#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \
- { 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \
- { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \
- { 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \
- { 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \
- { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_HALL \
- { 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \
- { 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_COURTYARD \
- { 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_FACTORY_ALCOVE \
- { 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
-
-/* Ice Palace Presets */
-
-#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \
- { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \
- { 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \
- { 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \
- { 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \
- { 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_HALL \
- { 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \
- { 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \
- { 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \
- { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
-
-/* Space Station Presets */
-
-#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \
- { 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \
- { 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \
- { 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \
- { 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \
- { 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_HALL \
- { 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \
- { 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \
- { 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
-
-/* Wooden Galleon Presets */
-
-#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \
- { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \
- { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \
- { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_HALL \
- { 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \
- { 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_COURTYARD \
- { 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_WOODEN_ALCOVE \
- { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
-
-/* Sports Presets */
-
-#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \
- { 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \
- { 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \
- { 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \
- { 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \
- { 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \
- { 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \
- { 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-/* Prefab Presets */
-
-#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \
- { 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \
- { 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \
- { 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \
- { 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PREFAB_CARAVAN \
- { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-/* Dome and Pipe Presets */
-
-#define EFX_REVERB_PRESET_DOME_TOMB \
- { 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PIPE_SMALL \
- { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DOME_SAINTPAULS \
- { 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PIPE_LONGTHIN \
- { 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_PIPE_LARGE \
- { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_PIPE_RESONANT \
- { 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
-
-/* Outdoors Presets */
-
-#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \
- { 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \
- { 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \
- { 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_CREEK \
- { 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \
- { 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-/* Mood Presets */
-
-#define EFX_REVERB_PRESET_MOOD_HEAVEN \
- { 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_MOOD_HELL \
- { 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_MOOD_MEMORY \
- { 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-/* Driving Presets */
-
-#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
- { 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
- { 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \
- { 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \
- { 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \
- { 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \
- { 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \
- { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_DRIVING_TUNNEL \
- { 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 }
-
-/* City Presets */
-
-#define EFX_REVERB_PRESET_CITY_STREETS \
- { 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY_SUBWAY \
- { 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY_MUSEUM \
- { 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_CITY_LIBRARY \
- { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
-
-#define EFX_REVERB_PRESET_CITY_UNDERPASS \
- { 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CITY_ABANDONED \
- { 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-/* Misc. Presets */
-
-#define EFX_REVERB_PRESET_DUSTYROOM \
- { 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_CHAPEL \
- { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
-
-#define EFX_REVERB_PRESET_SMALLWATERROOM \
- { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
-
-#endif /* EFX_PRESETS_H */
diff --git a/project/vs2015/external/openal_soft/include/AL/efx.h b/project/vs2015/external/openal_soft/include/AL/efx.h
deleted file mode 100644
index 57766983..00000000
--- a/project/vs2015/external/openal_soft/include/AL/efx.h
+++ /dev/null
@@ -1,761 +0,0 @@
-#ifndef AL_EFX_H
-#define AL_EFX_H
-
-
-#include "alc.h"
-#include "al.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ALC_EXT_EFX_NAME "ALC_EXT_EFX"
-
-#define ALC_EFX_MAJOR_VERSION 0x20001
-#define ALC_EFX_MINOR_VERSION 0x20002
-#define ALC_MAX_AUXILIARY_SENDS 0x20003
-
-
-/* Listener properties. */
-#define AL_METERS_PER_UNIT 0x20004
-
-/* Source properties. */
-#define AL_DIRECT_FILTER 0x20005
-#define AL_AUXILIARY_SEND_FILTER 0x20006
-#define AL_AIR_ABSORPTION_FACTOR 0x20007
-#define AL_ROOM_ROLLOFF_FACTOR 0x20008
-#define AL_CONE_OUTER_GAINHF 0x20009
-#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A
-#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B
-#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C
-
-
-/* Effect properties. */
-
-/* Reverb effect parameters */
-#define AL_REVERB_DENSITY 0x0001
-#define AL_REVERB_DIFFUSION 0x0002
-#define AL_REVERB_GAIN 0x0003
-#define AL_REVERB_GAINHF 0x0004
-#define AL_REVERB_DECAY_TIME 0x0005
-#define AL_REVERB_DECAY_HFRATIO 0x0006
-#define AL_REVERB_REFLECTIONS_GAIN 0x0007
-#define AL_REVERB_REFLECTIONS_DELAY 0x0008
-#define AL_REVERB_LATE_REVERB_GAIN 0x0009
-#define AL_REVERB_LATE_REVERB_DELAY 0x000A
-#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B
-#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
-#define AL_REVERB_DECAY_HFLIMIT 0x000D
-
-/* EAX Reverb effect parameters */
-#define AL_EAXREVERB_DENSITY 0x0001
-#define AL_EAXREVERB_DIFFUSION 0x0002
-#define AL_EAXREVERB_GAIN 0x0003
-#define AL_EAXREVERB_GAINHF 0x0004
-#define AL_EAXREVERB_GAINLF 0x0005
-#define AL_EAXREVERB_DECAY_TIME 0x0006
-#define AL_EAXREVERB_DECAY_HFRATIO 0x0007
-#define AL_EAXREVERB_DECAY_LFRATIO 0x0008
-#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009
-#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A
-#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B
-#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C
-#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D
-#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E
-#define AL_EAXREVERB_ECHO_TIME 0x000F
-#define AL_EAXREVERB_ECHO_DEPTH 0x0010
-#define AL_EAXREVERB_MODULATION_TIME 0x0011
-#define AL_EAXREVERB_MODULATION_DEPTH 0x0012
-#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013
-#define AL_EAXREVERB_HFREFERENCE 0x0014
-#define AL_EAXREVERB_LFREFERENCE 0x0015
-#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016
-#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017
-
-/* Chorus effect parameters */
-#define AL_CHORUS_WAVEFORM 0x0001
-#define AL_CHORUS_PHASE 0x0002
-#define AL_CHORUS_RATE 0x0003
-#define AL_CHORUS_DEPTH 0x0004
-#define AL_CHORUS_FEEDBACK 0x0005
-#define AL_CHORUS_DELAY 0x0006
-
-/* Distortion effect parameters */
-#define AL_DISTORTION_EDGE 0x0001
-#define AL_DISTORTION_GAIN 0x0002
-#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003
-#define AL_DISTORTION_EQCENTER 0x0004
-#define AL_DISTORTION_EQBANDWIDTH 0x0005
-
-/* Echo effect parameters */
-#define AL_ECHO_DELAY 0x0001
-#define AL_ECHO_LRDELAY 0x0002
-#define AL_ECHO_DAMPING 0x0003
-#define AL_ECHO_FEEDBACK 0x0004
-#define AL_ECHO_SPREAD 0x0005
-
-/* Flanger effect parameters */
-#define AL_FLANGER_WAVEFORM 0x0001
-#define AL_FLANGER_PHASE 0x0002
-#define AL_FLANGER_RATE 0x0003
-#define AL_FLANGER_DEPTH 0x0004
-#define AL_FLANGER_FEEDBACK 0x0005
-#define AL_FLANGER_DELAY 0x0006
-
-/* Frequency shifter effect parameters */
-#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001
-#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002
-#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003
-
-/* Vocal morpher effect parameters */
-#define AL_VOCAL_MORPHER_PHONEMEA 0x0001
-#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002
-#define AL_VOCAL_MORPHER_PHONEMEB 0x0003
-#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004
-#define AL_VOCAL_MORPHER_WAVEFORM 0x0005
-#define AL_VOCAL_MORPHER_RATE 0x0006
-
-/* Pitchshifter effect parameters */
-#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001
-#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002
-
-/* Ringmodulator effect parameters */
-#define AL_RING_MODULATOR_FREQUENCY 0x0001
-#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002
-#define AL_RING_MODULATOR_WAVEFORM 0x0003
-
-/* Autowah effect parameters */
-#define AL_AUTOWAH_ATTACK_TIME 0x0001
-#define AL_AUTOWAH_RELEASE_TIME 0x0002
-#define AL_AUTOWAH_RESONANCE 0x0003
-#define AL_AUTOWAH_PEAK_GAIN 0x0004
-
-/* Compressor effect parameters */
-#define AL_COMPRESSOR_ONOFF 0x0001
-
-/* Equalizer effect parameters */
-#define AL_EQUALIZER_LOW_GAIN 0x0001
-#define AL_EQUALIZER_LOW_CUTOFF 0x0002
-#define AL_EQUALIZER_MID1_GAIN 0x0003
-#define AL_EQUALIZER_MID1_CENTER 0x0004
-#define AL_EQUALIZER_MID1_WIDTH 0x0005
-#define AL_EQUALIZER_MID2_GAIN 0x0006
-#define AL_EQUALIZER_MID2_CENTER 0x0007
-#define AL_EQUALIZER_MID2_WIDTH 0x0008
-#define AL_EQUALIZER_HIGH_GAIN 0x0009
-#define AL_EQUALIZER_HIGH_CUTOFF 0x000A
-
-/* Effect type */
-#define AL_EFFECT_FIRST_PARAMETER 0x0000
-#define AL_EFFECT_LAST_PARAMETER 0x8000
-#define AL_EFFECT_TYPE 0x8001
-
-/* Effect types, used with the AL_EFFECT_TYPE property */
-#define AL_EFFECT_NULL 0x0000
-#define AL_EFFECT_REVERB 0x0001
-#define AL_EFFECT_CHORUS 0x0002
-#define AL_EFFECT_DISTORTION 0x0003
-#define AL_EFFECT_ECHO 0x0004
-#define AL_EFFECT_FLANGER 0x0005
-#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
-#define AL_EFFECT_VOCAL_MORPHER 0x0007
-#define AL_EFFECT_PITCH_SHIFTER 0x0008
-#define AL_EFFECT_RING_MODULATOR 0x0009
-#define AL_EFFECT_AUTOWAH 0x000A
-#define AL_EFFECT_COMPRESSOR 0x000B
-#define AL_EFFECT_EQUALIZER 0x000C
-#define AL_EFFECT_EAXREVERB 0x8000
-
-/* Auxiliary Effect Slot properties. */
-#define AL_EFFECTSLOT_EFFECT 0x0001
-#define AL_EFFECTSLOT_GAIN 0x0002
-#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003
-
-/* NULL Auxiliary Slot ID to disable a source send. */
-#define AL_EFFECTSLOT_NULL 0x0000
-
-
-/* Filter properties. */
-
-/* Lowpass filter parameters */
-#define AL_LOWPASS_GAIN 0x0001
-#define AL_LOWPASS_GAINHF 0x0002
-
-/* Highpass filter parameters */
-#define AL_HIGHPASS_GAIN 0x0001
-#define AL_HIGHPASS_GAINLF 0x0002
-
-/* Bandpass filter parameters */
-#define AL_BANDPASS_GAIN 0x0001
-#define AL_BANDPASS_GAINLF 0x0002
-#define AL_BANDPASS_GAINHF 0x0003
-
-/* Filter type */
-#define AL_FILTER_FIRST_PARAMETER 0x0000
-#define AL_FILTER_LAST_PARAMETER 0x8000
-#define AL_FILTER_TYPE 0x8001
-
-/* Filter types, used with the AL_FILTER_TYPE property */
-#define AL_FILTER_NULL 0x0000
-#define AL_FILTER_LOWPASS 0x0001
-#define AL_FILTER_HIGHPASS 0x0002
-#define AL_FILTER_BANDPASS 0x0003
-
-
-/* Effect object function types. */
-typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
-typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint);
-typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*);
-typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*);
-typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*);
-typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*);
-
-/* Filter object function types. */
-typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
-typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint);
-typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*);
-typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*);
-typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*);
-typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*);
-
-/* Auxiliary Effect Slot object function types. */
-typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*);
-typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*);
-typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
-
-#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
-AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects);
-AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect);
-AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
-AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues);
-AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues);
-AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
-AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
-AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
-
-AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
-AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters);
-AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter);
-AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
-AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues);
-AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues);
-AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
-AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
-AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
-
-AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
-AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots);
-AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
-AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
-#endif
-
-/* Filter ranges and defaults. */
-
-/* Lowpass filter */
-#define AL_LOWPASS_MIN_GAIN (0.0f)
-#define AL_LOWPASS_MAX_GAIN (1.0f)
-#define AL_LOWPASS_DEFAULT_GAIN (1.0f)
-
-#define AL_LOWPASS_MIN_GAINHF (0.0f)
-#define AL_LOWPASS_MAX_GAINHF (1.0f)
-#define AL_LOWPASS_DEFAULT_GAINHF (1.0f)
-
-/* Highpass filter */
-#define AL_HIGHPASS_MIN_GAIN (0.0f)
-#define AL_HIGHPASS_MAX_GAIN (1.0f)
-#define AL_HIGHPASS_DEFAULT_GAIN (1.0f)
-
-#define AL_HIGHPASS_MIN_GAINLF (0.0f)
-#define AL_HIGHPASS_MAX_GAINLF (1.0f)
-#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f)
-
-/* Bandpass filter */
-#define AL_BANDPASS_MIN_GAIN (0.0f)
-#define AL_BANDPASS_MAX_GAIN (1.0f)
-#define AL_BANDPASS_DEFAULT_GAIN (1.0f)
-
-#define AL_BANDPASS_MIN_GAINHF (0.0f)
-#define AL_BANDPASS_MAX_GAINHF (1.0f)
-#define AL_BANDPASS_DEFAULT_GAINHF (1.0f)
-
-#define AL_BANDPASS_MIN_GAINLF (0.0f)
-#define AL_BANDPASS_MAX_GAINLF (1.0f)
-#define AL_BANDPASS_DEFAULT_GAINLF (1.0f)
-
-
-/* Effect parameter ranges and defaults. */
-
-/* Standard reverb effect */
-#define AL_REVERB_MIN_DENSITY (0.0f)
-#define AL_REVERB_MAX_DENSITY (1.0f)
-#define AL_REVERB_DEFAULT_DENSITY (1.0f)
-
-#define AL_REVERB_MIN_DIFFUSION (0.0f)
-#define AL_REVERB_MAX_DIFFUSION (1.0f)
-#define AL_REVERB_DEFAULT_DIFFUSION (1.0f)
-
-#define AL_REVERB_MIN_GAIN (0.0f)
-#define AL_REVERB_MAX_GAIN (1.0f)
-#define AL_REVERB_DEFAULT_GAIN (0.32f)
-
-#define AL_REVERB_MIN_GAINHF (0.0f)
-#define AL_REVERB_MAX_GAINHF (1.0f)
-#define AL_REVERB_DEFAULT_GAINHF (0.89f)
-
-#define AL_REVERB_MIN_DECAY_TIME (0.1f)
-#define AL_REVERB_MAX_DECAY_TIME (20.0f)
-#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f)
-
-#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f)
-#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f)
-#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f)
-
-#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f)
-#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f)
-#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
-
-#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f)
-#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f)
-#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
-
-#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f)
-#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f)
-#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
-
-#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f)
-#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f)
-#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
-
-#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
-#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
-#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
-
-#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
-#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
-#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
-
-#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE
-#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE
-#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
-
-/* EAX reverb effect */
-#define AL_EAXREVERB_MIN_DENSITY (0.0f)
-#define AL_EAXREVERB_MAX_DENSITY (1.0f)
-#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f)
-
-#define AL_EAXREVERB_MIN_DIFFUSION (0.0f)
-#define AL_EAXREVERB_MAX_DIFFUSION (1.0f)
-#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f)
-
-#define AL_EAXREVERB_MIN_GAIN (0.0f)
-#define AL_EAXREVERB_MAX_GAIN (1.0f)
-#define AL_EAXREVERB_DEFAULT_GAIN (0.32f)
-
-#define AL_EAXREVERB_MIN_GAINHF (0.0f)
-#define AL_EAXREVERB_MAX_GAINHF (1.0f)
-#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f)
-
-#define AL_EAXREVERB_MIN_GAINLF (0.0f)
-#define AL_EAXREVERB_MAX_GAINLF (1.0f)
-#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f)
-
-#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f)
-#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f)
-#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f)
-
-#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f)
-#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f)
-#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f)
-
-#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f)
-#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f)
-#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f)
-
-#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f)
-#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f)
-#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
-
-#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f)
-#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
-#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
-
-#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f)
-
-#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f)
-#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f)
-#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
-
-#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f)
-#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
-#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
-
-#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f)
-
-#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f)
-#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f)
-#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f)
-
-#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f)
-#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f)
-#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f)
-
-#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f)
-#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f)
-#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f)
-
-#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f)
-#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f)
-#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f)
-
-#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
-#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
-#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
-
-#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f)
-#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f)
-#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f)
-
-#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f)
-#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f)
-#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f)
-
-#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
-#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
-#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
-
-#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE
-#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE
-#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
-
-/* Chorus effect */
-#define AL_CHORUS_WAVEFORM_SINUSOID (0)
-#define AL_CHORUS_WAVEFORM_TRIANGLE (1)
-
-#define AL_CHORUS_MIN_WAVEFORM (0)
-#define AL_CHORUS_MAX_WAVEFORM (1)
-#define AL_CHORUS_DEFAULT_WAVEFORM (1)
-
-#define AL_CHORUS_MIN_PHASE (-180)
-#define AL_CHORUS_MAX_PHASE (180)
-#define AL_CHORUS_DEFAULT_PHASE (90)
-
-#define AL_CHORUS_MIN_RATE (0.0f)
-#define AL_CHORUS_MAX_RATE (10.0f)
-#define AL_CHORUS_DEFAULT_RATE (1.1f)
-
-#define AL_CHORUS_MIN_DEPTH (0.0f)
-#define AL_CHORUS_MAX_DEPTH (1.0f)
-#define AL_CHORUS_DEFAULT_DEPTH (0.1f)
-
-#define AL_CHORUS_MIN_FEEDBACK (-1.0f)
-#define AL_CHORUS_MAX_FEEDBACK (1.0f)
-#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f)
-
-#define AL_CHORUS_MIN_DELAY (0.0f)
-#define AL_CHORUS_MAX_DELAY (0.016f)
-#define AL_CHORUS_DEFAULT_DELAY (0.016f)
-
-/* Distortion effect */
-#define AL_DISTORTION_MIN_EDGE (0.0f)
-#define AL_DISTORTION_MAX_EDGE (1.0f)
-#define AL_DISTORTION_DEFAULT_EDGE (0.2f)
-
-#define AL_DISTORTION_MIN_GAIN (0.01f)
-#define AL_DISTORTION_MAX_GAIN (1.0f)
-#define AL_DISTORTION_DEFAULT_GAIN (0.05f)
-
-#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f)
-#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f)
-#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f)
-
-#define AL_DISTORTION_MIN_EQCENTER (80.0f)
-#define AL_DISTORTION_MAX_EQCENTER (24000.0f)
-#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f)
-
-#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f)
-#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f)
-#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f)
-
-/* Echo effect */
-#define AL_ECHO_MIN_DELAY (0.0f)
-#define AL_ECHO_MAX_DELAY (0.207f)
-#define AL_ECHO_DEFAULT_DELAY (0.1f)
-
-#define AL_ECHO_MIN_LRDELAY (0.0f)
-#define AL_ECHO_MAX_LRDELAY (0.404f)
-#define AL_ECHO_DEFAULT_LRDELAY (0.1f)
-
-#define AL_ECHO_MIN_DAMPING (0.0f)
-#define AL_ECHO_MAX_DAMPING (0.99f)
-#define AL_ECHO_DEFAULT_DAMPING (0.5f)
-
-#define AL_ECHO_MIN_FEEDBACK (0.0f)
-#define AL_ECHO_MAX_FEEDBACK (1.0f)
-#define AL_ECHO_DEFAULT_FEEDBACK (0.5f)
-
-#define AL_ECHO_MIN_SPREAD (-1.0f)
-#define AL_ECHO_MAX_SPREAD (1.0f)
-#define AL_ECHO_DEFAULT_SPREAD (-1.0f)
-
-/* Flanger effect */
-#define AL_FLANGER_WAVEFORM_SINUSOID (0)
-#define AL_FLANGER_WAVEFORM_TRIANGLE (1)
-
-#define AL_FLANGER_MIN_WAVEFORM (0)
-#define AL_FLANGER_MAX_WAVEFORM (1)
-#define AL_FLANGER_DEFAULT_WAVEFORM (1)
-
-#define AL_FLANGER_MIN_PHASE (-180)
-#define AL_FLANGER_MAX_PHASE (180)
-#define AL_FLANGER_DEFAULT_PHASE (0)
-
-#define AL_FLANGER_MIN_RATE (0.0f)
-#define AL_FLANGER_MAX_RATE (10.0f)
-#define AL_FLANGER_DEFAULT_RATE (0.27f)
-
-#define AL_FLANGER_MIN_DEPTH (0.0f)
-#define AL_FLANGER_MAX_DEPTH (1.0f)
-#define AL_FLANGER_DEFAULT_DEPTH (1.0f)
-
-#define AL_FLANGER_MIN_FEEDBACK (-1.0f)
-#define AL_FLANGER_MAX_FEEDBACK (1.0f)
-#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f)
-
-#define AL_FLANGER_MIN_DELAY (0.0f)
-#define AL_FLANGER_MAX_DELAY (0.004f)
-#define AL_FLANGER_DEFAULT_DELAY (0.002f)
-
-/* Frequency shifter effect */
-#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f)
-#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f)
-#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f)
-
-#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0)
-#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2)
-#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0)
-
-#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0)
-#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1)
-#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2)
-
-#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0)
-#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2)
-#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0)
-
-/* Vocal morpher effect */
-#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0)
-
-#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0)
-
-#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10)
-
-#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24)
-#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24)
-#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0)
-
-#define AL_VOCAL_MORPHER_PHONEME_A (0)
-#define AL_VOCAL_MORPHER_PHONEME_E (1)
-#define AL_VOCAL_MORPHER_PHONEME_I (2)
-#define AL_VOCAL_MORPHER_PHONEME_O (3)
-#define AL_VOCAL_MORPHER_PHONEME_U (4)
-#define AL_VOCAL_MORPHER_PHONEME_AA (5)
-#define AL_VOCAL_MORPHER_PHONEME_AE (6)
-#define AL_VOCAL_MORPHER_PHONEME_AH (7)
-#define AL_VOCAL_MORPHER_PHONEME_AO (8)
-#define AL_VOCAL_MORPHER_PHONEME_EH (9)
-#define AL_VOCAL_MORPHER_PHONEME_ER (10)
-#define AL_VOCAL_MORPHER_PHONEME_IH (11)
-#define AL_VOCAL_MORPHER_PHONEME_IY (12)
-#define AL_VOCAL_MORPHER_PHONEME_UH (13)
-#define AL_VOCAL_MORPHER_PHONEME_UW (14)
-#define AL_VOCAL_MORPHER_PHONEME_B (15)
-#define AL_VOCAL_MORPHER_PHONEME_D (16)
-#define AL_VOCAL_MORPHER_PHONEME_F (17)
-#define AL_VOCAL_MORPHER_PHONEME_G (18)
-#define AL_VOCAL_MORPHER_PHONEME_J (19)
-#define AL_VOCAL_MORPHER_PHONEME_K (20)
-#define AL_VOCAL_MORPHER_PHONEME_L (21)
-#define AL_VOCAL_MORPHER_PHONEME_M (22)
-#define AL_VOCAL_MORPHER_PHONEME_N (23)
-#define AL_VOCAL_MORPHER_PHONEME_P (24)
-#define AL_VOCAL_MORPHER_PHONEME_R (25)
-#define AL_VOCAL_MORPHER_PHONEME_S (26)
-#define AL_VOCAL_MORPHER_PHONEME_T (27)
-#define AL_VOCAL_MORPHER_PHONEME_V (28)
-#define AL_VOCAL_MORPHER_PHONEME_Z (29)
-
-#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0)
-#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1)
-#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2)
-
-#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0)
-#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2)
-#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0)
-
-#define AL_VOCAL_MORPHER_MIN_RATE (0.0f)
-#define AL_VOCAL_MORPHER_MAX_RATE (10.0f)
-#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f)
-
-/* Pitch shifter effect */
-#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12)
-#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12)
-#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12)
-
-#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50)
-#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50)
-#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0)
-
-/* Ring modulator effect */
-#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f)
-#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f)
-#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f)
-
-#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f)
-#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f)
-#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f)
-
-#define AL_RING_MODULATOR_SINUSOID (0)
-#define AL_RING_MODULATOR_SAWTOOTH (1)
-#define AL_RING_MODULATOR_SQUARE (2)
-
-#define AL_RING_MODULATOR_MIN_WAVEFORM (0)
-#define AL_RING_MODULATOR_MAX_WAVEFORM (2)
-#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0)
-
-/* Autowah effect */
-#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f)
-#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f)
-#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f)
-
-#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f)
-#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f)
-#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f)
-
-#define AL_AUTOWAH_MIN_RESONANCE (2.0f)
-#define AL_AUTOWAH_MAX_RESONANCE (1000.0f)
-#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f)
-
-#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f)
-#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f)
-#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f)
-
-/* Compressor effect */
-#define AL_COMPRESSOR_MIN_ONOFF (0)
-#define AL_COMPRESSOR_MAX_ONOFF (1)
-#define AL_COMPRESSOR_DEFAULT_ONOFF (1)
-
-/* Equalizer effect */
-#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f)
-#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f)
-#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f)
-
-#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f)
-#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f)
-#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f)
-
-#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f)
-#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f)
-#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f)
-
-#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f)
-#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f)
-#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f)
-
-#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f)
-#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f)
-#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f)
-
-#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f)
-#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f)
-#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f)
-
-#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f)
-#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f)
-#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f)
-
-
-/* Source parameter value ranges and defaults. */
-#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f)
-#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f)
-#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f)
-
-#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
-#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
-#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
-
-#define AL_MIN_CONE_OUTER_GAINHF (0.0f)
-#define AL_MAX_CONE_OUTER_GAINHF (1.0f)
-#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f)
-
-#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE
-#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
-#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
-
-#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE
-#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
-#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
-
-#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE
-#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
-#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
-
-
-/* Listener parameter value ranges and defaults. */
-#define AL_MIN_METERS_PER_UNIT FLT_MIN
-#define AL_MAX_METERS_PER_UNIT FLT_MAX
-#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* AL_EFX_H */
diff --git a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll
deleted file mode 100644
index 1e3bddd5..00000000
--- a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib
deleted file mode 100644
index 8bdca11e..00000000
--- a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
deleted file mode 100644
index e24538a5..00000000
--- a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib
deleted file mode 100644
index 3d6e9abf..00000000
--- a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib
+++ /dev/null
Binary files differ
diff --git a/project/vs2015/raylib.sln b/project/vs2015/raylib.sln
index 0ac22f5e..8af10d25 100644
--- a/project/vs2015/raylib.sln
+++ b/project/vs2015/raylib.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
EndProject
@@ -11,6 +11,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window_cpp", "ex
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib.dll", "raylib\raylib.dll.vcxproj", "{C824147D-EE23-4752-AEA7-CD24789BCBC9}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@@ -29,6 +31,10 @@ Global
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.Build.0 = Debug|Win32
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.ActiveCfg = Release|Win32
{B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.Build.0 = Release|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Debug|x86.ActiveCfg = Debug|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Debug|x86.Build.0 = Debug|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Release|x86.ActiveCfg = Release|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/project/vs2015/raylib/raylib.dll.vcxproj b/project/vs2015/raylib/raylib.dll.vcxproj
new file mode 100644
index 00000000..418151b0
--- /dev/null
+++ b/project/vs2015/raylib/raylib.dll.vcxproj
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C824147D-EE23-4752-AEA7-CD24789BCBC9}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>raylib</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)raylib\dll\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)raylib\dll\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)raylib\dll\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)raylib\dll\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED</PreprocessorDefinitions>
+ <CompileAs>CompileAsC</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3dll.lib;openal32dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Lib>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
+ <CompileAs>CompileAsC</CompileAs>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3dll.lib;openal32dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <Text Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\audio.c" />
+ <ClCompile Include="..\..\..\src\core.c" />
+ <ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
+ <ClCompile Include="..\..\..\src\models.c" />
+ <ClCompile Include="..\..\..\src\rlgl.c" />
+ <ClCompile Include="..\..\..\src\shapes.c" />
+ <ClCompile Include="..\..\..\src\text.c" />
+ <ClCompile Include="..\..\..\src\textures.c" />
+ <ClCompile Include="..\..\..\src\utils.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\src\camera.h" />
+ <ClInclude Include="..\..\..\src\external\glad.h" />
+ <ClInclude Include="..\..\..\src\external\jar_mod.h" />
+ <ClInclude Include="..\..\..\src\external\jar_xm.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_resize.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_write.h" />
+ <ClInclude Include="..\..\..\src\external\stb_rect_pack.h" />
+ <ClInclude Include="..\..\..\src\external\stb_truetype.h" />
+ <ClInclude Include="..\..\..\src\external\stb_vorbis.h" />
+ <ClInclude Include="..\..\..\src\gestures.h" />
+ <ClInclude Include="..\..\..\src\raylib.h" />
+ <ClInclude Include="..\..\..\src\raymath.h" />
+ <ClInclude Include="..\..\..\src\rlgl.h" />
+ <ClInclude Include="..\..\..\src\shader_distortion.h" />
+ <ClInclude Include="..\..\..\src\shader_standard.h" />
+ <ClInclude Include="..\..\..\src\utils.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/project/vs2015/raylib/raylib.vcxproj b/project/vs2015/raylib/raylib.vcxproj
index 37e8b183..8a7bde9d 100644
--- a/project/vs2015/raylib/raylib.vcxproj
+++ b/project/vs2015/raylib/raylib.vcxproj
@@ -57,7 +57,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\src\external\openal_soft\include;$(SolutionDir)..\..\src\external\glfw3\include;$(SolutionDir)..\..\src\external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -75,7 +75,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;$(SolutionDir)..\..\src\external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
diff --git a/project/vs2017/examples/core_basic_window.vcxproj b/project/vs2017/examples/core_basic_window.vcxproj
new file mode 100644
index 00000000..b6abeb8d
--- /dev/null
+++ b/project/vs2017/examples/core_basic_window.vcxproj
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0981CA98-E4A5-4DF1-987F-A41D09131EFC}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>core_basic_window</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
+ <ProjectName>core_basic_window</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <CompileAs>CompileAsC</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <CompileAs>CompileAsC</CompileAs>
+ <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\examples\core\core_basic_window.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\raylib\raylib.vcxproj">
+ <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/project/vs2017/examples/core_basic_window_cpp.vcxproj b/project/vs2017/examples/core_basic_window_cpp.vcxproj
new file mode 100644
index 00000000..d5da2a54
--- /dev/null
+++ b/project/vs2017/examples/core_basic_window_cpp.vcxproj
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B655E850-3322-42F7-941D-6AC18FD66CA1}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>raylib_example_cpp</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
+ <ProjectName>core_basic_window_cpp</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)</OutDir>
+ <IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)</OutDir>
+ <IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <CompileAs>CompileAsCpp</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\raylib\raylib.vcxproj">
+ <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\examples\core\core_basic_window.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/project/vs2017/raylib.sln b/project/vs2017/raylib.sln
new file mode 100644
index 00000000..8af10d25
--- /dev/null
+++ b/project/vs2017/raylib.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib", "raylib\raylib.vcxproj", "{E89D61AC-55DE-4482-AFD4-DF7242EBC859}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window_cpp", "examples\core_basic_window_cpp.vcxproj", "{B655E850-3322-42F7-941D-6AC18FD66CA1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib.dll", "raylib\raylib.dll.vcxproj", "{C824147D-EE23-4752-AEA7-CD24789BCBC9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.ActiveCfg = Debug|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Debug|x86.Build.0 = Debug|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.ActiveCfg = Release|Win32
+ {B655E850-3322-42F7-941D-6AC18FD66CA1}.Release|x86.Build.0 = Release|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Debug|x86.ActiveCfg = Debug|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Debug|x86.Build.0 = Debug|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Release|x86.ActiveCfg = Release|Win32
+ {C824147D-EE23-4752-AEA7-CD24789BCBC9}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
+ {B655E850-3322-42F7-941D-6AC18FD66CA1} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
+ EndGlobalSection
+EndGlobal
diff --git a/project/vs2017/raylib/raylib.dll.vcxproj b/project/vs2017/raylib/raylib.dll.vcxproj
new file mode 100644
index 00000000..68f28ba5
--- /dev/null
+++ b/project/vs2017/raylib/raylib.dll.vcxproj
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C824147D-EE23-4752-AEA7-CD24789BCBC9}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>raylib</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)raylib\dll\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)raylib\dll\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)raylib\dll\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)raylib\dll\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED</PreprocessorDefinitions>
+ <CompileAs>CompileAsC</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3dll.lib;openal32dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Lib>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
+ <CompileAs>CompileAsC</CompileAs>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\..\release\libs\win32\msvc;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;glfw3dll.lib;openal32dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <Text Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\audio.c" />
+ <ClCompile Include="..\..\..\src\core.c" />
+ <ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
+ <ClCompile Include="..\..\..\src\models.c" />
+ <ClCompile Include="..\..\..\src\rlgl.c" />
+ <ClCompile Include="..\..\..\src\shapes.c" />
+ <ClCompile Include="..\..\..\src\text.c" />
+ <ClCompile Include="..\..\..\src\textures.c" />
+ <ClCompile Include="..\..\..\src\utils.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\src\camera.h" />
+ <ClInclude Include="..\..\..\src\external\glad.h" />
+ <ClInclude Include="..\..\..\src\external\jar_mod.h" />
+ <ClInclude Include="..\..\..\src\external\jar_xm.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_resize.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_write.h" />
+ <ClInclude Include="..\..\..\src\external\stb_rect_pack.h" />
+ <ClInclude Include="..\..\..\src\external\stb_truetype.h" />
+ <ClInclude Include="..\..\..\src\external\stb_vorbis.h" />
+ <ClInclude Include="..\..\..\src\gestures.h" />
+ <ClInclude Include="..\..\..\src\raylib.h" />
+ <ClInclude Include="..\..\..\src\raymath.h" />
+ <ClInclude Include="..\..\..\src\rlgl.h" />
+ <ClInclude Include="..\..\..\src\shader_distortion.h" />
+ <ClInclude Include="..\..\..\src\shader_standard.h" />
+ <ClInclude Include="..\..\..\src\utils.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/project/vs2017/raylib/raylib.vcxproj b/project/vs2017/raylib/raylib.vcxproj
new file mode 100644
index 00000000..970f9e7f
--- /dev/null
+++ b/project/vs2017/raylib/raylib.vcxproj
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E89D61AC-55DE-4482-AFD4-DF7242EBC859}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>raylib</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\temp</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
+ <CompileAs>CompileAsC</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Lib>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\release\include</AdditionalIncludeDirectories>
+ <CompileAs>CompileAsC</CompileAs>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <Text Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\audio.c" />
+ <ClCompile Include="..\..\..\src\core.c" />
+ <ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
+ <ClCompile Include="..\..\..\src\models.c" />
+ <ClCompile Include="..\..\..\src\rlgl.c" />
+ <ClCompile Include="..\..\..\src\shapes.c" />
+ <ClCompile Include="..\..\..\src\text.c" />
+ <ClCompile Include="..\..\..\src\textures.c" />
+ <ClCompile Include="..\..\..\src\utils.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\src\camera.h" />
+ <ClInclude Include="..\..\..\src\external\glad.h" />
+ <ClInclude Include="..\..\..\src\external\jar_mod.h" />
+ <ClInclude Include="..\..\..\src\external\jar_xm.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_resize.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_write.h" />
+ <ClInclude Include="..\..\..\src\external\stb_rect_pack.h" />
+ <ClInclude Include="..\..\..\src\external\stb_truetype.h" />
+ <ClInclude Include="..\..\..\src\external\stb_vorbis.h" />
+ <ClInclude Include="..\..\..\src\gestures.h" />
+ <ClInclude Include="..\..\..\src\raylib.h" />
+ <ClInclude Include="..\..\..\src\raymath.h" />
+ <ClInclude Include="..\..\..\src\rlgl.h" />
+ <ClInclude Include="..\..\..\src\shader_distortion.h" />
+ <ClInclude Include="..\..\..\src\shader_standard.h" />
+ <ClInclude Include="..\..\..\src\utils.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/raylib.pc.in b/raylib.pc.in
new file mode 100644
index 00000000..93984363
--- /dev/null
+++ b/raylib.pc.in
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: raylib
+Description: Simple and easy-to-use library to learn videogames programming
+URL: http://github.com/raysan5/raylib
+Version: @PROJECT_VERSION@
+Libs: -L${libdir} -lraylib
+Libs.private:@PKG_CONFIG_LIBS_PRIVATE@
+Requires.private:
+Cflags: -I${includedir}
diff --git a/release/libs/win32/mingw32/raylib.h b/release/libs/win32/mingw32/raylib.h
deleted file mode 100644
index 392e0a24..00000000
--- a/release/libs/win32/mingw32/raylib.h
+++ /dev/null
@@ -1,1168 +0,0 @@
-/**********************************************************************************************
-*
-* raylib v1.8.0
-*
-* A simple and easy-to-use library to learn videogames programming (www.raylib.com)
-*
-* FEATURES:
-* - Written in plain C code (C99) in PascalCase/camelCase notation
-* - Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi and HTML5
-* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES 2.0)
-* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
-* - Powerful fonts module with SpriteFonts support (XNA bitmap fonts, AngelCode fonts, TTF)
-* - Outstanding texture formats support, including compressed formats (DXT, ETC, PVRT, ASTC)
-* - Basic 3d support for Geometrics, Models, Billboards, Heightmaps and Cubicmaps
-* - Flexible Materials system, supporting classic maps and PBR maps
-* - Shaders support, including Model shaders and Postprocessing shaders
-* - Powerful math module for Vector2, Vector3, Matrix and Quaternion operations: [raymath]
-* - Audio loading and playing with streaming support and mixing channels: [audio]
-* - VR stereo rendering support with configurable HMD device parameters
-* - Minimal external dependencies (GLFW3, OpenGL, OpenAL)
-* - Complete bindings to LUA (raylib-lua) and Go (raylib-go)
-*
-* NOTES:
-* One custom font is loaded by default when InitWindow() [core]
-* If using OpenGL 3.3 or ES2, one default shader is loaded automatically (internally defined) [rlgl]
-* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
-*
-* DEPENDENCIES:
-* GLFW3 (www.glfw.org) for window/context management and input [core]
-* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
-* OpenAL Soft for audio device/context management [audio]
-*
-* OPTIONAL DEPENDENCIES:
-* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures]
-* stb_image_resize (Sean Barret) for image resizing algorythms [textures]
-* stb_image_write (Sean Barret) for image writting (PNG) [utils]
-* stb_truetype (Sean Barret) for ttf fonts loading [text]
-* stb_vorbis (Sean Barret) for ogg audio loading [audio]
-* stb_perlin (Sean Barret) for Perlin noise image generation [textures]
-* par_shapes (Philip Rideout) for parametric 3d shapes generation [models]
-* jar_xm (Joshua Reisenauer) for XM audio module loading [audio]
-* jar_mod (Joshua Reisenauer) for MOD audio module loading [audio]
-* dr_flac (David Reid) for FLAC audio file loading [audio]
-* rgif (Charlie Tangora, Ramon Santamaria) for GIF recording [core]
-* tinfl for data decompression (DEFLATE algorithm) [rres]
-*
-*
-* LICENSE: zlib/libpng
-*
-* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
-* BSD-like license that allows static linking with closed source software:
-*
-* Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
-*
-* 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.
-*
-**********************************************************************************************/
-
-#ifndef RAYLIB_H
-#define RAYLIB_H
-
-// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
-//#define PLATFORM_DESKTOP // Windows, Linux or OSX
-//#define PLATFORM_ANDROID // Android device
-//#define PLATFORM_RPI // Raspberry Pi
-//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
-
-// Security check in case no PLATFORM_* defined
-#if !defined(PLATFORM_DESKTOP) && \
- !defined(PLATFORM_ANDROID) && \
- !defined(PLATFORM_RPI) && \
- !defined(PLATFORM_WEB)
- #define PLATFORM_DESKTOP
-#endif
-
-#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
- #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 shared library (.dll)
-#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
- #define RLAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
-#else
- #define RLAPI // We are building or using raylib as a static library (or Linux shared library)
-#endif
-
-//----------------------------------------------------------------------------------
-// Some basic Defines
-//----------------------------------------------------------------------------------
-#ifndef PI
- #define PI 3.14159265358979323846f
-#endif
-
-#define DEG2RAD (PI/180.0f)
-#define RAD2DEG (180.0f/PI)
-
-// raylib Config Flags
-#define FLAG_SHOW_LOGO 1 // Set to show raylib logo at startup
-#define FLAG_FULLSCREEN_MODE 2 // Set to run program in fullscreen
-#define FLAG_WINDOW_RESIZABLE 4 // Set to allow resizable window
-#define FLAG_WINDOW_DECORATED 8 // Set to show window decoration (frame and buttons)
-#define FLAG_WINDOW_TRANSPARENT 16 // Set to allow transparent window
-#define FLAG_MSAA_4X_HINT 32 // Set to try enabling MSAA 4X
-#define FLAG_VSYNC_HINT 64 // Set to try enabling V-Sync on GPU
-
-// Keyboard Function Keys
-#define KEY_SPACE 32
-#define KEY_ESCAPE 256
-#define KEY_ENTER 257
-#define KEY_BACKSPACE 259
-#define KEY_RIGHT 262
-#define KEY_LEFT 263
-#define KEY_DOWN 264
-#define KEY_UP 265
-#define KEY_F1 290
-#define KEY_F2 291
-#define KEY_F3 292
-#define KEY_F4 293
-#define KEY_F5 294
-#define KEY_F6 295
-#define KEY_F7 296
-#define KEY_F8 297
-#define KEY_F9 298
-#define KEY_F10 299
-#define KEY_F11 300
-#define KEY_F12 301
-#define KEY_LEFT_SHIFT 340
-#define KEY_LEFT_CONTROL 341
-#define KEY_LEFT_ALT 342
-#define KEY_RIGHT_SHIFT 344
-#define KEY_RIGHT_CONTROL 345
-#define KEY_RIGHT_ALT 346
-
-// Keyboard Alpha Numeric Keys
-#define KEY_ZERO 48
-#define KEY_ONE 49
-#define KEY_TWO 50
-#define KEY_THREE 51
-#define KEY_FOUR 52
-#define KEY_FIVE 53
-#define KEY_SIX 54
-#define KEY_SEVEN 55
-#define KEY_EIGHT 56
-#define KEY_NINE 57
-#define KEY_A 65
-#define KEY_B 66
-#define KEY_C 67
-#define KEY_D 68
-#define KEY_E 69
-#define KEY_F 70
-#define KEY_G 71
-#define KEY_H 72
-#define KEY_I 73
-#define KEY_J 74
-#define KEY_K 75
-#define KEY_L 76
-#define KEY_M 77
-#define KEY_N 78
-#define KEY_O 79
-#define KEY_P 80
-#define KEY_Q 81
-#define KEY_R 82
-#define KEY_S 83
-#define KEY_T 84
-#define KEY_U 85
-#define KEY_V 86
-#define KEY_W 87
-#define KEY_X 88
-#define KEY_Y 89
-#define KEY_Z 90
-
-#if defined(PLATFORM_ANDROID)
- // Android Physical Buttons
- #define KEY_BACK 4
- #define KEY_MENU 82
- #define KEY_VOLUME_UP 24
- #define KEY_VOLUME_DOWN 25
-#endif
-
-// Mouse Buttons
-#define MOUSE_LEFT_BUTTON 0
-#define MOUSE_RIGHT_BUTTON 1
-#define MOUSE_MIDDLE_BUTTON 2
-
-// Touch points registered
-#define MAX_TOUCH_POINTS 2
-
-// Gamepad Number
-#define GAMEPAD_PLAYER1 0
-#define GAMEPAD_PLAYER2 1
-#define GAMEPAD_PLAYER3 2
-#define GAMEPAD_PLAYER4 3
-
-// Gamepad Buttons/Axis
-
-// PS3 USB Controller Buttons
-#define GAMEPAD_PS3_BUTTON_TRIANGLE 0
-#define GAMEPAD_PS3_BUTTON_CIRCLE 1
-#define GAMEPAD_PS3_BUTTON_CROSS 2
-#define GAMEPAD_PS3_BUTTON_SQUARE 3
-#define GAMEPAD_PS3_BUTTON_L1 6
-#define GAMEPAD_PS3_BUTTON_R1 7
-#define GAMEPAD_PS3_BUTTON_L2 4
-#define GAMEPAD_PS3_BUTTON_R2 5
-#define GAMEPAD_PS3_BUTTON_START 8
-#define GAMEPAD_PS3_BUTTON_SELECT 9
-#define GAMEPAD_PS3_BUTTON_UP 24
-#define GAMEPAD_PS3_BUTTON_RIGHT 25
-#define GAMEPAD_PS3_BUTTON_DOWN 26
-#define GAMEPAD_PS3_BUTTON_LEFT 27
-#define GAMEPAD_PS3_BUTTON_PS 12
-
-// PS3 USB Controller Axis
-#define GAMEPAD_PS3_AXIS_LEFT_X 0
-#define GAMEPAD_PS3_AXIS_LEFT_Y 1
-#define GAMEPAD_PS3_AXIS_RIGHT_X 2
-#define GAMEPAD_PS3_AXIS_RIGHT_Y 5
-#define GAMEPAD_PS3_AXIS_L2 3 // [1..-1] (pressure-level)
-#define GAMEPAD_PS3_AXIS_R2 4 // [1..-1] (pressure-level)
-
-// Xbox360 USB Controller Buttons
-#define GAMEPAD_XBOX_BUTTON_A 0
-#define GAMEPAD_XBOX_BUTTON_B 1
-#define GAMEPAD_XBOX_BUTTON_X 2
-#define GAMEPAD_XBOX_BUTTON_Y 3
-#define GAMEPAD_XBOX_BUTTON_LB 4
-#define GAMEPAD_XBOX_BUTTON_RB 5
-#define GAMEPAD_XBOX_BUTTON_SELECT 6
-#define GAMEPAD_XBOX_BUTTON_START 7
-#define GAMEPAD_XBOX_BUTTON_UP 10
-#define GAMEPAD_XBOX_BUTTON_RIGHT 11
-#define GAMEPAD_XBOX_BUTTON_DOWN 12
-#define GAMEPAD_XBOX_BUTTON_LEFT 13
-#define GAMEPAD_XBOX_BUTTON_HOME 8
-
-// Xbox360 USB Controller Axis
-// NOTE: For Raspberry Pi, axis must be reconfigured
-#if defined(PLATFORM_RPI)
- #define GAMEPAD_XBOX_AXIS_LEFT_X 0 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_LEFT_Y 1 // [-1..1] (up->down)
- #define GAMEPAD_XBOX_AXIS_RIGHT_X 3 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_RIGHT_Y 4 // [-1..1] (up->down)
- #define GAMEPAD_XBOX_AXIS_LT 2 // [-1..1] (pressure-level)
- #define GAMEPAD_XBOX_AXIS_RT 5 // [-1..1] (pressure-level)
-#else
- #define GAMEPAD_XBOX_AXIS_LEFT_X 0 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_LEFT_Y 1 // [1..-1] (up->down)
- #define GAMEPAD_XBOX_AXIS_RIGHT_X 2 // [-1..1] (left->right)
- #define GAMEPAD_XBOX_AXIS_RIGHT_Y 3 // [1..-1] (up->down)
- #define GAMEPAD_XBOX_AXIS_LT 4 // [-1..1] (pressure-level)
- #define GAMEPAD_XBOX_AXIS_RT 5 // [-1..1] (pressure-level)
-#endif
-
-// NOTE: MSC C++ compiler does not support compound literals (C99 feature)
-// Plain structures in C++ (without constructors) can be initialized from { } initializers.
-#ifdef __cplusplus
- #define CLITERAL
-#else
- #define CLITERAL (Color)
-#endif
-
-// Some Basic Colors
-// NOTE: Custom raylib color palette for amazing visuals on WHITE background
-#define LIGHTGRAY CLITERAL{ 200, 200, 200, 255 } // Light Gray
-#define GRAY CLITERAL{ 130, 130, 130, 255 } // Gray
-#define DARKGRAY CLITERAL{ 80, 80, 80, 255 } // Dark Gray
-#define YELLOW CLITERAL{ 253, 249, 0, 255 } // Yellow
-#define GOLD CLITERAL{ 255, 203, 0, 255 } // Gold
-#define ORANGE CLITERAL{ 255, 161, 0, 255 } // Orange
-#define PINK CLITERAL{ 255, 109, 194, 255 } // Pink
-#define RED CLITERAL{ 230, 41, 55, 255 } // Red
-#define MAROON CLITERAL{ 190, 33, 55, 255 } // Maroon
-#define GREEN CLITERAL{ 0, 228, 48, 255 } // Green
-#define LIME CLITERAL{ 0, 158, 47, 255 } // Lime
-#define DARKGREEN CLITERAL{ 0, 117, 44, 255 } // Dark Green
-#define SKYBLUE CLITERAL{ 102, 191, 255, 255 } // Sky Blue
-#define BLUE CLITERAL{ 0, 121, 241, 255 } // Blue
-#define DARKBLUE CLITERAL{ 0, 82, 172, 255 } // Dark Blue
-#define PURPLE CLITERAL{ 200, 122, 255, 255 } // Purple
-#define VIOLET CLITERAL{ 135, 60, 190, 255 } // Violet
-#define DARKPURPLE CLITERAL{ 112, 31, 126, 255 } // Dark Purple
-#define BEIGE CLITERAL{ 211, 176, 131, 255 } // Beige
-#define BROWN CLITERAL{ 127, 106, 79, 255 } // Brown
-#define DARKBROWN CLITERAL{ 76, 63, 47, 255 } // Dark Brown
-
-#define WHITE CLITERAL{ 255, 255, 255, 255 } // White
-#define BLACK CLITERAL{ 0, 0, 0, 255 } // Black
-#define BLANK CLITERAL{ 0, 0, 0, 0 } // Blank (Transparent)
-#define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta
-#define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo)
-
-// Shader and material limits
-#define MAX_SHADER_LOCATIONS 32 // Maximum number of predefined locations stored in shader struct
-#define MAX_MATERIAL_MAPS 12 // Maximum number of texture maps stored in shader struct
-
-//----------------------------------------------------------------------------------
-// Structures Definition
-//----------------------------------------------------------------------------------
-#ifndef __cplusplus
-// Boolean type
- #ifndef bool
- typedef enum { false, true } bool;
- #endif
-#endif
-
-// Vector2 type
-typedef struct Vector2 {
- float x;
- float y;
-} Vector2;
-
-// Vector3 type
-typedef struct Vector3 {
- float x;
- float y;
- float z;
-} Vector3;
-
-// Matrix type (OpenGL style 4x4 - right handed, column major)
-typedef struct Matrix {
- float m0, m4, m8, m12;
- float m1, m5, m9, m13;
- float m2, m6, m10, m14;
- float m3, m7, m11, m15;
-} Matrix;
-
-// Color type, RGBA (32bit)
-typedef struct Color {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
-} Color;
-
-// Rectangle type
-typedef struct Rectangle {
- int x;
- int y;
- int width;
- int height;
-} Rectangle;
-
-// Image type, bpp always RGBA (32bit)
-// NOTE: Data stored in CPU memory (RAM)
-typedef struct Image {
- void *data; // Image raw data
- int width; // Image base width
- int height; // Image base height
- int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat type)
-} Image;
-
-// Texture2D type
-// NOTE: Data stored in GPU memory
-typedef struct Texture2D {
- unsigned int id; // OpenGL texture id
- int width; // Texture base width
- int height; // Texture base height
- int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat type)
-} Texture2D;
-
-// RenderTexture2D type, for texture rendering
-typedef struct RenderTexture2D {
- unsigned int id; // OpenGL Framebuffer Object (FBO) id
- Texture2D texture; // Color buffer attachment texture
- Texture2D depth; // Depth buffer attachment texture
-} RenderTexture2D;
-
-// SpriteFont character info
-typedef struct CharInfo {
- int value; // Character value (Unicode)
- Rectangle rec; // Character rectangle in sprite font
- int offsetX; // Character offset X when drawing
- int offsetY; // Character offset Y when drawing
- int advanceX; // Character advance position X
-} CharInfo;
-
-// SpriteFont type, includes texture and charSet array data
-typedef struct SpriteFont {
- Texture2D texture; // Font texture
- int baseSize; // Base size (default chars height)
- int charsCount; // Number of characters
- CharInfo *chars; // Characters info data
-} SpriteFont;
-
-// Camera type, defines a camera position/orientation in 3d space
-typedef struct Camera {
- Vector3 position; // Camera position
- Vector3 target; // Camera target it looks-at
- Vector3 up; // Camera up vector (rotation over its axis)
- float fovy; // Camera field-of-view apperture in Y (degrees)
-} Camera;
-
-// Camera2D type, defines a 2d camera
-typedef struct Camera2D {
- Vector2 offset; // Camera offset (displacement from target)
- Vector2 target; // Camera target (rotation and zoom origin)
- float rotation; // Camera rotation in degrees
- float zoom; // Camera zoom (scaling), should be 1.0f by default
-} Camera2D;
-
-// Bounding box type
-typedef struct BoundingBox {
- Vector3 min; // Minimum vertex box-corner
- Vector3 max; // Maximum vertex box-corner
-} BoundingBox;
-
-// Vertex data definning a mesh
-// NOTE: Data stored in CPU memory (and GPU)
-typedef struct Mesh {
- int vertexCount; // Number of vertices stored in arrays
- int triangleCount; // Number of triangles stored (indexed or not)
-
- float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
- float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
- float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
- float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
- float *tangents; // Vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
- unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
- unsigned short *indices;// Vertex indices (in case vertex data comes indexed)
-
- unsigned int vaoId; // OpenGL Vertex Array Object id
- unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
-} Mesh;
-
-// Shader type (generic)
-typedef struct Shader {
- unsigned int id; // Shader program id
- int locs[MAX_SHADER_LOCATIONS]; // Shader locations array
-} Shader;
-
-// Material texture map
-typedef struct MaterialMap {
- Texture2D texture; // Material map texture
- Color color; // Material map color
- float value; // Material map value
-} MaterialMap;
-
-// Material type (generic)
-typedef struct Material {
- Shader shader; // Material shader
- MaterialMap maps[MAX_MATERIAL_MAPS]; // Material maps
- float *params; // Material generic parameters (if required)
-} Material;
-
-// Model type
-typedef struct Model {
- Mesh mesh; // Vertex data buffers (RAM and VRAM)
- Matrix transform; // Local transform matrix
- Material material; // Shader and textures data
-} Model;
-
-// Ray type (useful for raycast)
-typedef struct Ray {
- Vector3 position; // Ray position (origin)
- Vector3 direction; // Ray direction
-} Ray;
-
-// Raycast hit information
-typedef struct RayHitInfo {
- bool hit; // Did the ray hit something?
- float distance; // Distance to nearest hit
- Vector3 position; // Position of nearest hit
- Vector3 normal; // Surface normal of hit
-} RayHitInfo;
-
-// Wave type, defines audio wave data
-typedef struct Wave {
- unsigned int sampleCount; // Number of samples
- unsigned int sampleRate; // Frequency (samples per second)
- unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
- unsigned int channels; // Number of channels (1-mono, 2-stereo)
- void *data; // Buffer data pointer
-} Wave;
-
-// Sound source type
-typedef struct Sound {
- unsigned int source; // OpenAL audio source id
- unsigned int buffer; // OpenAL audio buffer id
- int format; // OpenAL audio format specifier
-} Sound;
-
-// Music type (file streaming from memory)
-// NOTE: Anything longer than ~10 seconds should be streamed
-typedef struct MusicData *Music;
-
-// Audio stream type
-// NOTE: Useful to create custom audio streams not bound to a specific file
-typedef struct AudioStream {
- unsigned int sampleRate; // Frequency (samples per second)
- unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
- unsigned int channels; // Number of channels (1-mono, 2-stereo)
-
- int format; // OpenAL audio format specifier
- unsigned int source; // OpenAL audio source id
- unsigned int buffers[2]; // OpenAL audio buffers (double buffering)
-} AudioStream;
-
-// rRES data returned when reading a resource,
-// it contains all required data for user (24 byte)
-typedef struct RRESData {
- unsigned int type; // Resource type (4 byte)
-
- unsigned int param1; // Resouce parameter 1 (4 byte)
- unsigned int param2; // Resouce parameter 2 (4 byte)
- unsigned int param3; // Resouce parameter 3 (4 byte)
- unsigned int param4; // Resouce parameter 4 (4 byte)
-
- void *data; // Resource data pointer (4 byte)
-} RRESData;
-
-// RRES type (pointer to RRESData array)
-typedef struct RRESData *RRES;
-
-// Head-Mounted-Display device parameters
-typedef struct VrDeviceInfo {
- int hResolution; // HMD horizontal resolution in pixels
- int vResolution; // HMD vertical resolution in pixels
- float hScreenSize; // HMD horizontal size in meters
- float vScreenSize; // HMD vertical size in meters
- float vScreenCenter; // HMD screen center in meters
- float eyeToScreenDistance; // HMD distance between eye and display in meters
- float lensSeparationDistance; // HMD lens separation distance in meters
- float interpupillaryDistance; // HMD IPD (distance between pupils) in meters
- float lensDistortionValues[4]; // HMD lens distortion constant parameters
- float chromaAbCorrection[4]; // HMD chromatic aberration correction parameters
-} VrDeviceInfo;
-
-//----------------------------------------------------------------------------------
-// Enumerators Definition
-//----------------------------------------------------------------------------------
-// Trace log type
-typedef enum {
- LOG_INFO = 0,
- LOG_WARNING,
- LOG_ERROR,
- LOG_DEBUG,
- LOG_OTHER
-} LogType;
-
-// Shader location point type
-typedef enum {
- LOC_VERTEX_POSITION = 0,
- LOC_VERTEX_TEXCOORD01,
- LOC_VERTEX_TEXCOORD02,
- LOC_VERTEX_NORMAL,
- LOC_VERTEX_TANGENT,
- LOC_VERTEX_COLOR,
- LOC_MATRIX_MVP,
- LOC_MATRIX_MODEL,
- LOC_MATRIX_VIEW,
- LOC_MATRIX_PROJECTION,
- LOC_VECTOR_VIEW,
- LOC_COLOR_DIFFUSE,
- LOC_COLOR_SPECULAR,
- LOC_COLOR_AMBIENT,
- LOC_MAP_ALBEDO, // LOC_MAP_DIFFUSE
- LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
- LOC_MAP_NORMAL,
- LOC_MAP_ROUGHNESS,
- LOC_MAP_OCCUSION,
- LOC_MAP_EMISSION,
- LOC_MAP_HEIGHT,
- LOC_MAP_CUBEMAP,
- LOC_MAP_IRRADIANCE,
- LOC_MAP_PREFILTER,
- LOC_MAP_BRDF
-} ShaderLocationIndex;
-
-#define LOC_MAP_DIFFUSE LOC_MAP_ALBEDO
-#define LOC_MAP_SPECULAR LOC_MAP_METALNESS
-
-// Material map type
-typedef enum {
- MAP_ALBEDO = 0, // MAP_DIFFUSE
- MAP_METALNESS = 1, // MAP_SPECULAR
- MAP_NORMAL = 2,
- MAP_ROUGHNESS = 3,
- MAP_OCCLUSION,
- MAP_EMISSION,
- MAP_HEIGHT,
- MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_BRDF
-} TexmapIndex;
-
-#define MAP_DIFFUSE MAP_ALBEDO
-#define MAP_SPECULAR MAP_METALNESS
-
-// Texture formats
-// NOTE: Support depends on OpenGL version and platform
-typedef enum {
- UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
- UNCOMPRESSED_GRAY_ALPHA, // 16 bpp (2 channels)
- UNCOMPRESSED_R5G6B5, // 16 bpp
- UNCOMPRESSED_R8G8B8, // 24 bpp
- UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
- UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
- UNCOMPRESSED_R8G8B8A8, // 32 bpp
- UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
- COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
- COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
- COMPRESSED_DXT3_RGBA, // 8 bpp
- COMPRESSED_DXT5_RGBA, // 8 bpp
- COMPRESSED_ETC1_RGB, // 4 bpp
- COMPRESSED_ETC2_RGB, // 4 bpp
- COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
- COMPRESSED_PVRT_RGB, // 4 bpp
- COMPRESSED_PVRT_RGBA, // 4 bpp
- COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
- COMPRESSED_ASTC_8x8_RGBA // 2 bpp
-} TextureFormat;
-
-// Texture parameters: filter mode
-// NOTE 1: Filtering considers mipmaps if available in the texture
-// NOTE 2: Filter is accordingly set for minification and magnification
-typedef enum {
- FILTER_POINT = 0, // No filter, just pixel aproximation
- FILTER_BILINEAR, // Linear filtering
- FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
- FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
- FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x
- FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x
-} TextureFilterMode;
-
-// Texture parameters: wrap mode
-typedef enum {
- WRAP_REPEAT = 0,
- WRAP_CLAMP,
- WRAP_MIRROR
-} TextureWrapMode;
-
-// Color blending modes (pre-defined)
-typedef enum {
- BLEND_ALPHA = 0,
- BLEND_ADDITIVE,
- BLEND_MULTIPLIED
-} BlendMode;
-
-// Gestures type
-// NOTE: It could be used as flags to enable only some gestures
-typedef enum {
- GESTURE_NONE = 0,
- GESTURE_TAP = 1,
- GESTURE_DOUBLETAP = 2,
- GESTURE_HOLD = 4,
- GESTURE_DRAG = 8,
- GESTURE_SWIPE_RIGHT = 16,
- GESTURE_SWIPE_LEFT = 32,
- GESTURE_SWIPE_UP = 64,
- GESTURE_SWIPE_DOWN = 128,
- GESTURE_PINCH_IN = 256,
- GESTURE_PINCH_OUT = 512
-} Gestures;
-
-// Camera system modes
-typedef enum {
- CAMERA_CUSTOM = 0,
- CAMERA_FREE,
- CAMERA_ORBITAL,
- CAMERA_FIRST_PERSON,
- CAMERA_THIRD_PERSON
-} CameraMode;
-
-// Head Mounted Display devices
-typedef enum {
- HMD_DEFAULT_DEVICE = 0,
- HMD_OCULUS_RIFT_DK2,
- HMD_OCULUS_RIFT_CV1,
- HMD_OCULUS_GO,
- HMD_VALVE_HTC_VIVE,
- HMD_SONY_PSVR
-} VrDeviceType;
-
-// RRESData type
-typedef enum {
- RRES_TYPE_RAW = 0,
- RRES_TYPE_IMAGE,
- RRES_TYPE_WAVE,
- RRES_TYPE_VERTEX,
- RRES_TYPE_TEXT,
- RRES_TYPE_FONT_IMAGE,
- RRES_TYPE_FONT_CHARDATA, // CharInfo data array
- RRES_TYPE_DIRECTORY
-} RRESDataType;
-
-#ifdef __cplusplus
-extern "C" { // Prevents name mangling of functions
-#endif
-
-//------------------------------------------------------------------------------------
-// Global Variables Definition
-//------------------------------------------------------------------------------------
-// It's lonely here...
-
-//------------------------------------------------------------------------------------
-// Window and Graphics Device Functions (Module: core)
-//------------------------------------------------------------------------------------
-
-// Window-related functions
-#if defined(PLATFORM_ANDROID)
-RLAPI void InitWindow(int width, int height, void *state); // Initialize Android activity
-#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context
-#endif
-RLAPI void CloseWindow(void); // Close window and unload OpenGL context
-RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed
-RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus)
-RLAPI void ToggleFullscreen(void); // Toggle fullscreen mode (only PLATFORM_DESKTOP)
-RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP)
-RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP)
-RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
-RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode)
-RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
-RLAPI int GetScreenWidth(void); // Get current screen width
-RLAPI int GetScreenHeight(void); // Get current screen height
-
-#if !defined(PLATFORM_ANDROID)
-// Cursor-related functions
-RLAPI void ShowCursor(void); // Shows cursor
-RLAPI void HideCursor(void); // Hides cursor
-RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
-RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
-RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
-#endif
-
-// Drawing-related functions
-RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
-RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
-RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
-RLAPI void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera (2D)
-RLAPI void End2dMode(void); // Ends 2D mode with custom camera
-RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode with custom camera (3D)
-RLAPI void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
-RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
-RLAPI void EndTextureMode(void); // Ends drawing to render texture
-
-// Screen-space-related functions
-RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
-RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
-RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
-
-// Timming-related functions
-RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
-RLAPI int GetFPS(void); // Returns current FPS
-RLAPI float GetFrameTime(void); // Returns time in seconds for last frame drawn
-
-// Color-related functions
-RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color
-RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
-RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
-RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
-
-// Math useful functions (available from raymath.h)
-RLAPI float *VectorToFloat(Vector3 vec); // Returns Vector3 as float array
-RLAPI float *MatrixToFloat(Matrix mat); // Returns Matrix as float array
-RLAPI Vector3 Vector3Zero(void); // Vector with components value 0.0f
-RLAPI Vector3 Vector3One(void); // Vector with components value 1.0f
-RLAPI Matrix MatrixIdentity(void); // Returns identity matrix
-
-// Misc. functions
-RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags)
-RLAPI void SetConfigFlags(char flags); // Setup window configuration flags (view FLAGS)
-RLAPI void TraceLog(int logType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
-RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (saved a .png)
-RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
-
-// Files management functions
-RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension
-RLAPI const char *GetExtension(const char *fileName); // Get file extension
-RLAPI const char *GetDirectoryPath(const char *fileName); // Get directory for a given fileName (with path)
-RLAPI const char *GetWorkingDirectory(void); // Get current working directory
-RLAPI bool ChangeDirectory(const char *dir); // Change working directory, returns true if success
-RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
-RLAPI char **GetDroppedFiles(int *count); // Get dropped files names
-RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer
-
-// Persistent storage management
-RLAPI void StorageSaveValue(int position, int value); // Save integer value to storage file (to defined position)
-RLAPI int StorageLoadValue(int position); // Load integer value from storage file (from defined position)
-
-//------------------------------------------------------------------------------------
-// Input Handling Functions (Module: core)
-//------------------------------------------------------------------------------------
-
-// Input-related functions: keyboard
-RLAPI bool IsKeyPressed(int key); // Detect if a key has been pressed once
-RLAPI bool IsKeyDown(int key); // Detect if a key is being pressed
-RLAPI bool IsKeyReleased(int key); // Detect if a key has been released once
-RLAPI bool IsKeyUp(int key); // Detect if a key is NOT being pressed
-RLAPI int GetKeyPressed(void); // Get latest key pressed
-RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
-
-// Input-related functions: gamepads
-RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
-RLAPI bool IsGamepadName(int gamepad, const char *name); // Check gamepad name (if available)
-RLAPI const char *GetGamepadName(int gamepad); // Return gamepad internal name id
-RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
-RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
-RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
-RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
-RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
-RLAPI int GetGamepadAxisCount(int gamepad); // Return gamepad axis count for a gamepad
-RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
-
-// Input-related functions: mouse
-RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
-RLAPI bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
-RLAPI bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
-RLAPI bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
-RLAPI int GetMouseX(void); // Returns mouse position X
-RLAPI int GetMouseY(void); // Returns mouse position Y
-RLAPI Vector2 GetMousePosition(void); // Returns mouse position XY
-RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY
-RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y
-
-// Input-related functions: touch
-RLAPI int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
-RLAPI int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
-RLAPI Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
-
-//------------------------------------------------------------------------------------
-// Gestures and Touch Handling Functions (Module: gestures)
-//------------------------------------------------------------------------------------
-RLAPI void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
-RLAPI bool IsGestureDetected(int gesture); // Check if a gesture have been detected
-RLAPI int GetGestureDetected(void); // Get latest detected gesture
-RLAPI int GetTouchPointsCount(void); // Get touch points count
-RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
-RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
-RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
-RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
-RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
-
-//------------------------------------------------------------------------------------
-// Camera System Functions (Module: camera)
-//------------------------------------------------------------------------------------
-RLAPI void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available)
-RLAPI void UpdateCamera(Camera *camera); // Update camera position for selected mode
-
-RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
-RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
-RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
-RLAPI void SetCameraMoveControls(int frontKey, int backKey,
- int rightKey, int leftKey,
- int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
-
-//------------------------------------------------------------------------------------
-// Basic Shapes Drawing Functions (Module: shapes)
-//------------------------------------------------------------------------------------
-
-// Basic shapes drawing functions
-RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
-RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
-RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
-RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
-RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness
-RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out
-RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
-RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
-RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
-RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
-RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
-RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
-RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
-RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle
-RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
-RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
-RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
-RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
-RLAPI void DrawRectangleT(int posX, int posY, int width, int height, Color color); // Draw rectangle using text character
-RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
-RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
-RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
-RLAPI void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
-RLAPI void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
-
-// Basic shapes collision detection functions
-RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
-RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
-RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
-RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
-RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
-RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
-RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
-
-//------------------------------------------------------------------------------------
-// Texture Loading and Drawing Functions (Module: textures)
-//------------------------------------------------------------------------------------
-
-// Image/Texture2D data loading/unloading/saving functions
-RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
-RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit)
-RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters
-RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
-RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM)
-RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
-RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
-RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
-RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
-RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
-RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
-RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
-RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
-RLAPI void SaveImageAs(const char *fileName, Image image); // Save image to a PNG file
-
-// Image manipulation functions
-RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
-RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
-RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
-RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
-RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
-RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
-RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
-RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
-RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
-RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
-RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
-RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text,
- float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
-RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
-RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
-RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
-RLAPI void ImageColorInvert(Image *image); // Modify image color: invert
-RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale
-RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
-RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
-
-// Image generation functions
-RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom); // Generate image: vertical gradient
-RLAPI Image GenImageGradientH(int width, int height, Color left, Color right); // Generate image: horizontal gradient
-RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
-RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
-RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
-RLAPI Image GenImagePerlinNoise(int width, int height, float scale); // Generate image: perlin noise
-RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm. Bigger tileSize means bigger cells
-
-// Texture2D configuration functions
-RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture
-RLAPI void SetTextureFilter(Texture2D texture, int filterMode); // Set texture scaling filter mode
-RLAPI void SetTextureWrap(Texture2D texture, int wrapMode); // Set texture wrapping mode
-
-// Texture2D drawing functions
-RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
-RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
-RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
-RLAPI void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
-RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
- float rotation, Color tint);
-
-//------------------------------------------------------------------------------------
-// Font Loading and Text Drawing Functions (Module: text)
-//------------------------------------------------------------------------------------
-
-// SpriteFont loading/unloading functions
-RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
-RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM)
-RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters
-RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM)
-
-// Text drawing functions
-RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
-RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
-RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
- float fontSize, int spacing, Color tint);
-
-// Text misc. functions
-RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
-RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
-RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
-RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
-
-//------------------------------------------------------------------------------------
-// Basic 3d Shapes Drawing Functions (Module: models)
-//------------------------------------------------------------------------------------
-
-// Basic geometric 3D shapes drawing functions
-RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
-RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
-RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
-RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
-RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
-RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
-RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
-RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
-RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
-RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
-RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
-RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
-RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
-RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
-RLAPI void DrawGizmo(Vector3 position); // Draw simple gizmo
-//DrawTorus(), DrawTeapot() could be useful?
-
-//------------------------------------------------------------------------------------
-// Model 3d Loading and Drawing Functions (Module: models)
-//------------------------------------------------------------------------------------
-
-// Model loading/unloading functions
-RLAPI Model LoadModel(const char *fileName); // Load model from files (mesh and material)
-RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh
-RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM)
-
-// Mesh loading/unloading functions
-RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
-RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
-
-// Mesh generation functions
-RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
-RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
-RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
-RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
-RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
-RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
-RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
-RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
-RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
-
-// Material loading/unloading functions
-RLAPI Material LoadMaterial(const char *fileName); // Load material from file
-RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
-RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
-
-// Model drawing functions
-RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
-RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis,
- float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
-RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
-RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis,
- float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
-RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
-RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
-RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec,
- Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
-
-// Collision detection functions
-RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
-RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
-RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
-RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
-RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
-RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius,
- Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
-RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
-RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh
-RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
-RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane)
-
-//------------------------------------------------------------------------------------
-// Shaders System Functions (Module: rlgl)
-// NOTE: This functions are useless when using OpenGL 1.1
-//------------------------------------------------------------------------------------
-
-// Shader loading/unloading functions
-RLAPI char *LoadText(const char *fileName); // Load chars array from text file
-RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations
-RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
-
-RLAPI Shader GetShaderDefault(void); // Get default shader
-RLAPI Texture2D GetTextureDefault(void); // Get default texture
-
-// Shader configuration functions
-RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
-RLAPI void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
-RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
-RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
-RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
-
-// Texture maps generation (PBR)
-// NOTE: Required shaders should be provided
-RLAPI Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size); // Generate cubemap texture from HDR texture
-RLAPI Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size); // Generate irradiance texture using cubemap data
-RLAPI Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size); // Generate prefilter texture using cubemap data
-RLAPI Texture2D GenTextureBRDF(Shader shader, Texture2D cubemap, int size); // Generate BRDF texture using cubemap data
-
-// Shading begin/end functions
-RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
-RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
-RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
-RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
-
-// VR control functions
-VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
-void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
-RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
-RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
-RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
-RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
-RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
-RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
-
-//------------------------------------------------------------------------------------
-// Audio Loading and Playing Functions (Module: audio)
-//------------------------------------------------------------------------------------
-
-// Audio device management functions
-RLAPI void InitAudioDevice(void); // Initialize audio device and context
-RLAPI void CloseAudioDevice(void); // Close the audio device and context
-RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
-RLAPI void SetMasterVolume(float volume); // Set master volume (listener)
-
-// Wave/Sound loading/unloading functions
-RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
-RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data
-RLAPI Sound LoadSound(const char *fileName); // Load sound from file
-RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
-RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
-RLAPI void UnloadWave(Wave wave); // Unload wave data
-RLAPI void UnloadSound(Sound sound); // Unload sound
-
-// Wave/Sound management functions
-RLAPI void PlaySound(Sound sound); // Play a sound
-RLAPI void PauseSound(Sound sound); // Pause a sound
-RLAPI void ResumeSound(Sound sound); // Resume a paused sound
-RLAPI void StopSound(Sound sound); // Stop playing a sound
-RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
-RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
-RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
-RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format
-RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave
-RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
-RLAPI float *GetWaveData(Wave wave); // Get samples data from wave as a floats array
-
-// Music management functions
-RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
-RLAPI void UnloadMusicStream(Music music); // Unload music stream
-RLAPI void PlayMusicStream(Music music); // Start music playing
-RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming
-RLAPI void StopMusicStream(Music music); // Stop music playing
-RLAPI void PauseMusicStream(Music music); // Pause music playing
-RLAPI void ResumeMusicStream(Music music); // Resume playing paused music
-RLAPI bool IsMusicPlaying(Music music); // Check if music is playing
-RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level)
-RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level)
-RLAPI void SetMusicLoopCount(Music music, float count); // Set music loop count (loop repeats)
-RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds)
-RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
-
-// AudioStream management functions
-RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize,
- unsigned int channels); // Init audio stream (to stream raw audio pcm data)
-RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
-RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory
-RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
-RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream
-RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream
-RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream
-RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // RAYLIB_H
diff --git a/release/libs/win32/msvc/OpenAL32.dll b/release/libs/win32/msvc/OpenAL32.dll
index 36b986bd..e9a290ce 100644
--- a/release/libs/win32/msvc/OpenAL32.dll
+++ b/release/libs/win32/msvc/OpenAL32.dll
Binary files differ
diff --git a/release/libs/win32/msvc/OpenAL32.lib b/release/libs/win32/msvc/OpenAL32.lib
deleted file mode 100644
index 10c4e7e6..00000000
--- a/release/libs/win32/msvc/OpenAL32.lib
+++ /dev/null
Binary files differ
diff --git a/release/libs/win32/msvc/OpenAL32dll.lib b/release/libs/win32/msvc/OpenAL32dll.lib
new file mode 100644
index 00000000..8b86ce5e
--- /dev/null
+++ b/release/libs/win32/msvc/OpenAL32dll.lib
Binary files differ
diff --git a/release/libs/win32/msvc/libOpenAL32.dll.a b/release/libs/win32/msvc/libOpenAL32.dll.a
deleted file mode 100644
index 6d07e000..00000000
--- a/release/libs/win32/msvc/libOpenAL32.dll.a
+++ /dev/null
Binary files differ
diff --git a/release/libs/win32/msvc/raylib.dll b/release/libs/win32/msvc/raylib.dll
new file mode 100644
index 00000000..b9896ff8
--- /dev/null
+++ b/release/libs/win32/msvc/raylib.dll
Binary files differ
diff --git a/release/libs/win32/msvc/raylibdll.lib b/release/libs/win32/msvc/raylibdll.lib
new file mode 100644
index 00000000..8ad371ae
--- /dev/null
+++ b/release/libs/win32/msvc/raylibdll.lib
Binary files differ
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a398d665..cb8af48d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,14 +2,20 @@
project(raylib)
include("../utils.cmake")
-set(raylib_VERSION_MAJOR 1)
-set(raylib_VERSION_MINOR 8)
+set(PROJECT_VERSION 1.9.1-dev)
set(RAYLIB raylib) # Name of the generated library
-
### Config options ###
-# Build a static or shared raylib?
+# Shared library is always PIC. Static library should be PIC too if linked into a shared library
+set(WITH_PIC OFF CACHE BOOL "Compile static library as position-independent code" OFF)
+# Build a static and/or shared raylib?
set(SHARED_RAYLIB OFF CACHE BOOL "Build raylib as a dynamic library")
+set(STATIC_RAYLIB ON CACHE BOOL "Build raylib as a static library")
+set(MACOS_FATLIB ON CACHE BOOL "Build fat library for both i386 and x86_64 on macOS")
+
+if(NOT (STATIC_RAYLIB OR SHARED_RAYLIB))
+ message(FATAL_ERROR "Nothing to do if both -DSHARED_RAYLIB=OFF and -DSTATIC_RAYLIB=OFF...")
+endif()
# Platform
set(PLATFORM "Desktop" CACHE STRING "Platform to build for.")
@@ -18,8 +24,10 @@ set_property(CACHE PLATFORM PROPERTY STRINGS "Desktop" "Web" "Android" "Raspberr
# OpenGL version
set(OPENGL_VERSION "3.3" CACHE STRING "OpenGL Version to build raylib with")
set_property(CACHE OPENGL_VERSION PROPERTY STRINGS "3.3" "2.1" "1.1" "ES 2.0")
-### Config options ###
+### Config options ###
+include_directories(external/glfw/include)
+include_directories(external/openal/include) # For use with AppVeyor on Windows
# Translate the config options to what raylib wants
if(${PLATFORM} MATCHES "Desktop")
@@ -40,7 +48,12 @@ if(${PLATFORM} MATCHES "Desktop")
# See: https://github.com/raysan5/raylib/issues/341
if(APPLE)
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
+ set_source_files_properties(rglfw.c PROPERTIES COMPILE_FLAGS "-x objective-c")
+ link_libraries("${LIBS_PRIVATE}")
+ elseif(WIN32)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
+
elseif(${PLATFORM} MATCHES "Web")
set(PLATFORM "PLATFORM_WEB")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
@@ -60,6 +73,14 @@ elseif(${PLATFORM} MATCHES "Raspberry Pi")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
endif()
+if(BUILD_MACOS_FATLIB)
+ if (CMAKE_OSX_ARCHITECTURES)
+ message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides BUILD_MACOS_FATLIB=ON")
+ else()
+ SET(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
+ endif()
+endif()
+
# Get the sources together
file(GLOB raylib_sources *.c)
file(GLOB stb_vorbis external/stb_vorbis.c)
@@ -67,43 +88,78 @@ set(sources ${raylib_sources} ${stb_vorbis})
# Which platform?
if(${PLATFORM} MATCHES "PLATFORM_DESKTOP")
- # Build a static or shared raylib?
- # TODO clean this up a bit?
- if(${SHARED_RAYLIB})
- # Shared library
- add_library(${RAYLIB} SHARED ${sources})
-
- # Will link -framework (if on OS X)
- link_os_x_frameworks(raylib)
- else()
- # Static library
- add_library(${RAYLIB} STATIC ${sources})
-
- if(LINUX)
- # On Linux, need to link a few extra things for static
- target_link_libraries(${RAYLIB} m pthread dl)
- target_link_libraries(${RAYLIB} X11 Xrandr Xinerama Xi Xxf86vm Xcursor) # X11 stuff
- endif()
- endif()
-
- # Always need to link OpenAL and OpenGL
+
if(LINUX)
- # Elsewhere (such as Linux), need `-lopenal -lGL`
- target_link_libraries(${RAYLIB} openal)
- target_link_libraries(${RAYLIB} GL)
+ foreach(L ${LIBS_PRIVATE})
+ set(PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE} -l${L}")
+ endforeach(L)
endif()
-
- # Add in GLFW as a linking target
- target_link_libraries(${RAYLIB} glfw)
-
- # Library file & Header
- set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h")
- install(
- TARGETS ${RAYLIB}
- ARCHIVE DESTINATION lib
- LIBRARY DESTINATION lib
- PUBLIC_HEADER DESTINATION include
- )
+
+ if(APPLE)
+ # TODO extract framework location and name from ${LIBS_PRIVATE}
+ # and specify them as -F and -framework instead of hardcoding
+ foreach(F OpenGL OpenAL Cocoa)
+ set(PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE} -framework ${F}")
+ endforeach(F)
+ endif()
+
+ if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ foreach(L ${LIBS_PRIVATE})
+ set(PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE} -l${L}")
+ endforeach(L)
+ endif()
+
+ if(${SHARED_RAYLIB})
+ add_library(${RAYLIB}_shared SHARED ${sources})
+
+ target_compile_definitions(${RAYLIB}_shared
+ PUBLIC ${PLATFORM}
+ PUBLIC ${GRAPHICS}
+ )
+
+ set_property(TARGET ${RAYLIB}_shared PROPERTY POSITION_INDEPENDENT_CODE ON)
+ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+ set(CMAKE_MACOSX_RPATH ON)
+
+ target_link_libraries(${RAYLIB}_shared ${LIBS_PRIVATE})
+ set_target_properties(${RAYLIB}_shared PROPERTIES PUBLIC_HEADER "raylib.h")
+ if(WIN32)
+ install(
+ TARGETS ${RAYLIB}_shared
+ RUNTIME DESTINATION lib
+ PUBLIC_HEADER DESTINATION include
+ )
+ else() # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows
+ set_target_properties(${RAYLIB}_shared PROPERTIES OUTPUT_NAME ${RAYLIB})
+ install(
+ TARGETS ${RAYLIB}_shared
+ LIBRARY DESTINATION lib
+ PUBLIC_HEADER DESTINATION include
+ )
+ endif()
+ endif(${SHARED_RAYLIB})
+
+ if(${STATIC_RAYLIB})
+ add_library(${RAYLIB} STATIC ${sources})
+
+ target_compile_definitions(${RAYLIB}
+ PUBLIC ${PLATFORM}
+ PUBLIC ${GRAPHICS}
+ )
+
+ if (WITH_PIC)
+ set_property(TARGET ${RAYLIB} PROPERTY POSITION_INDEPENDENT_CODE ON)
+ endif()
+ set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h")
+ install(TARGETS ${RAYLIB}
+ ARCHIVE DESTINATION lib
+ PUBLIC_HEADER DESTINATION include
+ )
+ endif(${STATIC_RAYLIB})
+
+ configure_file(../raylib.pc.in raylib.pc @ONLY)
+ install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION lib/pkgconfig)
# Copy the header files to the build directory
file(COPY "raylib.h" DESTINATION ".")
@@ -116,17 +172,21 @@ elseif(${PLATFORM} MATCHES "PLATFORM_WEB")
add_executable(${RAYLIB} ${sources})
endif()
-
-# Set the compile flags to raylib
-target_compile_definitions(${RAYLIB}
- PUBLIC ${PLATFORM}
- PUBLIC ${GRAPHICS}
-)
-
-
-
# Print the flags for the user
message(STATUS "Compiling with the flags:")
message(STATUS " PLATFORM=" ${PLATFORM})
message(STATUS " GRAPHICS=" ${GRAPHICS})
+# Packaging
+SET(CPACK_PACKAGE_NAME "raylib")
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to learn videogames programming")
+SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
+SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
+SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
+SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
+SET(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/../README.md")
+SET(CPACK_RESOURCE_FILE_WELCOME "${PROJECT_SOURCE_DIR}/../README.md")
+SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE.md")
+SET(CPACK_PACKAGE_FILE_NAME "raylib-${PROJECT_VERSION}$ENV{RAYLIB_PACKAGE_SUFFIX}")
+SET(CPACK_GENERATOR "ZIP;TGZ") # Remove this, if you want the NSIS installer on Windows
+include(CPack)
diff --git a/src/Makefile b/src/Makefile
index 13be7844..2408f0f1 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,10 +3,11 @@
# raylib makefile
#
# Platforms supported:
-# PLATFORM_DESKTOP: Windows (win32/Win64)
+# PLATFORM_DESKTOP: Windows (Win32, Win64)
# PLATFORM_DESKTOP: Linux
-# PLATFORM_DESKTOP: OSX (Mac)
-# PLATFORM_ANDROID: Android (ARM or ARM64)
+# PLATFORM_DESKTOP: OSX/macOS
+# PLATFORM_DESKTOP: FreeBSD
+# PLATFORM_ANDROID: Android (ARM, ARM64)
# PLATFORM_RPI: Raspberry Pi (Raspbian)
# PLATFORM_WEB: HTML5 (Chrome, Firefox)
#
@@ -56,9 +57,12 @@ endif
# Use cross-compiler for PLATFORM_RPI
ifeq ($(PLATFORM),PLATFORM_RPI)
- RPI_CROSS_COMPILE ?= YES
- RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry
- RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot
+ RPI_CROSS_COMPILE ?= NO
+
+ ifeq ($(RPI_CROSS_COMPILE),YES)
+ RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry
+ RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot
+ endif
endif
# Determine if the file has root access (only for installing raylib)
@@ -76,11 +80,19 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
- else
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS=FREEBSD
+ endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
endif
- endif
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ UNAMEOS=$(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS=LINUX
endif
endif
@@ -117,6 +129,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),OSX)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/osx
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/freebsd
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/rpi
@@ -165,6 +180,10 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# OSX default compiler
CC = clang
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # FreeBSD default compiler
+ CC = clang
+ endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
ifeq ($(RPI_CROSS_COMPILE),YES)
@@ -211,7 +230,7 @@ endif
# Define compiler flags:
# -O1 defines optimization level
-# -Og enable debugging
+# -g enable debugging
# -s strip unnecessary data from build
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
@@ -257,7 +276,14 @@ endif
# Define include paths for required headers
# NOTE: Several external required libraries (stb and others)
-INCLUDE_PATHS = -I. -Iexternal -Iexternal/include
+INCLUDE_PATHS = -I. -Iexternal -Iexternal/include -Iexternal/glfw/include
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ INCLUDE_PATHS += -I/usr/local/include
+ LDFLAGS += -L. -Lsrc -L/usr/local/lib -L$(RAYLIB_RELEASE_PATH)
+ endif
+endif
# Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
@@ -290,8 +316,23 @@ endif
# Define all object files required with a wildcard
# The wildcard takes all files that finish with ".c",
# and replaces extentions with ".o", that are the object files
-OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
-OBJS += stb_vorbis.o
+# NOTE: Some objects depend on the PLATFORM to be added or not!
+# OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
+
+# Define object required on compilation
+OBJS = core.o \
+ rlgl.o \
+ shapes.o \
+ textures.o \
+ text.o \
+ models.o \
+ audio.o \
+ stb_vorbis.o \
+ utils.o
+
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ OBJS += rglfw.o
+endif
# Default target entry
all: raylib
@@ -318,21 +359,26 @@ else
ifeq ($(RAYLIB_LIBTYPE),SHARED)
# NOTE: If using OpenAL Soft as static library, all its dependencies must be also linked in the shared library
ifeq ($(PLATFORM_OS),WINDOWS)
- $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/raylib.dll $(OBJS) -L$(RAYLIB_RELEASE_PATH) -lglfw3 -lgdi32 -lopenal32 -lwinmm -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/libraylibdll.a
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/raylib.dll $(OBJS) -L$(RAYLIB_RELEASE_PATH) -lgdi32 -lopenal32 -lwinmm -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/libraylibdll.a
@echo "raylib dynamic library (raylib.dll) and import library (libraylibdll.a) generated!"
@echo "expected OpenAL Soft static library linking"
endif
ifeq ($(PLATFORM_OS),LINUX)
# Compile raylib to shared library version for GNU/Linux.
# WARNING: you should type "make clean" before doing this target
- $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so $(OBJS) -lglfw -lGL -lopenal -lm -lpthread -ldl
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so $(OBJS) -lGL -lopenal -lm -lpthread -ldl
@echo "raylib shared library generated (libraylib.so)!"
endif
ifeq ($(PLATFORM_OS),OSX)
- $(CC) -dynamiclib -o $(RAYLIB_RELEASE_PATH)/libraylib.dylib $(OBJS) -L/usr/local/Cellar/glfw/3.2.1/lib -lglfw -framework OpenGL -framework OpenAL -framework Cocoa
+ $(CC) -dynamiclib -o $(RAYLIB_RELEASE_PATH)/libraylib.dylib $(OBJS) -L/usr/local/Cellar/glfw/3.2.1/lib -framework OpenGL -framework OpenAL -framework Cocoa
install_name_tool -id "libraylib.dylib" $(RAYLIB_RELEASE_PATH)/libraylib.dylib
@echo "raylib shared library generated (libraylib.dylib)!"
endif
+ ifeq ($(PLATFORM_OS),FREEBSD)
+ # WARNING: you should type "gmake clean" before doing this target
+ $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so $(OBJS) -lGL -lopenal -lpthread
+ @echo "raylib shared library generated (libraylib.so)!"
+ endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.so $(OBJS) $(LDFLAGS) $(LDLIBS)
@echo "raylib shared library generated (libraylib.so)!"
@@ -355,6 +401,10 @@ endif
# Compile core module
core.o : core.c raylib.h rlgl.h utils.h raymath.h gestures.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
+
+# Compile rglfw module
+rglfw.o : rglfw.c
+ $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM) -D$(GRAPHICS)
# Compile rlgl module
rlgl.o : rlgl.c rlgl.h raymath.h
diff --git a/src/core.c b/src/core.c
index 5172a710..b3dde142 100644
--- a/src/core.c
+++ b/src/core.c
@@ -3,17 +3,18 @@
* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms
*
* PLATFORMS SUPPORTED:
-* - Windows (win32/Win64)
+* - Windows (Win32, Win64)
* - Linux (tested on Ubuntu)
-* - OSX (Mac)
-* - Android (ARM or ARM64)
+* - FreeBSD
+* - OSX/macOS
+* - Android (ARM, ARM64)
* - Raspberry Pi (Raspbian)
* - HTML5 (Chrome, Firefox)
*
* CONFIGURATION:
*
* #define PLATFORM_DESKTOP
-* Windowing and input system configured for desktop platforms: Windows, Linux, OSX (managed by GLFW3 library)
+* Windowing and input system configured for desktop platforms: Windows, Linux, OSX, FreeBSD (managed by GLFW3 library)
* NOTE: Oculus Rift CV1 requires PLATFORM_DESKTOP for mirror rendering - View [rlgl] module to enable it
*
* #define PLATFORM_ANDROID
@@ -87,6 +88,11 @@
#include "raylib.h"
+#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_S_SOURCE < 199309L
+ #undef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
+#endif
+
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include "utils.h" // Required for: fopen() Android mapping
@@ -109,10 +115,6 @@
#include "external/rgif.h" // Support GIF recording
#endif
-#if defined(__linux__) || defined(PLATFORM_WEB)
- #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
-#endif
-
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Required for: malloc(), free(), rand(), atexit()
#include <stdint.h> // Required for: typedef unsigned long long int uint64_t, used by hi-res timer
@@ -278,10 +280,11 @@ static int renderOffsetY = 0; // Offset Y from render area (must b
static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP)
static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size)
+static bool cursorHidden = false; // Track if cursor is hidden
+
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-static const char *windowTitle; // Window text title...
+static const char *windowTitle = NULL; // Window text title...
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
-static bool cursorHidden = false; // Track if cursor is hidden
static int screenshotCounter = 0; // Screenshots counter
// Register mouse states
@@ -408,12 +411,13 @@ static void *GamepadThread(void *arg); // Mouse reading thread
//----------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
// Initialize window and OpenGL context
-void InitWindow(int width, int height, const char *title)
+// NOTE: data parameter could be used to pass any kind of required data to the initialization
+void InitWindow(int width, int height, void *data)
{
- TraceLog(LOG_INFO, "Initializing raylib (v1.8.0)");
+ TraceLog(LOG_INFO, "Initializing raylib (v1.9-dev)");
- // Store window title (could be useful...)
- windowTitle = title;
+ // Input data is window title char data
+ windowTitle = (char *)data;
// Init graphics device (display device and OpenGL context)
InitGraphicsDevice(width, height);
@@ -470,15 +474,17 @@ void InitWindow(int width, int height, const char *title)
#endif
#if defined(PLATFORM_ANDROID)
-// Initialize Android activity
-void InitWindow(int width, int height, void *state)
+// Initialize window and OpenGL context (and Android activity)
+// NOTE: data parameter could be used to pass any kind of required data to the initialization
+void InitWindow(int width, int height, void *data)
{
- TraceLog(LOG_INFO, "Initializing raylib (v1.8.0)");
+ TraceLog(LOG_INFO, "Initializing raylib (v1.9-dev)");
screenWidth = width;
screenHeight = height;
- app = (struct android_app *)state;
+ // Input data is android app pointer
+ app = (struct android_app *)data;
internalDataPath = app->activity->internalDataPath;
// Set desired windows flags before initializing anything
@@ -507,7 +513,6 @@ void InitWindow(int width, int height, void *state)
//AConfiguration_getScreenSize(app->config);
//AConfiguration_getScreenLong(app->config);
- //state->userData = &engine;
app->onAppCmd = AndroidCommandCallback;
app->onInputEvent = AndroidInputCallback;
@@ -708,7 +713,6 @@ int GetScreenHeight(void)
return screenHeight;
}
-#if !defined(PLATFORM_ANDROID)
// Show mouse cursor
void ShowCursor()
{
@@ -771,7 +775,6 @@ void DisableCursor()
#endif
cursorHidden = true;
}
-#endif // !defined(PLATFORM_ANDROID)
// Set background color (framebuffer clear color)
void ClearBackground(Color color)
@@ -1108,9 +1111,7 @@ Color Fade(Color color, float alpha)
if (alpha < 0.0f) alpha = 0.0f;
else if (alpha > 1.0f) alpha = 1.0f;
- float colorAlpha = (float)color.a*alpha;
-
- return (Color){color.r, color.g, color.b, (unsigned char)colorAlpha};
+ return (Color){color.r, color.g, color.b, (unsigned char)(255.0f*alpha)};
}
// Activate raylib logo at startup (can be done with flags)
@@ -2525,6 +2526,8 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
rlClearScreenBuffers(); // Clear screen buffers (color and depth)
// Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
+ // NOTE: Be careful! GLFW3 will choose the closest fullscreen resolution supported by current monitor,
+ // for example, if reescaling back to 800x450 (desired), it could set 720x480 (closest fullscreen supported)
screenWidth = width;
screenHeight = height;
renderWidth = width;
@@ -2776,8 +2779,16 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
ProcessGestureEvent(gestureEvent);
#else
- // TODO: Support only simple touch position
-
+ // Support only simple touch position
+ if (flags == AMOTION_EVENT_ACTION_DOWN)
+ {
+ // Get first touch position
+ touchPosition[0].x = AMotionEvent_getX(event, 0);
+ touchPosition[0].y = AMotionEvent_getY(event, 0);
+
+ touchPosition[0].x /= (float)GetScreenWidth();
+ touchPosition[0].y /= (float)GetScreenHeight();
+ }
#endif
return 0;
diff --git a/project/vs2015/external/glfw3/COPYING.txt b/src/external/glfw/LICENSE.md
index ad16462a..e4c6682e 100644
--- a/project/vs2015/external/glfw3/COPYING.txt
+++ b/src/external/glfw/LICENSE.md
@@ -1,5 +1,5 @@
-Copyright (c) 2002-2006 Marcus Geelnard
-Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
+Copyright (c) 2002-2006 Marcus Geelnard
+Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff --git a/src/external/glfw/README.md b/src/external/glfw/README.md
new file mode 100644
index 00000000..4048baf1
--- /dev/null
+++ b/src/external/glfw/README.md
@@ -0,0 +1,435 @@
+# GLFW
+
+[![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/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)
+
+## Introduction
+
+GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
+application development. It provides a simple, platform-independent API for
+creating windows, contexts and surfaces, reading input, handling events, etc.
+
+GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
+Experimental implementations for the Wayland protocol and the Mir display server
+are available but not yet officially supported.
+
+GLFW is licensed under the [zlib/libpng
+license](http://www.glfw.org/license.html).
+
+The latest stable release is version 3.2.1.
+
+See the [downloads](http://www.glfw.org/download.html) page for details and
+files, or fetch the `latest` branch, which always points to the latest stable
+release. Each release starting with 3.0 also has a corresponding [annotated
+tag](https://github.com/glfw/glfw/releases) with source and binary archives.
+The [version history](http://www.glfw.org/changelog.html) lists all user-visible
+changes for every release.
+
+This is a development branch for version 3.3, which is _not yet described_.
+Pre-release documentation is available [here](http://www.glfw.org/docs/3.3/).
+
+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
+change until they have been included in a release. New features and many bug
+fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
+they are stable enough to merge.
+
+If you are new to GLFW, you may find the
+[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
+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
+3 API.
+
+
+## Compiling GLFW
+
+GLFW itself requires only the headers and libraries for your window system. It
+does not need the headers for any context creation API (WGL, GLX, EGL, NSGL,
+OSMesa) or rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
+
+GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
+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
+not regularly tested.
+
+There are [pre-compiled Windows binaries](http://www.glfw.org/download.html)
+available for all supported compilers.
+
+See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) for
+more information about how to compile GLFW yourself.
+
+
+## Using GLFW
+
+See the [documentation](http://www.glfw.org/docs/latest/) for tutorials, guides
+and the API reference.
+
+
+## Contributing to GLFW
+
+See the [contribution
+guide](https://github.com/glfw/glfw/blob/master/.github/CONTRIBUTING.md) for
+more information.
+
+
+## System requirements
+
+GLFW supports Windows XP and later and macOS 10.7 and later. Linux and other
+Unix-like systems running the X Window System are supported even without
+a desktop environment or modern extensions, although some features require
+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)
+in the documentation for more information.
+
+
+## Dependencies
+
+GLFW itself depends only on the headers and libraries for your 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
+located in the `deps/` directory.
+
+ - [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
+ with command-line options
+ - [TinyCThread](https://github.com/tinycthread/tinycthread) for threaded
+ examples
+ - An OpenGL 3.2 core loader generated by
+ [glad](https://github.com/Dav1dde/glad) for examples using modern OpenGL
+ - [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
+ examples
+ - [Nuklear](https://github.com/vurtun/nuklear) for test and example UI
+ - [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
+ - [Vulkan headers](https://www.khronos.org/registry/vulkan/) for Vulkan tests
+
+The Vulkan example additionally requires the Vulkan SDK to be installed, or it
+will not be included in the build. On macOS you need to provide the path to the
+MoltenVK SDK manually as it has no standard installation location.
+
+The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can
+find that tool.
+
+
+## Reporting bugs
+
+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/.github/CONTRIBUTING.md) for
+information on what to include when reporting a bug.
+
+
+## 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` and `glfwGetMonitorContentScale` for
+ DPI-aware rendering (#235,#439,#677,#845,#898)
+- Added `glfwRequestWindowAttention` function for requesting attention from the
+ user (#732,#988)
+- 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` and `glfwInitHintString` for setting initialization hints
+- 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` window hint for enabling window framebuffer
+ transparency (#197,#663,#715,#723,#1078)
+- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
+ (#749,#842)
+- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
+- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
+- Added macOS specific `GLFW_COCOA_FRAME_AUTOSAVE` 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_WM_CLASS_NAME` and `GLFW_X11_WM_CLASS_CLASS` init
+ hints (#893)
+- 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
+- Removed `GLFW_USE_RETINA` compile-time option
+- Removed `GLFW_USE_CHDIR` compile-time option
+- Removed `GLFW_USE_MENUBAR` compile-time option
+- 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)
+- [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)
+- [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
+- [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)
+- [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
+
+
+## Contact
+
+On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as
+well as news, documentation and other information about the project.
+
+If you have questions related to the use of GLFW, we have a
+[forum](http://discourse.glfw.org/), and the `#glfw` IRC channel on
+[Freenode](http://freenode.net/).
+
+If you have a bug to report, a patch to submit or a feature you'd like to
+request, please file it in the
+[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
+
+Finally, if you're interested in helping out with the development of GLFW or
+porting it to your favorite platform, join us on the forum, GitHub or IRC.
+
+
+## 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
+ - Niklas Behrens
+ - 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
+ - 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
+ - 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
+ - Tristam MacDonald
+ - Hans Mackowiak
+ - Дмитри Малышев
+ - Zbigniew Mandziejewicz
+ - 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
+ - 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
+ - Alexandre Pretyman
+ - Philip Rideout
+ - Eddie Ringle
+ - 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
+ - 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
+ - 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
+
diff --git a/src/external/glfw/deps/mingw/_mingw_dxhelper.h b/src/external/glfw/deps/mingw/_mingw_dxhelper.h
new file mode 100644
index 00000000..849e2914
--- /dev/null
+++ b/src/external/glfw/deps/mingw/_mingw_dxhelper.h
@@ -0,0 +1,117 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
+#define NONAMELESSUNION 1
+#endif
+#if defined(NONAMELESSSTRUCT) && \
+ !defined(NONAMELESSUNION)
+#define NONAMELESSUNION 1
+#endif
+#if defined(NONAMELESSUNION) && \
+ !defined(NONAMELESSSTRUCT)
+#define NONAMELESSSTRUCT 1
+#endif
+#if !defined(__GNU_EXTENSION)
+#if defined(__GNUC__) || defined(__GNUG__)
+#define __GNU_EXTENSION __extension__
+#else
+#define __GNU_EXTENSION
+#endif
+#endif /* __extension__ */
+
+#ifndef __ANONYMOUS_DEFINED
+#define __ANONYMOUS_DEFINED
+#if defined(__GNUC__) || defined(__GNUG__)
+#define _ANONYMOUS_UNION __extension__
+#define _ANONYMOUS_STRUCT __extension__
+#else
+#define _ANONYMOUS_UNION
+#define _ANONYMOUS_STRUCT
+#endif
+#ifndef NONAMELESSUNION
+#define _UNION_NAME(x)
+#define _STRUCT_NAME(x)
+#else /* NONAMELESSUNION */
+#define _UNION_NAME(x) x
+#define _STRUCT_NAME(x) x
+#endif
+#endif /* __ANONYMOUS_DEFINED */
+
+#ifndef DUMMYUNIONNAME
+# ifdef NONAMELESSUNION
+# define DUMMYUNIONNAME u
+# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
+# define DUMMYUNIONNAME2 u2
+# define DUMMYUNIONNAME3 u3
+# define DUMMYUNIONNAME4 u4
+# define DUMMYUNIONNAME5 u5
+# define DUMMYUNIONNAME6 u6
+# define DUMMYUNIONNAME7 u7
+# define DUMMYUNIONNAME8 u8
+# define DUMMYUNIONNAME9 u9
+# else /* NONAMELESSUNION */
+# define DUMMYUNIONNAME
+# define DUMMYUNIONNAME1 /* Wine uses this variant */
+# define DUMMYUNIONNAME2
+# define DUMMYUNIONNAME3
+# define DUMMYUNIONNAME4
+# define DUMMYUNIONNAME5
+# define DUMMYUNIONNAME6
+# define DUMMYUNIONNAME7
+# define DUMMYUNIONNAME8
+# define DUMMYUNIONNAME9
+# endif
+#endif /* DUMMYUNIONNAME */
+
+#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
+# ifdef NONAMELESSUNION
+# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
+# else
+# define DUMMYUNIONNAME1 /* Wine uses this variant */
+# endif
+#endif /* DUMMYUNIONNAME1 */
+
+#ifndef DUMMYSTRUCTNAME
+# ifdef NONAMELESSUNION
+# define DUMMYSTRUCTNAME s
+# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
+# define DUMMYSTRUCTNAME2 s2
+# define DUMMYSTRUCTNAME3 s3
+# define DUMMYSTRUCTNAME4 s4
+# define DUMMYSTRUCTNAME5 s5
+# else
+# define DUMMYSTRUCTNAME
+# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
+# define DUMMYSTRUCTNAME2
+# define DUMMYSTRUCTNAME3
+# define DUMMYSTRUCTNAME4
+# define DUMMYSTRUCTNAME5
+# endif
+#endif /* DUMMYSTRUCTNAME */
+
+/* These are for compatibility with the Wine source tree */
+
+#ifndef WINELIB_NAME_AW
+# ifdef __MINGW_NAME_AW
+# define WINELIB_NAME_AW __MINGW_NAME_AW
+# else
+# ifdef UNICODE
+# define WINELIB_NAME_AW(func) func##W
+# else
+# define WINELIB_NAME_AW(func) func##A
+# endif
+# endif
+#endif /* WINELIB_NAME_AW */
+
+#ifndef DECL_WINELIB_TYPE_AW
+# ifdef __MINGW_TYPEDEF_AW
+# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
+# else
+# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
+# endif
+#endif /* DECL_WINELIB_TYPE_AW */
+
diff --git a/src/external/glfw/deps/mingw/dinput.h b/src/external/glfw/deps/mingw/dinput.h
new file mode 100644
index 00000000..b5754802
--- /dev/null
+++ b/src/external/glfw/deps/mingw/dinput.h
@@ -0,0 +1,2467 @@
+/*
+ * Copyright (C) the Wine project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __DINPUT_INCLUDED__
+#define __DINPUT_INCLUDED__
+
+#define COM_NO_WINDOWS_H
+#include <objbase.h>
+#include <_mingw_dxhelper.h>
+
+#ifndef DIRECTINPUT_VERSION
+#define DIRECTINPUT_VERSION 0x0800
+#endif
+
+/* Classes */
+DEFINE_GUID(CLSID_DirectInput, 0x25E609E0,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(CLSID_DirectInputDevice, 0x25E609E1,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+DEFINE_GUID(CLSID_DirectInput8, 0x25E609E4,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(CLSID_DirectInputDevice8, 0x25E609E5,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* Interfaces */
+DEFINE_GUID(IID_IDirectInputA, 0x89521360,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputW, 0x89521361,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput2A, 0x5944E662,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput2W, 0x5944E663,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput7A, 0x9A4CB684,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInput7W, 0x9A4CB685,0x236D,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInput8A, 0xBF798030,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00);
+DEFINE_GUID(IID_IDirectInput8W, 0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00);
+DEFINE_GUID(IID_IDirectInputDeviceA, 0x5944E680,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDeviceW, 0x5944E681,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice2A, 0x5944E682,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice2W, 0x5944E683,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice7A, 0x57D7C6BC,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInputDevice7W, 0x57D7C6BD,0x2356,0x11D3,0x8E,0x9D,0x00,0xC0,0x4F,0x68,0x44,0xAE);
+DEFINE_GUID(IID_IDirectInputDevice8A, 0x54D41080,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79);
+DEFINE_GUID(IID_IDirectInputDevice8W, 0x54D41081,0xDC15,0x4833,0xA4,0x1B,0x74,0x8F,0x73,0xA3,0x81,0x79);
+DEFINE_GUID(IID_IDirectInputEffect, 0xE7E1F7C0,0x88D2,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+
+/* Predefined object types */
+DEFINE_GUID(GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RxAxis,0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RyAxis,0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RzAxis,0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Slider,0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Button,0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Key, 0x55728220,0xD33C,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_POV, 0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Unknown,0xA36D02F3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* Predefined product GUIDs */
+DEFINE_GUID(GUID_SysMouse, 0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboard, 0x6F1D2B61,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Joystick, 0x6F1D2B70,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysMouseEm, 0x6F1D2B80,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysMouseEm2, 0x6F1D2B81,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboardEm, 0x6F1D2B82,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboardEm2,0x6F1D2B83,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* predefined forcefeedback effects */
+DEFINE_GUID(GUID_ConstantForce, 0x13541C20,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_RampForce, 0x13541C21,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Square, 0x13541C22,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Sine, 0x13541C23,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Triangle, 0x13541C24,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_SawtoothUp, 0x13541C25,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_SawtoothDown, 0x13541C26,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Spring, 0x13541C27,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Damper, 0x13541C28,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Inertia, 0x13541C29,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Friction, 0x13541C2A,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_CustomForce, 0x13541C2B,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+
+typedef struct IDirectInputA *LPDIRECTINPUTA;
+typedef struct IDirectInputW *LPDIRECTINPUTW;
+typedef struct IDirectInput2A *LPDIRECTINPUT2A;
+typedef struct IDirectInput2W *LPDIRECTINPUT2W;
+typedef struct IDirectInput7A *LPDIRECTINPUT7A;
+typedef struct IDirectInput7W *LPDIRECTINPUT7W;
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct IDirectInput8A *LPDIRECTINPUT8A;
+typedef struct IDirectInput8W *LPDIRECTINPUT8W;
+#endif /* DI8 */
+typedef struct IDirectInputDeviceA *LPDIRECTINPUTDEVICEA;
+typedef struct IDirectInputDeviceW *LPDIRECTINPUTDEVICEW;
+#if DIRECTINPUT_VERSION >= 0x0500
+typedef struct IDirectInputDevice2A *LPDIRECTINPUTDEVICE2A;
+typedef struct IDirectInputDevice2W *LPDIRECTINPUTDEVICE2W;
+#endif /* DI5 */
+#if DIRECTINPUT_VERSION >= 0x0700
+typedef struct IDirectInputDevice7A *LPDIRECTINPUTDEVICE7A;
+typedef struct IDirectInputDevice7W *LPDIRECTINPUTDEVICE7W;
+#endif /* DI7 */
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct IDirectInputDevice8A *LPDIRECTINPUTDEVICE8A;
+typedef struct IDirectInputDevice8W *LPDIRECTINPUTDEVICE8W;
+#endif /* DI8 */
+#if DIRECTINPUT_VERSION >= 0x0500
+typedef struct IDirectInputEffect *LPDIRECTINPUTEFFECT;
+#endif /* DI5 */
+typedef struct SysKeyboardA *LPSYSKEYBOARDA;
+typedef struct SysMouseA *LPSYSMOUSEA;
+
+#define IID_IDirectInput WINELIB_NAME_AW(IID_IDirectInput)
+#define IDirectInput WINELIB_NAME_AW(IDirectInput)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT)
+#define IID_IDirectInput2 WINELIB_NAME_AW(IID_IDirectInput2)
+#define IDirectInput2 WINELIB_NAME_AW(IDirectInput2)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT2)
+#define IID_IDirectInput7 WINELIB_NAME_AW(IID_IDirectInput7)
+#define IDirectInput7 WINELIB_NAME_AW(IDirectInput7)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT7)
+#if DIRECTINPUT_VERSION >= 0x0800
+#define IID_IDirectInput8 WINELIB_NAME_AW(IID_IDirectInput8)
+#define IDirectInput8 WINELIB_NAME_AW(IDirectInput8)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUT8)
+#endif /* DI8 */
+#define IID_IDirectInputDevice WINELIB_NAME_AW(IID_IDirectInputDevice)
+#define IDirectInputDevice WINELIB_NAME_AW(IDirectInputDevice)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE)
+#if DIRECTINPUT_VERSION >= 0x0500
+#define IID_IDirectInputDevice2 WINELIB_NAME_AW(IID_IDirectInputDevice2)
+#define IDirectInputDevice2 WINELIB_NAME_AW(IDirectInputDevice2)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE2)
+#endif /* DI5 */
+#if DIRECTINPUT_VERSION >= 0x0700
+#define IID_IDirectInputDevice7 WINELIB_NAME_AW(IID_IDirectInputDevice7)
+#define IDirectInputDevice7 WINELIB_NAME_AW(IDirectInputDevice7)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE7)
+#endif /* DI7 */
+#if DIRECTINPUT_VERSION >= 0x0800
+#define IID_IDirectInputDevice8 WINELIB_NAME_AW(IID_IDirectInputDevice8)
+#define IDirectInputDevice8 WINELIB_NAME_AW(IDirectInputDevice8)
+DECL_WINELIB_TYPE_AW(LPDIRECTINPUTDEVICE8)
+#endif /* DI8 */
+
+#define DI_OK S_OK
+#define DI_NOTATTACHED S_FALSE
+#define DI_BUFFEROVERFLOW S_FALSE
+#define DI_PROPNOEFFECT S_FALSE
+#define DI_NOEFFECT S_FALSE
+#define DI_POLLEDDEVICE ((HRESULT)0x00000002L)
+#define DI_DOWNLOADSKIPPED ((HRESULT)0x00000003L)
+#define DI_EFFECTRESTARTED ((HRESULT)0x00000004L)
+#define DI_TRUNCATED ((HRESULT)0x00000008L)
+#define DI_SETTINGSNOTSAVED ((HRESULT)0x0000000BL)
+#define DI_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL)
+#define DI_WRITEPROTECT ((HRESULT)0x00000013L)
+
+#define DIERR_OLDDIRECTINPUTVERSION \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_OLD_WIN_VERSION)
+#define DIERR_BETADIRECTINPUTVERSION \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_RMODE_APP)
+#define DIERR_BADDRIVERVER \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BAD_DRIVER_LEVEL)
+#define DIERR_DEVICENOTREG REGDB_E_CLASSNOTREG
+#define DIERR_NOTFOUND \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND)
+#define DIERR_OBJECTNOTFOUND \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND)
+#define DIERR_INVALIDPARAM E_INVALIDARG
+#define DIERR_NOINTERFACE E_NOINTERFACE
+#define DIERR_GENERIC E_FAIL
+#define DIERR_OUTOFMEMORY E_OUTOFMEMORY
+#define DIERR_UNSUPPORTED E_NOTIMPL
+#define DIERR_NOTINITIALIZED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NOT_READY)
+#define DIERR_ALREADYINITIALIZED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_ALREADY_INITIALIZED)
+#define DIERR_NOAGGREGATION CLASS_E_NOAGGREGATION
+#define DIERR_OTHERAPPHASPRIO E_ACCESSDENIED
+#define DIERR_INPUTLOST \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_READ_FAULT)
+#define DIERR_ACQUIRED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BUSY)
+#define DIERR_NOTACQUIRED \
+ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INVALID_ACCESS)
+#define DIERR_READONLY E_ACCESSDENIED
+#define DIERR_HANDLEEXISTS E_ACCESSDENIED
+#ifndef E_PENDING
+#define E_PENDING 0x8000000AL
+#endif
+#define DIERR_INSUFFICIENTPRIVS 0x80040200L
+#define DIERR_DEVICEFULL 0x80040201L
+#define DIERR_MOREDATA 0x80040202L
+#define DIERR_NOTDOWNLOADED 0x80040203L
+#define DIERR_HASEFFECTS 0x80040204L
+#define DIERR_NOTEXCLUSIVEACQUIRED 0x80040205L
+#define DIERR_INCOMPLETEEFFECT 0x80040206L
+#define DIERR_NOTBUFFERED 0x80040207L
+#define DIERR_EFFECTPLAYING 0x80040208L
+#define DIERR_UNPLUGGED 0x80040209L
+#define DIERR_REPORTFULL 0x8004020AL
+#define DIERR_MAPFILEFAIL 0x8004020BL
+
+#define DIENUM_STOP 0
+#define DIENUM_CONTINUE 1
+
+#define DIEDFL_ALLDEVICES 0x00000000
+#define DIEDFL_ATTACHEDONLY 0x00000001
+#define DIEDFL_FORCEFEEDBACK 0x00000100
+#define DIEDFL_INCLUDEALIASES 0x00010000
+#define DIEDFL_INCLUDEPHANTOMS 0x00020000
+#define DIEDFL_INCLUDEHIDDEN 0x00040000
+
+#define DIDEVTYPE_DEVICE 1
+#define DIDEVTYPE_MOUSE 2
+#define DIDEVTYPE_KEYBOARD 3
+#define DIDEVTYPE_JOYSTICK 4
+#define DIDEVTYPE_HID 0x00010000
+
+#define DI8DEVCLASS_ALL 0
+#define DI8DEVCLASS_DEVICE 1
+#define DI8DEVCLASS_POINTER 2
+#define DI8DEVCLASS_KEYBOARD 3
+#define DI8DEVCLASS_GAMECTRL 4
+
+#define DI8DEVTYPE_DEVICE 0x11
+#define DI8DEVTYPE_MOUSE 0x12
+#define DI8DEVTYPE_KEYBOARD 0x13
+#define DI8DEVTYPE_JOYSTICK 0x14
+#define DI8DEVTYPE_GAMEPAD 0x15
+#define DI8DEVTYPE_DRIVING 0x16
+#define DI8DEVTYPE_FLIGHT 0x17
+#define DI8DEVTYPE_1STPERSON 0x18
+#define DI8DEVTYPE_DEVICECTRL 0x19
+#define DI8DEVTYPE_SCREENPOINTER 0x1A
+#define DI8DEVTYPE_REMOTE 0x1B
+#define DI8DEVTYPE_SUPPLEMENTAL 0x1C
+
+#define DIDEVTYPEMOUSE_UNKNOWN 1
+#define DIDEVTYPEMOUSE_TRADITIONAL 2
+#define DIDEVTYPEMOUSE_FINGERSTICK 3
+#define DIDEVTYPEMOUSE_TOUCHPAD 4
+#define DIDEVTYPEMOUSE_TRACKBALL 5
+
+#define DIDEVTYPEKEYBOARD_UNKNOWN 0
+#define DIDEVTYPEKEYBOARD_PCXT 1
+#define DIDEVTYPEKEYBOARD_OLIVETTI 2
+#define DIDEVTYPEKEYBOARD_PCAT 3
+#define DIDEVTYPEKEYBOARD_PCENH 4
+#define DIDEVTYPEKEYBOARD_NOKIA1050 5
+#define DIDEVTYPEKEYBOARD_NOKIA9140 6
+#define DIDEVTYPEKEYBOARD_NEC98 7
+#define DIDEVTYPEKEYBOARD_NEC98LAPTOP 8
+#define DIDEVTYPEKEYBOARD_NEC98106 9
+#define DIDEVTYPEKEYBOARD_JAPAN106 10
+#define DIDEVTYPEKEYBOARD_JAPANAX 11
+#define DIDEVTYPEKEYBOARD_J3100 12
+
+#define DIDEVTYPEJOYSTICK_UNKNOWN 1
+#define DIDEVTYPEJOYSTICK_TRADITIONAL 2
+#define DIDEVTYPEJOYSTICK_FLIGHTSTICK 3
+#define DIDEVTYPEJOYSTICK_GAMEPAD 4
+#define DIDEVTYPEJOYSTICK_RUDDER 5
+#define DIDEVTYPEJOYSTICK_WHEEL 6
+#define DIDEVTYPEJOYSTICK_HEADTRACKER 7
+
+#define DI8DEVTYPEMOUSE_UNKNOWN 1
+#define DI8DEVTYPEMOUSE_TRADITIONAL 2
+#define DI8DEVTYPEMOUSE_FINGERSTICK 3
+#define DI8DEVTYPEMOUSE_TOUCHPAD 4
+#define DI8DEVTYPEMOUSE_TRACKBALL 5
+#define DI8DEVTYPEMOUSE_ABSOLUTE 6
+
+#define DI8DEVTYPEKEYBOARD_UNKNOWN 0
+#define DI8DEVTYPEKEYBOARD_PCXT 1
+#define DI8DEVTYPEKEYBOARD_OLIVETTI 2
+#define DI8DEVTYPEKEYBOARD_PCAT 3
+#define DI8DEVTYPEKEYBOARD_PCENH 4
+#define DI8DEVTYPEKEYBOARD_NOKIA1050 5
+#define DI8DEVTYPEKEYBOARD_NOKIA9140 6
+#define DI8DEVTYPEKEYBOARD_NEC98 7
+#define DI8DEVTYPEKEYBOARD_NEC98LAPTOP 8
+#define DI8DEVTYPEKEYBOARD_NEC98106 9
+#define DI8DEVTYPEKEYBOARD_JAPAN106 10
+#define DI8DEVTYPEKEYBOARD_JAPANAX 11
+#define DI8DEVTYPEKEYBOARD_J3100 12
+
+#define DI8DEVTYPE_LIMITEDGAMESUBTYPE 1
+
+#define DI8DEVTYPEJOYSTICK_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEJOYSTICK_STANDARD 2
+
+#define DI8DEVTYPEGAMEPAD_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEGAMEPAD_STANDARD 2
+#define DI8DEVTYPEGAMEPAD_TILT 3
+
+#define DI8DEVTYPEDRIVING_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEDRIVING_COMBINEDPEDALS 2
+#define DI8DEVTYPEDRIVING_DUALPEDALS 3
+#define DI8DEVTYPEDRIVING_THREEPEDALS 4
+#define DI8DEVTYPEDRIVING_HANDHELD 5
+
+#define DI8DEVTYPEFLIGHT_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPEFLIGHT_STICK 2
+#define DI8DEVTYPEFLIGHT_YOKE 3
+#define DI8DEVTYPEFLIGHT_RC 4
+
+#define DI8DEVTYPE1STPERSON_LIMITED DI8DEVTYPE_LIMITEDGAMESUBTYPE
+#define DI8DEVTYPE1STPERSON_UNKNOWN 2
+#define DI8DEVTYPE1STPERSON_SIXDOF 3
+#define DI8DEVTYPE1STPERSON_SHOOTER 4
+
+#define DI8DEVTYPESCREENPTR_UNKNOWN 2
+#define DI8DEVTYPESCREENPTR_LIGHTGUN 3
+#define DI8DEVTYPESCREENPTR_LIGHTPEN 4
+#define DI8DEVTYPESCREENPTR_TOUCH 5
+
+#define DI8DEVTYPEREMOTE_UNKNOWN 2
+
+#define DI8DEVTYPEDEVICECTRL_UNKNOWN 2
+#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION 3
+#define DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED 4
+
+#define DI8DEVTYPESUPPLEMENTAL_UNKNOWN 2
+#define DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER 3
+#define DI8DEVTYPESUPPLEMENTAL_HEADTRACKER 4
+#define DI8DEVTYPESUPPLEMENTAL_HANDTRACKER 5
+#define DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE 6
+#define DI8DEVTYPESUPPLEMENTAL_SHIFTER 7
+#define DI8DEVTYPESUPPLEMENTAL_THROTTLE 8
+#define DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE 9
+#define DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS 10
+#define DI8DEVTYPESUPPLEMENTAL_DUALPEDALS 11
+#define DI8DEVTYPESUPPLEMENTAL_THREEPEDALS 12
+#define DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS 13
+
+#define GET_DIDEVICE_TYPE(dwDevType) LOBYTE(dwDevType)
+#define GET_DIDEVICE_SUBTYPE(dwDevType) HIBYTE(dwDevType)
+
+typedef struct DIDEVICEOBJECTINSTANCE_DX3A {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ CHAR tszName[MAX_PATH];
+} DIDEVICEOBJECTINSTANCE_DX3A, *LPDIDEVICEOBJECTINSTANCE_DX3A;
+typedef const DIDEVICEOBJECTINSTANCE_DX3A *LPCDIDEVICEOBJECTINSTANCE_DX3A;
+typedef struct DIDEVICEOBJECTINSTANCE_DX3W {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ WCHAR tszName[MAX_PATH];
+} DIDEVICEOBJECTINSTANCE_DX3W, *LPDIDEVICEOBJECTINSTANCE_DX3W;
+typedef const DIDEVICEOBJECTINSTANCE_DX3W *LPCDIDEVICEOBJECTINSTANCE_DX3W;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEOBJECTINSTANCE_DX3)
+
+typedef struct DIDEVICEOBJECTINSTANCEA {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ CHAR tszName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ DWORD dwFFMaxForce;
+ DWORD dwFFForceResolution;
+ WORD wCollectionNumber;
+ WORD wDesignatorIndex;
+ WORD wUsagePage;
+ WORD wUsage;
+ DWORD dwDimension;
+ WORD wExponent;
+ WORD wReserved;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEOBJECTINSTANCEA, *LPDIDEVICEOBJECTINSTANCEA;
+typedef const DIDEVICEOBJECTINSTANCEA *LPCDIDEVICEOBJECTINSTANCEA;
+
+typedef struct DIDEVICEOBJECTINSTANCEW {
+ DWORD dwSize;
+ GUID guidType;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+ WCHAR tszName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ DWORD dwFFMaxForce;
+ DWORD dwFFForceResolution;
+ WORD wCollectionNumber;
+ WORD wDesignatorIndex;
+ WORD wUsagePage;
+ WORD wUsage;
+ DWORD dwDimension;
+ WORD wExponent;
+ WORD wReserved;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEOBJECTINSTANCEW, *LPDIDEVICEOBJECTINSTANCEW;
+typedef const DIDEVICEOBJECTINSTANCEW *LPCDIDEVICEOBJECTINSTANCEW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEOBJECTINSTANCE)
+
+typedef struct DIDEVICEINSTANCE_DX3A {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ CHAR tszInstanceName[MAX_PATH];
+ CHAR tszProductName[MAX_PATH];
+} DIDEVICEINSTANCE_DX3A, *LPDIDEVICEINSTANCE_DX3A;
+typedef const DIDEVICEINSTANCE_DX3A *LPCDIDEVICEINSTANCE_DX3A;
+typedef struct DIDEVICEINSTANCE_DX3W {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ WCHAR tszInstanceName[MAX_PATH];
+ WCHAR tszProductName[MAX_PATH];
+} DIDEVICEINSTANCE_DX3W, *LPDIDEVICEINSTANCE_DX3W;
+typedef const DIDEVICEINSTANCE_DX3W *LPCDIDEVICEINSTANCE_DX3W;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE_DX3)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE_DX3)
+
+typedef struct DIDEVICEINSTANCEA {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ CHAR tszInstanceName[MAX_PATH];
+ CHAR tszProductName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ GUID guidFFDriver;
+ WORD wUsagePage;
+ WORD wUsage;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEINSTANCEA, *LPDIDEVICEINSTANCEA;
+typedef const DIDEVICEINSTANCEA *LPCDIDEVICEINSTANCEA;
+
+typedef struct DIDEVICEINSTANCEW {
+ DWORD dwSize;
+ GUID guidInstance;
+ GUID guidProduct;
+ DWORD dwDevType;
+ WCHAR tszInstanceName[MAX_PATH];
+ WCHAR tszProductName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ GUID guidFFDriver;
+ WORD wUsagePage;
+ WORD wUsage;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEINSTANCEW, *LPDIDEVICEINSTANCEW;
+typedef const DIDEVICEINSTANCEW *LPCDIDEVICEINSTANCEW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE)
+
+typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKA)(LPCDIDEVICEINSTANCEA,LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMDEVICESCALLBACKW)(LPCDIDEVICEINSTANCEW,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESCALLBACK)
+
+#define DIEDBS_MAPPEDPRI1 0x00000001
+#define DIEDBS_MAPPEDPRI2 0x00000002
+#define DIEDBS_RECENTDEVICE 0x00000010
+#define DIEDBS_NEWDEVICE 0x00000020
+
+#define DIEDBSFL_ATTACHEDONLY 0x00000000
+#define DIEDBSFL_THISUSER 0x00000010
+#define DIEDBSFL_FORCEFEEDBACK DIEDFL_FORCEFEEDBACK
+#define DIEDBSFL_AVAILABLEDEVICES 0x00001000
+#define DIEDBSFL_MULTIMICEKEYBOARDS 0x00002000
+#define DIEDBSFL_NONGAMINGDEVICES 0x00004000
+#define DIEDBSFL_VALID 0x00007110
+
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef BOOL (CALLBACK *LPDIENUMDEVICESBYSEMANTICSCBA)(LPCDIDEVICEINSTANCEA,LPDIRECTINPUTDEVICE8A,DWORD,DWORD,LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMDEVICESBYSEMANTICSCBW)(LPCDIDEVICEINSTANCEW,LPDIRECTINPUTDEVICE8W,DWORD,DWORD,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESBYSEMANTICSCB)
+#endif
+
+typedef BOOL (CALLBACK *LPDICONFIGUREDEVICESCALLBACK)(LPUNKNOWN,LPVOID);
+
+typedef BOOL (CALLBACK *LPDIENUMDEVICEOBJECTSCALLBACKA)(LPCDIDEVICEOBJECTINSTANCEA,LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMDEVICEOBJECTSCALLBACKW)(LPCDIDEVICEOBJECTINSTANCEW,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICEOBJECTSCALLBACK)
+
+#if DIRECTINPUT_VERSION >= 0x0500
+typedef BOOL (CALLBACK *LPDIENUMCREATEDEFFECTOBJECTSCALLBACK)(LPDIRECTINPUTEFFECT, LPVOID);
+#endif
+
+#define DIK_ESCAPE 0x01
+#define DIK_1 0x02
+#define DIK_2 0x03
+#define DIK_3 0x04
+#define DIK_4 0x05
+#define DIK_5 0x06
+#define DIK_6 0x07
+#define DIK_7 0x08
+#define DIK_8 0x09
+#define DIK_9 0x0A
+#define DIK_0 0x0B
+#define DIK_MINUS 0x0C /* - on main keyboard */
+#define DIK_EQUALS 0x0D
+#define DIK_BACK 0x0E /* backspace */
+#define DIK_TAB 0x0F
+#define DIK_Q 0x10
+#define DIK_W 0x11
+#define DIK_E 0x12
+#define DIK_R 0x13
+#define DIK_T 0x14
+#define DIK_Y 0x15
+#define DIK_U 0x16
+#define DIK_I 0x17
+#define DIK_O 0x18
+#define DIK_P 0x19
+#define DIK_LBRACKET 0x1A
+#define DIK_RBRACKET 0x1B
+#define DIK_RETURN 0x1C /* Enter on main keyboard */
+#define DIK_LCONTROL 0x1D
+#define DIK_A 0x1E
+#define DIK_S 0x1F
+#define DIK_D 0x20
+#define DIK_F 0x21
+#define DIK_G 0x22
+#define DIK_H 0x23
+#define DIK_J 0x24
+#define DIK_K 0x25
+#define DIK_L 0x26
+#define DIK_SEMICOLON 0x27
+#define DIK_APOSTROPHE 0x28
+#define DIK_GRAVE 0x29 /* accent grave */
+#define DIK_LSHIFT 0x2A
+#define DIK_BACKSLASH 0x2B
+#define DIK_Z 0x2C
+#define DIK_X 0x2D
+#define DIK_C 0x2E
+#define DIK_V 0x2F
+#define DIK_B 0x30
+#define DIK_N 0x31
+#define DIK_M 0x32
+#define DIK_COMMA 0x33
+#define DIK_PERIOD 0x34 /* . on main keyboard */
+#define DIK_SLASH 0x35 /* / on main keyboard */
+#define DIK_RSHIFT 0x36
+#define DIK_MULTIPLY 0x37 /* * on numeric keypad */
+#define DIK_LMENU 0x38 /* left Alt */
+#define DIK_SPACE 0x39
+#define DIK_CAPITAL 0x3A
+#define DIK_F1 0x3B
+#define DIK_F2 0x3C
+#define DIK_F3 0x3D
+#define DIK_F4 0x3E
+#define DIK_F5 0x3F
+#define DIK_F6 0x40
+#define DIK_F7 0x41
+#define DIK_F8 0x42
+#define DIK_F9 0x43
+#define DIK_F10 0x44
+#define DIK_NUMLOCK 0x45
+#define DIK_SCROLL 0x46 /* Scroll Lock */
+#define DIK_NUMPAD7 0x47
+#define DIK_NUMPAD8 0x48
+#define DIK_NUMPAD9 0x49
+#define DIK_SUBTRACT 0x4A /* - on numeric keypad */
+#define DIK_NUMPAD4 0x4B
+#define DIK_NUMPAD5 0x4C
+#define DIK_NUMPAD6 0x4D
+#define DIK_ADD 0x4E /* + on numeric keypad */
+#define DIK_NUMPAD1 0x4F
+#define DIK_NUMPAD2 0x50
+#define DIK_NUMPAD3 0x51
+#define DIK_NUMPAD0 0x52
+#define DIK_DECIMAL 0x53 /* . on numeric keypad */
+#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
+#define DIK_F11 0x57
+#define DIK_F12 0x58
+#define DIK_F13 0x64 /* (NEC PC98) */
+#define DIK_F14 0x65 /* (NEC PC98) */
+#define DIK_F15 0x66 /* (NEC PC98) */
+#define DIK_KANA 0x70 /* (Japanese keyboard) */
+#define DIK_ABNT_C1 0x73 /* / ? on Portugese (Brazilian) keyboards */
+#define DIK_CONVERT 0x79 /* (Japanese keyboard) */
+#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */
+#define DIK_YEN 0x7D /* (Japanese keyboard) */
+#define DIK_ABNT_C2 0x7E /* Numpad . on Portugese (Brazilian) keyboards */
+#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */
+#define DIK_CIRCUMFLEX 0x90 /* (Japanese keyboard) */
+#define DIK_AT 0x91 /* (NEC PC98) */
+#define DIK_COLON 0x92 /* (NEC PC98) */
+#define DIK_UNDERLINE 0x93 /* (NEC PC98) */
+#define DIK_KANJI 0x94 /* (Japanese keyboard) */
+#define DIK_STOP 0x95 /* (NEC PC98) */
+#define DIK_AX 0x96 /* (Japan AX) */
+#define DIK_UNLABELED 0x97 /* (J3100) */
+#define DIK_NEXTTRACK 0x99 /* Next Track */
+#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */
+#define DIK_RCONTROL 0x9D
+#define DIK_MUTE 0xA0 /* Mute */
+#define DIK_CALCULATOR 0xA1 /* Calculator */
+#define DIK_PLAYPAUSE 0xA2 /* Play / Pause */
+#define DIK_MEDIASTOP 0xA4 /* Media Stop */
+#define DIK_VOLUMEDOWN 0xAE /* Volume - */
+#define DIK_VOLUMEUP 0xB0 /* Volume + */
+#define DIK_WEBHOME 0xB2 /* Web home */
+#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */
+#define DIK_DIVIDE 0xB5 /* / on numeric keypad */
+#define DIK_SYSRQ 0xB7
+#define DIK_RMENU 0xB8 /* right Alt */
+#define DIK_PAUSE 0xC5 /* Pause */
+#define DIK_HOME 0xC7 /* Home on arrow keypad */
+#define DIK_UP 0xC8 /* UpArrow on arrow keypad */
+#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */
+#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */
+#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */
+#define DIK_END 0xCF /* End on arrow keypad */
+#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */
+#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */
+#define DIK_INSERT 0xD2 /* Insert on arrow keypad */
+#define DIK_DELETE 0xD3 /* Delete on arrow keypad */
+#define DIK_LWIN 0xDB /* Left Windows key */
+#define DIK_RWIN 0xDC /* Right Windows key */
+#define DIK_APPS 0xDD /* AppMenu key */
+#define DIK_POWER 0xDE
+#define DIK_SLEEP 0xDF
+#define DIK_WAKE 0xE3 /* System Wake */
+#define DIK_WEBSEARCH 0xE5 /* Web Search */
+#define DIK_WEBFAVORITES 0xE6 /* Web Favorites */
+#define DIK_WEBREFRESH 0xE7 /* Web Refresh */
+#define DIK_WEBSTOP 0xE8 /* Web Stop */
+#define DIK_WEBFORWARD 0xE9 /* Web Forward */
+#define DIK_WEBBACK 0xEA /* Web Back */
+#define DIK_MYCOMPUTER 0xEB /* My Computer */
+#define DIK_MAIL 0xEC /* Mail */
+#define DIK_MEDIASELECT 0xED /* Media Select */
+
+#define DIK_BACKSPACE DIK_BACK /* backspace */
+#define DIK_NUMPADSTAR DIK_MULTIPLY /* * on numeric keypad */
+#define DIK_LALT DIK_LMENU /* left Alt */
+#define DIK_CAPSLOCK DIK_CAPITAL /* CapsLock */
+#define DIK_NUMPADMINUS DIK_SUBTRACT /* - on numeric keypad */
+#define DIK_NUMPADPLUS DIK_ADD /* + on numeric keypad */
+#define DIK_NUMPADPERIOD DIK_DECIMAL /* . on numeric keypad */
+#define DIK_NUMPADSLASH DIK_DIVIDE /* / on numeric keypad */
+#define DIK_RALT DIK_RMENU /* right Alt */
+#define DIK_UPARROW DIK_UP /* UpArrow on arrow keypad */
+#define DIK_PGUP DIK_PRIOR /* PgUp on arrow keypad */
+#define DIK_LEFTARROW DIK_LEFT /* LeftArrow on arrow keypad */
+#define DIK_RIGHTARROW DIK_RIGHT /* RightArrow on arrow keypad */
+#define DIK_DOWNARROW DIK_DOWN /* DownArrow on arrow keypad */
+#define DIK_PGDN DIK_NEXT /* PgDn on arrow keypad */
+
+#define DIDFT_ALL 0x00000000
+#define DIDFT_RELAXIS 0x00000001
+#define DIDFT_ABSAXIS 0x00000002
+#define DIDFT_AXIS 0x00000003
+#define DIDFT_PSHBUTTON 0x00000004
+#define DIDFT_TGLBUTTON 0x00000008
+#define DIDFT_BUTTON 0x0000000C
+#define DIDFT_POV 0x00000010
+#define DIDFT_COLLECTION 0x00000040
+#define DIDFT_NODATA 0x00000080
+#define DIDFT_ANYINSTANCE 0x00FFFF00
+#define DIDFT_INSTANCEMASK DIDFT_ANYINSTANCE
+#define DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8)
+#define DIDFT_GETTYPE(n) LOBYTE(n)
+#define DIDFT_GETINSTANCE(n) LOWORD((n) >> 8)
+#define DIDFT_FFACTUATOR 0x01000000
+#define DIDFT_FFEFFECTTRIGGER 0x02000000
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIDFT_OUTPUT 0x10000000
+#define DIDFT_VENDORDEFINED 0x04000000
+#define DIDFT_ALIAS 0x08000000
+#endif /* DI5a */
+#ifndef DIDFT_OPTIONAL
+#define DIDFT_OPTIONAL 0x80000000
+#endif
+#define DIDFT_ENUMCOLLECTION(n) ((WORD)(n) << 8)
+#define DIDFT_NOCOLLECTION 0x00FFFF00
+
+#define DIDF_ABSAXIS 0x00000001
+#define DIDF_RELAXIS 0x00000002
+
+#define DIGDD_PEEK 0x00000001
+
+#define DISEQUENCE_COMPARE(dwSq1,cmp,dwSq2) ((int)((dwSq1) - (dwSq2)) cmp 0)
+
+typedef struct DIDEVICEOBJECTDATA_DX3 {
+ DWORD dwOfs;
+ DWORD dwData;
+ DWORD dwTimeStamp;
+ DWORD dwSequence;
+} DIDEVICEOBJECTDATA_DX3,*LPDIDEVICEOBJECTDATA_DX3;
+typedef const DIDEVICEOBJECTDATA_DX3 *LPCDIDEVICEOBJECTDATA_DX3;
+
+typedef struct DIDEVICEOBJECTDATA {
+ DWORD dwOfs;
+ DWORD dwData;
+ DWORD dwTimeStamp;
+ DWORD dwSequence;
+#if(DIRECTINPUT_VERSION >= 0x0800)
+ UINT_PTR uAppData;
+#endif /* DIRECTINPUT_VERSION >= 0x0800 */
+} DIDEVICEOBJECTDATA, *LPDIDEVICEOBJECTDATA;
+typedef const DIDEVICEOBJECTDATA *LPCDIDEVICEOBJECTDATA;
+
+typedef struct _DIOBJECTDATAFORMAT {
+ const GUID *pguid;
+ DWORD dwOfs;
+ DWORD dwType;
+ DWORD dwFlags;
+} DIOBJECTDATAFORMAT, *LPDIOBJECTDATAFORMAT;
+typedef const DIOBJECTDATAFORMAT *LPCDIOBJECTDATAFORMAT;
+
+typedef struct _DIDATAFORMAT {
+ DWORD dwSize;
+ DWORD dwObjSize;
+ DWORD dwFlags;
+ DWORD dwDataSize;
+ DWORD dwNumObjs;
+ LPDIOBJECTDATAFORMAT rgodf;
+} DIDATAFORMAT, *LPDIDATAFORMAT;
+typedef const DIDATAFORMAT *LPCDIDATAFORMAT;
+
+#if DIRECTINPUT_VERSION >= 0x0500
+#define DIDOI_FFACTUATOR 0x00000001
+#define DIDOI_FFEFFECTTRIGGER 0x00000002
+#define DIDOI_POLLED 0x00008000
+#define DIDOI_ASPECTPOSITION 0x00000100
+#define DIDOI_ASPECTVELOCITY 0x00000200
+#define DIDOI_ASPECTACCEL 0x00000300
+#define DIDOI_ASPECTFORCE 0x00000400
+#define DIDOI_ASPECTMASK 0x00000F00
+#endif /* DI5 */
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIDOI_GUIDISUSAGE 0x00010000
+#endif /* DI5a */
+
+typedef struct DIPROPHEADER {
+ DWORD dwSize;
+ DWORD dwHeaderSize;
+ DWORD dwObj;
+ DWORD dwHow;
+} DIPROPHEADER,*LPDIPROPHEADER;
+typedef const DIPROPHEADER *LPCDIPROPHEADER;
+
+#define DIPH_DEVICE 0
+#define DIPH_BYOFFSET 1
+#define DIPH_BYID 2
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIPH_BYUSAGE 3
+
+#define DIMAKEUSAGEDWORD(UsagePage, Usage) (DWORD)MAKELONG(Usage, UsagePage)
+#endif /* DI5a */
+
+typedef struct DIPROPDWORD {
+ DIPROPHEADER diph;
+ DWORD dwData;
+} DIPROPDWORD, *LPDIPROPDWORD;
+typedef const DIPROPDWORD *LPCDIPROPDWORD;
+
+typedef struct DIPROPRANGE {
+ DIPROPHEADER diph;
+ LONG lMin;
+ LONG lMax;
+} DIPROPRANGE, *LPDIPROPRANGE;
+typedef const DIPROPRANGE *LPCDIPROPRANGE;
+
+#define DIPROPRANGE_NOMIN ((LONG)0x80000000)
+#define DIPROPRANGE_NOMAX ((LONG)0x7FFFFFFF)
+
+#if DIRECTINPUT_VERSION >= 0x050a
+typedef struct DIPROPCAL {
+ DIPROPHEADER diph;
+ LONG lMin;
+ LONG lCenter;
+ LONG lMax;
+} DIPROPCAL, *LPDIPROPCAL;
+typedef const DIPROPCAL *LPCDIPROPCAL;
+
+typedef struct DIPROPCALPOV {
+ DIPROPHEADER diph;
+ LONG lMin[5];
+ LONG lMax[5];
+} DIPROPCALPOV, *LPDIPROPCALPOV;
+typedef const DIPROPCALPOV *LPCDIPROPCALPOV;
+
+typedef struct DIPROPGUIDANDPATH {
+ DIPROPHEADER diph;
+ GUID guidClass;
+ WCHAR wszPath[MAX_PATH];
+} DIPROPGUIDANDPATH, *LPDIPROPGUIDANDPATH;
+typedef const DIPROPGUIDANDPATH *LPCDIPROPGUIDANDPATH;
+
+typedef struct DIPROPSTRING {
+ DIPROPHEADER diph;
+ WCHAR wsz[MAX_PATH];
+} DIPROPSTRING, *LPDIPROPSTRING;
+typedef const DIPROPSTRING *LPCDIPROPSTRING;
+#endif /* DI5a */
+
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct DIPROPPOINTER {
+ DIPROPHEADER diph;
+ UINT_PTR uData;
+} DIPROPPOINTER, *LPDIPROPPOINTER;
+typedef const DIPROPPOINTER *LPCDIPROPPOINTER;
+#endif /* DI8 */
+
+/* special property GUIDs */
+#ifdef __cplusplus
+#define MAKEDIPROP(prop) (*(const GUID *)(prop))
+#else
+#define MAKEDIPROP(prop) ((REFGUID)(prop))
+#endif
+#define DIPROP_BUFFERSIZE MAKEDIPROP(1)
+#define DIPROP_AXISMODE MAKEDIPROP(2)
+
+#define DIPROPAXISMODE_ABS 0
+#define DIPROPAXISMODE_REL 1
+
+#define DIPROP_GRANULARITY MAKEDIPROP(3)
+#define DIPROP_RANGE MAKEDIPROP(4)
+#define DIPROP_DEADZONE MAKEDIPROP(5)
+#define DIPROP_SATURATION MAKEDIPROP(6)
+#define DIPROP_FFGAIN MAKEDIPROP(7)
+#define DIPROP_FFLOAD MAKEDIPROP(8)
+#define DIPROP_AUTOCENTER MAKEDIPROP(9)
+
+#define DIPROPAUTOCENTER_OFF 0
+#define DIPROPAUTOCENTER_ON 1
+
+#define DIPROP_CALIBRATIONMODE MAKEDIPROP(10)
+
+#define DIPROPCALIBRATIONMODE_COOKED 0
+#define DIPROPCALIBRATIONMODE_RAW 1
+
+#if DIRECTINPUT_VERSION >= 0x050a
+#define DIPROP_CALIBRATION MAKEDIPROP(11)
+#define DIPROP_GUIDANDPATH MAKEDIPROP(12)
+#define DIPROP_INSTANCENAME MAKEDIPROP(13)
+#define DIPROP_PRODUCTNAME MAKEDIPROP(14)
+#endif
+
+#if DIRECTINPUT_VERSION >= 0x5B2
+#define DIPROP_JOYSTICKID MAKEDIPROP(15)
+#define DIPROP_GETPORTDISPLAYNAME MAKEDIPROP(16)
+#endif
+
+#if DIRECTINPUT_VERSION >= 0x0700
+#define DIPROP_PHYSICALRANGE MAKEDIPROP(18)
+#define DIPROP_LOGICALRANGE MAKEDIPROP(19)
+#endif
+
+#if(DIRECTINPUT_VERSION >= 0x0800)
+#define DIPROP_KEYNAME MAKEDIPROP(20)
+#define DIPROP_CPOINTS MAKEDIPROP(21)
+#define DIPROP_APPDATA MAKEDIPROP(22)
+#define DIPROP_SCANCODE MAKEDIPROP(23)
+#define DIPROP_VIDPID MAKEDIPROP(24)
+#define DIPROP_USERNAME MAKEDIPROP(25)
+#define DIPROP_TYPENAME MAKEDIPROP(26)
+
+#define MAXCPOINTSNUM 8
+
+typedef struct _CPOINT {
+ LONG lP;
+ DWORD dwLog;
+} CPOINT, *PCPOINT;
+
+typedef struct DIPROPCPOINTS {
+ DIPROPHEADER diph;
+ DWORD dwCPointsNum;
+ CPOINT cp[MAXCPOINTSNUM];
+} DIPROPCPOINTS, *LPDIPROPCPOINTS;
+typedef const DIPROPCPOINTS *LPCDIPROPCPOINTS;
+#endif /* DI8 */
+
+
+typedef struct DIDEVCAPS_DX3 {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDevType;
+ DWORD dwAxes;
+ DWORD dwButtons;
+ DWORD dwPOVs;
+} DIDEVCAPS_DX3, *LPDIDEVCAPS_DX3;
+
+typedef struct DIDEVCAPS {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDevType;
+ DWORD dwAxes;
+ DWORD dwButtons;
+ DWORD dwPOVs;
+#if(DIRECTINPUT_VERSION >= 0x0500)
+ DWORD dwFFSamplePeriod;
+ DWORD dwFFMinTimeResolution;
+ DWORD dwFirmwareRevision;
+ DWORD dwHardwareRevision;
+ DWORD dwFFDriverVersion;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVCAPS,*LPDIDEVCAPS;
+
+#define DIDC_ATTACHED 0x00000001
+#define DIDC_POLLEDDEVICE 0x00000002
+#define DIDC_EMULATED 0x00000004
+#define DIDC_POLLEDDATAFORMAT 0x00000008
+#define DIDC_FORCEFEEDBACK 0x00000100
+#define DIDC_FFATTACK 0x00000200
+#define DIDC_FFFADE 0x00000400
+#define DIDC_SATURATION 0x00000800
+#define DIDC_POSNEGCOEFFICIENTS 0x00001000
+#define DIDC_POSNEGSATURATION 0x00002000
+#define DIDC_DEADBAND 0x00004000
+#define DIDC_STARTDELAY 0x00008000
+#define DIDC_ALIAS 0x00010000
+#define DIDC_PHANTOM 0x00020000
+#define DIDC_HIDDEN 0x00040000
+
+
+/* SetCooperativeLevel dwFlags */
+#define DISCL_EXCLUSIVE 0x00000001
+#define DISCL_NONEXCLUSIVE 0x00000002
+#define DISCL_FOREGROUND 0x00000004
+#define DISCL_BACKGROUND 0x00000008
+#define DISCL_NOWINKEY 0x00000010
+
+#if (DIRECTINPUT_VERSION >= 0x0500)
+/* Device FF flags */
+#define DISFFC_RESET 0x00000001
+#define DISFFC_STOPALL 0x00000002
+#define DISFFC_PAUSE 0x00000004
+#define DISFFC_CONTINUE 0x00000008
+#define DISFFC_SETACTUATORSON 0x00000010
+#define DISFFC_SETACTUATORSOFF 0x00000020
+
+#define DIGFFS_EMPTY 0x00000001
+#define DIGFFS_STOPPED 0x00000002
+#define DIGFFS_PAUSED 0x00000004
+#define DIGFFS_ACTUATORSON 0x00000010
+#define DIGFFS_ACTUATORSOFF 0x00000020
+#define DIGFFS_POWERON 0x00000040
+#define DIGFFS_POWEROFF 0x00000080
+#define DIGFFS_SAFETYSWITCHON 0x00000100
+#define DIGFFS_SAFETYSWITCHOFF 0x00000200
+#define DIGFFS_USERFFSWITCHON 0x00000400
+#define DIGFFS_USERFFSWITCHOFF 0x00000800
+#define DIGFFS_DEVICELOST 0x80000000
+
+/* Effect flags */
+#define DIEFT_ALL 0x00000000
+
+#define DIEFT_CONSTANTFORCE 0x00000001
+#define DIEFT_RAMPFORCE 0x00000002
+#define DIEFT_PERIODIC 0x00000003
+#define DIEFT_CONDITION 0x00000004
+#define DIEFT_CUSTOMFORCE 0x00000005
+#define DIEFT_HARDWARE 0x000000FF
+#define DIEFT_FFATTACK 0x00000200
+#define DIEFT_FFFADE 0x00000400
+#define DIEFT_SATURATION 0x00000800
+#define DIEFT_POSNEGCOEFFICIENTS 0x00001000
+#define DIEFT_POSNEGSATURATION 0x00002000
+#define DIEFT_DEADBAND 0x00004000
+#define DIEFT_STARTDELAY 0x00008000
+#define DIEFT_GETTYPE(n) LOBYTE(n)
+
+#define DIEFF_OBJECTIDS 0x00000001
+#define DIEFF_OBJECTOFFSETS 0x00000002
+#define DIEFF_CARTESIAN 0x00000010
+#define DIEFF_POLAR 0x00000020
+#define DIEFF_SPHERICAL 0x00000040
+
+#define DIEP_DURATION 0x00000001
+#define DIEP_SAMPLEPERIOD 0x00000002
+#define DIEP_GAIN 0x00000004
+#define DIEP_TRIGGERBUTTON 0x00000008
+#define DIEP_TRIGGERREPEATINTERVAL 0x00000010
+#define DIEP_AXES 0x00000020
+#define DIEP_DIRECTION 0x00000040
+#define DIEP_ENVELOPE 0x00000080
+#define DIEP_TYPESPECIFICPARAMS 0x00000100
+#if(DIRECTINPUT_VERSION >= 0x0600)
+#define DIEP_STARTDELAY 0x00000200
+#define DIEP_ALLPARAMS_DX5 0x000001FF
+#define DIEP_ALLPARAMS 0x000003FF
+#else
+#define DIEP_ALLPARAMS 0x000001FF
+#endif /* DIRECTINPUT_VERSION >= 0x0600 */
+#define DIEP_START 0x20000000
+#define DIEP_NORESTART 0x40000000
+#define DIEP_NODOWNLOAD 0x80000000
+#define DIEB_NOTRIGGER 0xFFFFFFFF
+
+#define DIES_SOLO 0x00000001
+#define DIES_NODOWNLOAD 0x80000000
+
+#define DIEGES_PLAYING 0x00000001
+#define DIEGES_EMULATED 0x00000002
+
+#define DI_DEGREES 100
+#define DI_FFNOMINALMAX 10000
+#define DI_SECONDS 1000000
+
+typedef struct DICONSTANTFORCE {
+ LONG lMagnitude;
+} DICONSTANTFORCE, *LPDICONSTANTFORCE;
+typedef const DICONSTANTFORCE *LPCDICONSTANTFORCE;
+
+typedef struct DIRAMPFORCE {
+ LONG lStart;
+ LONG lEnd;
+} DIRAMPFORCE, *LPDIRAMPFORCE;
+typedef const DIRAMPFORCE *LPCDIRAMPFORCE;
+
+typedef struct DIPERIODIC {
+ DWORD dwMagnitude;
+ LONG lOffset;
+ DWORD dwPhase;
+ DWORD dwPeriod;
+} DIPERIODIC, *LPDIPERIODIC;
+typedef const DIPERIODIC *LPCDIPERIODIC;
+
+typedef struct DICONDITION {
+ LONG lOffset;
+ LONG lPositiveCoefficient;
+ LONG lNegativeCoefficient;
+ DWORD dwPositiveSaturation;
+ DWORD dwNegativeSaturation;
+ LONG lDeadBand;
+} DICONDITION, *LPDICONDITION;
+typedef const DICONDITION *LPCDICONDITION;
+
+typedef struct DICUSTOMFORCE {
+ DWORD cChannels;
+ DWORD dwSamplePeriod;
+ DWORD cSamples;
+ LPLONG rglForceData;
+} DICUSTOMFORCE, *LPDICUSTOMFORCE;
+typedef const DICUSTOMFORCE *LPCDICUSTOMFORCE;
+
+typedef struct DIENVELOPE {
+ DWORD dwSize;
+ DWORD dwAttackLevel;
+ DWORD dwAttackTime;
+ DWORD dwFadeLevel;
+ DWORD dwFadeTime;
+} DIENVELOPE, *LPDIENVELOPE;
+typedef const DIENVELOPE *LPCDIENVELOPE;
+
+typedef struct DIEFFECT_DX5 {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDuration;
+ DWORD dwSamplePeriod;
+ DWORD dwGain;
+ DWORD dwTriggerButton;
+ DWORD dwTriggerRepeatInterval;
+ DWORD cAxes;
+ LPDWORD rgdwAxes;
+ LPLONG rglDirection;
+ LPDIENVELOPE lpEnvelope;
+ DWORD cbTypeSpecificParams;
+ LPVOID lpvTypeSpecificParams;
+} DIEFFECT_DX5, *LPDIEFFECT_DX5;
+typedef const DIEFFECT_DX5 *LPCDIEFFECT_DX5;
+
+typedef struct DIEFFECT {
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwDuration;
+ DWORD dwSamplePeriod;
+ DWORD dwGain;
+ DWORD dwTriggerButton;
+ DWORD dwTriggerRepeatInterval;
+ DWORD cAxes;
+ LPDWORD rgdwAxes;
+ LPLONG rglDirection;
+ LPDIENVELOPE lpEnvelope;
+ DWORD cbTypeSpecificParams;
+ LPVOID lpvTypeSpecificParams;
+#if(DIRECTINPUT_VERSION >= 0x0600)
+ DWORD dwStartDelay;
+#endif /* DIRECTINPUT_VERSION >= 0x0600 */
+} DIEFFECT, *LPDIEFFECT;
+typedef const DIEFFECT *LPCDIEFFECT;
+typedef DIEFFECT DIEFFECT_DX6;
+typedef LPDIEFFECT LPDIEFFECT_DX6;
+
+typedef struct DIEFFECTINFOA {
+ DWORD dwSize;
+ GUID guid;
+ DWORD dwEffType;
+ DWORD dwStaticParams;
+ DWORD dwDynamicParams;
+ CHAR tszName[MAX_PATH];
+} DIEFFECTINFOA, *LPDIEFFECTINFOA;
+typedef const DIEFFECTINFOA *LPCDIEFFECTINFOA;
+
+typedef struct DIEFFECTINFOW {
+ DWORD dwSize;
+ GUID guid;
+ DWORD dwEffType;
+ DWORD dwStaticParams;
+ DWORD dwDynamicParams;
+ WCHAR tszName[MAX_PATH];
+} DIEFFECTINFOW, *LPDIEFFECTINFOW;
+typedef const DIEFFECTINFOW *LPCDIEFFECTINFOW;
+
+DECL_WINELIB_TYPE_AW(DIEFFECTINFO)
+DECL_WINELIB_TYPE_AW(LPDIEFFECTINFO)
+DECL_WINELIB_TYPE_AW(LPCDIEFFECTINFO)
+
+typedef BOOL (CALLBACK *LPDIENUMEFFECTSCALLBACKA)(LPCDIEFFECTINFOA, LPVOID);
+typedef BOOL (CALLBACK *LPDIENUMEFFECTSCALLBACKW)(LPCDIEFFECTINFOW, LPVOID);
+
+typedef struct DIEFFESCAPE {
+ DWORD dwSize;
+ DWORD dwCommand;
+ LPVOID lpvInBuffer;
+ DWORD cbInBuffer;
+ LPVOID lpvOutBuffer;
+ DWORD cbOutBuffer;
+} DIEFFESCAPE, *LPDIEFFESCAPE;
+
+typedef struct DIJOYSTATE {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ LONG lRx;
+ LONG lRy;
+ LONG lRz;
+ LONG rglSlider[2];
+ DWORD rgdwPOV[4];
+ BYTE rgbButtons[32];
+} DIJOYSTATE, *LPDIJOYSTATE;
+
+typedef struct DIJOYSTATE2 {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ LONG lRx;
+ LONG lRy;
+ LONG lRz;
+ LONG rglSlider[2];
+ DWORD rgdwPOV[4];
+ BYTE rgbButtons[128];
+ LONG lVX; /* 'v' as in velocity */
+ LONG lVY;
+ LONG lVZ;
+ LONG lVRx;
+ LONG lVRy;
+ LONG lVRz;
+ LONG rglVSlider[2];
+ LONG lAX; /* 'a' as in acceleration */
+ LONG lAY;
+ LONG lAZ;
+ LONG lARx;
+ LONG lARy;
+ LONG lARz;
+ LONG rglASlider[2];
+ LONG lFX; /* 'f' as in force */
+ LONG lFY;
+ LONG lFZ;
+ LONG lFRx; /* 'fr' as in rotational force aka torque */
+ LONG lFRy;
+ LONG lFRz;
+ LONG rglFSlider[2];
+} DIJOYSTATE2, *LPDIJOYSTATE2;
+
+#define DIJOFS_X FIELD_OFFSET(DIJOYSTATE, lX)
+#define DIJOFS_Y FIELD_OFFSET(DIJOYSTATE, lY)
+#define DIJOFS_Z FIELD_OFFSET(DIJOYSTATE, lZ)
+#define DIJOFS_RX FIELD_OFFSET(DIJOYSTATE, lRx)
+#define DIJOFS_RY FIELD_OFFSET(DIJOYSTATE, lRy)
+#define DIJOFS_RZ FIELD_OFFSET(DIJOYSTATE, lRz)
+#define DIJOFS_SLIDER(n) (FIELD_OFFSET(DIJOYSTATE, rglSlider) + \
+ (n) * sizeof(LONG))
+#define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE, rgdwPOV) + \
+ (n) * sizeof(DWORD))
+#define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE, rgbButtons) + (n))
+#define DIJOFS_BUTTON0 DIJOFS_BUTTON(0)
+#define DIJOFS_BUTTON1 DIJOFS_BUTTON(1)
+#define DIJOFS_BUTTON2 DIJOFS_BUTTON(2)
+#define DIJOFS_BUTTON3 DIJOFS_BUTTON(3)
+#define DIJOFS_BUTTON4 DIJOFS_BUTTON(4)
+#define DIJOFS_BUTTON5 DIJOFS_BUTTON(5)
+#define DIJOFS_BUTTON6 DIJOFS_BUTTON(6)
+#define DIJOFS_BUTTON7 DIJOFS_BUTTON(7)
+#define DIJOFS_BUTTON8 DIJOFS_BUTTON(8)
+#define DIJOFS_BUTTON9 DIJOFS_BUTTON(9)
+#define DIJOFS_BUTTON10 DIJOFS_BUTTON(10)
+#define DIJOFS_BUTTON11 DIJOFS_BUTTON(11)
+#define DIJOFS_BUTTON12 DIJOFS_BUTTON(12)
+#define DIJOFS_BUTTON13 DIJOFS_BUTTON(13)
+#define DIJOFS_BUTTON14 DIJOFS_BUTTON(14)
+#define DIJOFS_BUTTON15 DIJOFS_BUTTON(15)
+#define DIJOFS_BUTTON16 DIJOFS_BUTTON(16)
+#define DIJOFS_BUTTON17 DIJOFS_BUTTON(17)
+#define DIJOFS_BUTTON18 DIJOFS_BUTTON(18)
+#define DIJOFS_BUTTON19 DIJOFS_BUTTON(19)
+#define DIJOFS_BUTTON20 DIJOFS_BUTTON(20)
+#define DIJOFS_BUTTON21 DIJOFS_BUTTON(21)
+#define DIJOFS_BUTTON22 DIJOFS_BUTTON(22)
+#define DIJOFS_BUTTON23 DIJOFS_BUTTON(23)
+#define DIJOFS_BUTTON24 DIJOFS_BUTTON(24)
+#define DIJOFS_BUTTON25 DIJOFS_BUTTON(25)
+#define DIJOFS_BUTTON26 DIJOFS_BUTTON(26)
+#define DIJOFS_BUTTON27 DIJOFS_BUTTON(27)
+#define DIJOFS_BUTTON28 DIJOFS_BUTTON(28)
+#define DIJOFS_BUTTON29 DIJOFS_BUTTON(29)
+#define DIJOFS_BUTTON30 DIJOFS_BUTTON(30)
+#define DIJOFS_BUTTON31 DIJOFS_BUTTON(31)
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+
+/* DInput 7 structures, types */
+#if(DIRECTINPUT_VERSION >= 0x0700)
+typedef struct DIFILEEFFECT {
+ DWORD dwSize;
+ GUID GuidEffect;
+ LPCDIEFFECT lpDiEffect;
+ CHAR szFriendlyName[MAX_PATH];
+} DIFILEEFFECT, *LPDIFILEEFFECT;
+
+typedef const DIFILEEFFECT *LPCDIFILEEFFECT;
+typedef BOOL (CALLBACK *LPDIENUMEFFECTSINFILECALLBACK)(LPCDIFILEEFFECT , LPVOID);
+#endif /* DIRECTINPUT_VERSION >= 0x0700 */
+
+/* DInput 8 structures and types */
+#if DIRECTINPUT_VERSION >= 0x0800
+typedef struct _DIACTIONA {
+ UINT_PTR uAppData;
+ DWORD dwSemantic;
+ DWORD dwFlags;
+ __GNU_EXTENSION union {
+ LPCSTR lptszActionName;
+ UINT uResIdString;
+ } DUMMYUNIONNAME;
+ GUID guidInstance;
+ DWORD dwObjID;
+ DWORD dwHow;
+} DIACTIONA, *LPDIACTIONA;
+typedef const DIACTIONA *LPCDIACTIONA;
+
+typedef struct _DIACTIONW {
+ UINT_PTR uAppData;
+ DWORD dwSemantic;
+ DWORD dwFlags;
+ __GNU_EXTENSION union {
+ LPCWSTR lptszActionName;
+ UINT uResIdString;
+ } DUMMYUNIONNAME;
+ GUID guidInstance;
+ DWORD dwObjID;
+ DWORD dwHow;
+} DIACTIONW, *LPDIACTIONW;
+typedef const DIACTIONW *LPCDIACTIONW;
+
+DECL_WINELIB_TYPE_AW(DIACTION)
+DECL_WINELIB_TYPE_AW(LPDIACTION)
+DECL_WINELIB_TYPE_AW(LPCDIACTION)
+
+#define DIA_FORCEFEEDBACK 0x00000001
+#define DIA_APPMAPPED 0x00000002
+#define DIA_APPNOMAP 0x00000004
+#define DIA_NORANGE 0x00000008
+#define DIA_APPFIXED 0x00000010
+
+#define DIAH_UNMAPPED 0x00000000
+#define DIAH_USERCONFIG 0x00000001
+#define DIAH_APPREQUESTED 0x00000002
+#define DIAH_HWAPP 0x00000004
+#define DIAH_HWDEFAULT 0x00000008
+#define DIAH_DEFAULT 0x00000020
+#define DIAH_ERROR 0x80000000
+
+typedef struct _DIACTIONFORMATA {
+ DWORD dwSize;
+ DWORD dwActionSize;
+ DWORD dwDataSize;
+ DWORD dwNumActions;
+ LPDIACTIONA rgoAction;
+ GUID guidActionMap;
+ DWORD dwGenre;
+ DWORD dwBufferSize;
+ LONG lAxisMin;
+ LONG lAxisMax;
+ HINSTANCE hInstString;
+ FILETIME ftTimeStamp;
+ DWORD dwCRC;
+ CHAR tszActionMap[MAX_PATH];
+} DIACTIONFORMATA, *LPDIACTIONFORMATA;
+typedef const DIACTIONFORMATA *LPCDIACTIONFORMATA;
+
+typedef struct _DIACTIONFORMATW {
+ DWORD dwSize;
+ DWORD dwActionSize;
+ DWORD dwDataSize;
+ DWORD dwNumActions;
+ LPDIACTIONW rgoAction;
+ GUID guidActionMap;
+ DWORD dwGenre;
+ DWORD dwBufferSize;
+ LONG lAxisMin;
+ LONG lAxisMax;
+ HINSTANCE hInstString;
+ FILETIME ftTimeStamp;
+ DWORD dwCRC;
+ WCHAR tszActionMap[MAX_PATH];
+} DIACTIONFORMATW, *LPDIACTIONFORMATW;
+typedef const DIACTIONFORMATW *LPCDIACTIONFORMATW;
+
+DECL_WINELIB_TYPE_AW(DIACTIONFORMAT)
+DECL_WINELIB_TYPE_AW(LPDIACTIONFORMAT)
+DECL_WINELIB_TYPE_AW(LPCDIACTIONFORMAT)
+
+#define DIAFTS_NEWDEVICELOW 0xFFFFFFFF
+#define DIAFTS_NEWDEVICEHIGH 0xFFFFFFFF
+#define DIAFTS_UNUSEDDEVICELOW 0x00000000
+#define DIAFTS_UNUSEDDEVICEHIGH 0x00000000
+
+#define DIDBAM_DEFAULT 0x00000000
+#define DIDBAM_PRESERVE 0x00000001
+#define DIDBAM_INITIALIZE 0x00000002
+#define DIDBAM_HWDEFAULTS 0x00000004
+
+#define DIDSAM_DEFAULT 0x00000000
+#define DIDSAM_NOUSER 0x00000001
+#define DIDSAM_FORCESAVE 0x00000002
+
+#define DICD_DEFAULT 0x00000000
+#define DICD_EDIT 0x00000001
+
+#ifndef D3DCOLOR_DEFINED
+typedef DWORD D3DCOLOR;
+#define D3DCOLOR_DEFINED
+#endif
+
+typedef struct _DICOLORSET {
+ DWORD dwSize;
+ D3DCOLOR cTextFore;
+ D3DCOLOR cTextHighlight;
+ D3DCOLOR cCalloutLine;
+ D3DCOLOR cCalloutHighlight;
+ D3DCOLOR cBorder;
+ D3DCOLOR cControlFill;
+ D3DCOLOR cHighlightFill;
+ D3DCOLOR cAreaFill;
+} DICOLORSET, *LPDICOLORSET;
+typedef const DICOLORSET *LPCDICOLORSET;
+
+typedef struct _DICONFIGUREDEVICESPARAMSA {
+ DWORD dwSize;
+ DWORD dwcUsers;
+ LPSTR lptszUserNames;
+ DWORD dwcFormats;
+ LPDIACTIONFORMATA lprgFormats;
+ HWND hwnd;
+ DICOLORSET dics;
+ LPUNKNOWN lpUnkDDSTarget;
+} DICONFIGUREDEVICESPARAMSA, *LPDICONFIGUREDEVICESPARAMSA;
+typedef const DICONFIGUREDEVICESPARAMSA *LPCDICONFIGUREDEVICESPARAMSA;
+
+typedef struct _DICONFIGUREDEVICESPARAMSW {
+ DWORD dwSize;
+ DWORD dwcUsers;
+ LPWSTR lptszUserNames;
+ DWORD dwcFormats;
+ LPDIACTIONFORMATW lprgFormats;
+ HWND hwnd;
+ DICOLORSET dics;
+ LPUNKNOWN lpUnkDDSTarget;
+} DICONFIGUREDEVICESPARAMSW, *LPDICONFIGUREDEVICESPARAMSW;
+typedef const DICONFIGUREDEVICESPARAMSW *LPCDICONFIGUREDEVICESPARAMSW;
+
+DECL_WINELIB_TYPE_AW(DICONFIGUREDEVICESPARAMS)
+DECL_WINELIB_TYPE_AW(LPDICONFIGUREDEVICESPARAMS)
+DECL_WINELIB_TYPE_AW(LPCDICONFIGUREDEVICESPARAMS)
+
+#define DIDIFT_CONFIGURATION 0x00000001
+#define DIDIFT_OVERLAY 0x00000002
+
+#define DIDAL_CENTERED 0x00000000
+#define DIDAL_LEFTALIGNED 0x00000001
+#define DIDAL_RIGHTALIGNED 0x00000002
+#define DIDAL_MIDDLE 0x00000000
+#define DIDAL_TOPALIGNED 0x00000004
+#define DIDAL_BOTTOMALIGNED 0x00000008
+
+typedef struct _DIDEVICEIMAGEINFOA {
+ CHAR tszImagePath[MAX_PATH];
+ DWORD dwFlags;
+ DWORD dwViewID;
+ RECT rcOverlay;
+ DWORD dwObjID;
+ DWORD dwcValidPts;
+ POINT rgptCalloutLine[5];
+ RECT rcCalloutRect;
+ DWORD dwTextAlign;
+} DIDEVICEIMAGEINFOA, *LPDIDEVICEIMAGEINFOA;
+typedef const DIDEVICEIMAGEINFOA *LPCDIDEVICEIMAGEINFOA;
+
+typedef struct _DIDEVICEIMAGEINFOW {
+ WCHAR tszImagePath[MAX_PATH];
+ DWORD dwFlags;
+ DWORD dwViewID;
+ RECT rcOverlay;
+ DWORD dwObjID;
+ DWORD dwcValidPts;
+ POINT rgptCalloutLine[5];
+ RECT rcCalloutRect;
+ DWORD dwTextAlign;
+} DIDEVICEIMAGEINFOW, *LPDIDEVICEIMAGEINFOW;
+typedef const DIDEVICEIMAGEINFOW *LPCDIDEVICEIMAGEINFOW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEIMAGEINFO)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEIMAGEINFO)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEIMAGEINFO)
+
+typedef struct _DIDEVICEIMAGEINFOHEADERA {
+ DWORD dwSize;
+ DWORD dwSizeImageInfo;
+ DWORD dwcViews;
+ DWORD dwcButtons;
+ DWORD dwcAxes;
+ DWORD dwcPOVs;
+ DWORD dwBufferSize;
+ DWORD dwBufferUsed;
+ LPDIDEVICEIMAGEINFOA lprgImageInfoArray;
+} DIDEVICEIMAGEINFOHEADERA, *LPDIDEVICEIMAGEINFOHEADERA;
+typedef const DIDEVICEIMAGEINFOHEADERA *LPCDIDEVICEIMAGEINFOHEADERA;
+
+typedef struct _DIDEVICEIMAGEINFOHEADERW {
+ DWORD dwSize;
+ DWORD dwSizeImageInfo;
+ DWORD dwcViews;
+ DWORD dwcButtons;
+ DWORD dwcAxes;
+ DWORD dwcPOVs;
+ DWORD dwBufferSize;
+ DWORD dwBufferUsed;
+ LPDIDEVICEIMAGEINFOW lprgImageInfoArray;
+} DIDEVICEIMAGEINFOHEADERW, *LPDIDEVICEIMAGEINFOHEADERW;
+typedef const DIDEVICEIMAGEINFOHEADERW *LPCDIDEVICEIMAGEINFOHEADERW;
+
+DECL_WINELIB_TYPE_AW(DIDEVICEIMAGEINFOHEADER)
+DECL_WINELIB_TYPE_AW(LPDIDEVICEIMAGEINFOHEADER)
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEIMAGEINFOHEADER)
+
+#endif /* DI8 */
+
+
+/*****************************************************************************
+ * IDirectInputEffect interface
+ */
+#if (DIRECTINPUT_VERSION >= 0x0500)
+#undef INTERFACE
+#define INTERFACE IDirectInputEffect
+DECLARE_INTERFACE_(IDirectInputEffect,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputEffect methods ***/
+ STDMETHOD(Initialize)(THIS_ HINSTANCE, DWORD, REFGUID) PURE;
+ STDMETHOD(GetEffectGuid)(THIS_ LPGUID) PURE;
+ STDMETHOD(GetParameters)(THIS_ LPDIEFFECT, DWORD) PURE;
+ STDMETHOD(SetParameters)(THIS_ LPCDIEFFECT, DWORD) PURE;
+ STDMETHOD(Start)(THIS_ DWORD, DWORD) PURE;
+ STDMETHOD(Stop)(THIS) PURE;
+ STDMETHOD(GetEffectStatus)(THIS_ LPDWORD) PURE;
+ STDMETHOD(Download)(THIS) PURE;
+ STDMETHOD(Unload)(THIS) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputEffect_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputEffect_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputEffect_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputEffect methods ***/
+#define IDirectInputEffect_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirectInputEffect_GetEffectGuid(p,a) (p)->lpVtbl->GetEffectGuid(p,a)
+#define IDirectInputEffect_GetParameters(p,a,b) (p)->lpVtbl->GetParameters(p,a,b)
+#define IDirectInputEffect_SetParameters(p,a,b) (p)->lpVtbl->SetParameters(p,a,b)
+#define IDirectInputEffect_Start(p,a,b) (p)->lpVtbl->Start(p,a,b)
+#define IDirectInputEffect_Stop(p) (p)->lpVtbl->Stop(p)
+#define IDirectInputEffect_GetEffectStatus(p,a) (p)->lpVtbl->GetEffectStatus(p,a)
+#define IDirectInputEffect_Download(p) (p)->lpVtbl->Download(p)
+#define IDirectInputEffect_Unload(p) (p)->lpVtbl->Unload(p)
+#define IDirectInputEffect_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputEffect_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputEffect_AddRef(p) (p)->AddRef()
+#define IDirectInputEffect_Release(p) (p)->Release()
+/*** IDirectInputEffect methods ***/
+#define IDirectInputEffect_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#define IDirectInputEffect_GetEffectGuid(p,a) (p)->GetEffectGuid(a)
+#define IDirectInputEffect_GetParameters(p,a,b) (p)->GetParameters(a,b)
+#define IDirectInputEffect_SetParameters(p,a,b) (p)->SetParameters(a,b)
+#define IDirectInputEffect_Start(p,a,b) (p)->Start(a,b)
+#define IDirectInputEffect_Stop(p) (p)->Stop()
+#define IDirectInputEffect_GetEffectStatus(p,a) (p)->GetEffectStatus(a)
+#define IDirectInputEffect_Download(p) (p)->Download()
+#define IDirectInputEffect_Unload(p) (p)->Unload()
+#define IDirectInputEffect_Escape(p,a) (p)->Escape(a)
+#endif
+
+#endif /* DI5 */
+
+
+/*****************************************************************************
+ * IDirectInputDeviceA interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDeviceA
+DECLARE_INTERFACE_(IDirectInputDeviceA,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDeviceW interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDeviceW
+DECLARE_INTERFACE_(IDirectInputDeviceW,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#endif
+
+
+#if (DIRECTINPUT_VERSION >= 0x0500)
+/*****************************************************************************
+ * IDirectInputDevice2A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice2A
+DECLARE_INTERFACE_(IDirectInputDevice2A,IDirectInputDeviceA)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2A methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDevice2W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice2W
+DECLARE_INTERFACE_(IDirectInputDevice2W,IDirectInputDeviceW)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2W methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice2_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice2_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice2_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice2_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice2_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice2_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice2_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice2_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+#define IDirectInputDevice2_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#define IDirectInputDevice2_Poll(p) (p)->lpVtbl->Poll(p)
+#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice2_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice2_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice2_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice2_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice2_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice2_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice2_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice2_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice2_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice2_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice2_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice2_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice2_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice2_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice2_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice2_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice2_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+#define IDirectInputDevice2_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+#define IDirectInputDevice2_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+#define IDirectInputDevice2_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+#define IDirectInputDevice2_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+#define IDirectInputDevice2_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+#define IDirectInputDevice2_Escape(p,a) (p)->Escape(a)
+#define IDirectInputDevice2_Poll(p) (p)->Poll()
+#define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+#endif
+#endif /* DI5 */
+
+#if DIRECTINPUT_VERSION >= 0x0700
+/*****************************************************************************
+ * IDirectInputDevice7A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice7A
+DECLARE_INTERFACE_(IDirectInputDevice7A,IDirectInputDevice2A)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2A methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7A methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDevice7W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice7W
+DECLARE_INTERFACE_(IDirectInputDevice7W,IDirectInputDevice2W)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2W methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7W methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice7_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice7_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice7_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice7_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice7_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice7_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice7_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice7_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice7_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+#define IDirectInputDevice7_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#define IDirectInputDevice7_Poll(p) (p)->lpVtbl->Poll(p)
+#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d)
+#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice7_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice7_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice7_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice7_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice7_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice7_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice7_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice7_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice7_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice7_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice7_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice7_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice7_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+#define IDirectInputDevice7_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+#define IDirectInputDevice7_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+#define IDirectInputDevice7_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+#define IDirectInputDevice7_Escape(p,a) (p)->Escape(a)
+#define IDirectInputDevice7_Poll(p) (p)->Poll()
+#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d)
+#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d)
+#endif
+
+#endif /* DI7 */
+
+#if DIRECTINPUT_VERSION >= 0x0800
+/*****************************************************************************
+ * IDirectInputDevice8A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice8A
+DECLARE_INTERFACE_(IDirectInputDevice8A,IDirectInputDevice7A)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceA methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEA pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2A methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKA lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOA pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7A methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+ /*** IDirectInputDevice8A methods ***/
+ STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputDevice8W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputDevice8W
+DECLARE_INTERFACE_(IDirectInputDevice8W,IDirectInputDevice7W)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputDeviceW methods ***/
+ STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS lpDIDevCaps) PURE;
+ STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetProperty)(THIS_ REFGUID rguidProp, LPDIPROPHEADER pdiph) PURE;
+ STDMETHOD(SetProperty)(THIS_ REFGUID rguidProp, LPCDIPROPHEADER pdiph) PURE;
+ STDMETHOD(Acquire)(THIS) PURE;
+ STDMETHOD(Unacquire)(THIS) PURE;
+ STDMETHOD(GetDeviceState)(THIS_ DWORD cbData, LPVOID lpvData) PURE;
+ STDMETHOD(GetDeviceData)(THIS_ DWORD cbObjectData, LPDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD dwFlags) PURE;
+ STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT lpdf) PURE;
+ STDMETHOD(SetEventNotification)(THIS_ HANDLE hEvent) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwFlags) PURE;
+ STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow) PURE;
+ STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCEW pdidi) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion, REFGUID rguid) PURE;
+ /*** IDirectInputDevice2W methods ***/
+ STDMETHOD(CreateEffect)(THIS_ REFGUID rguid, LPCDIEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter) PURE;
+ STDMETHOD(EnumEffects)(THIS_ LPDIENUMEFFECTSCALLBACKW lpCallback, LPVOID pvRef, DWORD dwEffType) PURE;
+ STDMETHOD(GetEffectInfo)(THIS_ LPDIEFFECTINFOW pdei, REFGUID rguid) PURE;
+ STDMETHOD(GetForceFeedbackState)(THIS_ LPDWORD pdwOut) PURE;
+ STDMETHOD(SendForceFeedbackCommand)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(EnumCreatedEffectObjects)(THIS_ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, LPVOID pvRef, DWORD fl) PURE;
+ STDMETHOD(Escape)(THIS_ LPDIEFFESCAPE pesc) PURE;
+ STDMETHOD(Poll)(THIS) PURE;
+ STDMETHOD(SendDeviceData)(THIS_ DWORD cbObjectData, LPCDIDEVICEOBJECTDATA rgdod, LPDWORD pdwInOut, DWORD fl) PURE;
+ /*** IDirectInputDevice7W methods ***/
+ STDMETHOD(EnumEffectsInFile)(THIS_ LPCWSTR lpszFileName,LPDIENUMEFFECTSINFILECALLBACK pec,LPVOID pvRef,DWORD dwFlags) PURE;
+ STDMETHOD(WriteEffectToFile)(THIS_ LPCWSTR lpszFileName,DWORD dwEntries,LPDIFILEEFFECT rgDiFileEft,DWORD dwFlags) PURE;
+ /*** IDirectInputDevice8W methods ***/
+ STDMETHOD(BuildActionMap)(THIS_ LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(SetActionMap)(THIS_ LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags) PURE;
+ STDMETHOD(GetImageInfo)(THIS_ LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInputDevice8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInputDevice8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice8_GetCapabilities(p,a) (p)->lpVtbl->GetCapabilities(p,a)
+#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->lpVtbl->EnumObjects(p,a,b,c)
+#define IDirectInputDevice8_GetProperty(p,a,b) (p)->lpVtbl->GetProperty(p,a,b)
+#define IDirectInputDevice8_SetProperty(p,a,b) (p)->lpVtbl->SetProperty(p,a,b)
+#define IDirectInputDevice8_Acquire(p) (p)->lpVtbl->Acquire(p)
+#define IDirectInputDevice8_Unacquire(p) (p)->lpVtbl->Unacquire(p)
+#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->lpVtbl->GetDeviceState(p,a,b)
+#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->lpVtbl->GetDeviceData(p,a,b,c,d)
+#define IDirectInputDevice8_SetDataFormat(p,a) (p)->lpVtbl->SetDataFormat(p,a)
+#define IDirectInputDevice8_SetEventNotification(p,a) (p)->lpVtbl->SetEventNotification(p,a)
+#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->lpVtbl->GetObjectInfo(p,a,b,c)
+#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->lpVtbl->GetDeviceInfo(p,a)
+#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->lpVtbl->CreateEffect(p,a,b,c,d)
+#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->lpVtbl->EnumEffects(p,a,b,c)
+#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->lpVtbl->GetEffectInfo(p,a,b)
+#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->lpVtbl->GetForceFeedbackState(p,a)
+#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->lpVtbl->SendForceFeedbackCommand(p,a)
+#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->lpVtbl->EnumCreatedEffectObjects(p,a,b,c)
+#define IDirectInputDevice8_Escape(p,a) (p)->lpVtbl->Escape(p,a)
+#define IDirectInputDevice8_Poll(p) (p)->lpVtbl->Poll(p)
+#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->lpVtbl->SendDeviceData(p,a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->lpVtbl->EnumEffectsInFile(p,a,b,c,d)
+#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->lpVtbl->WriteEffectToFile(p,a,b,c,d)
+/*** IDirectInputDevice8 methods ***/
+#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->lpVtbl->BuildActionMap(p,a,b,c)
+#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->lpVtbl->SetActionMap(p,a,b,c)
+#define IDirectInputDevice8_GetImageInfo(p,a) (p)->lpVtbl->GetImageInfo(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectInputDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInputDevice8_AddRef(p) (p)->AddRef()
+#define IDirectInputDevice8_Release(p) (p)->Release()
+/*** IDirectInputDevice methods ***/
+#define IDirectInputDevice8_GetCapabilities(p,a) (p)->GetCapabilities(a)
+#define IDirectInputDevice8_EnumObjects(p,a,b,c) (p)->EnumObjects(a,b,c)
+#define IDirectInputDevice8_GetProperty(p,a,b) (p)->GetProperty(a,b)
+#define IDirectInputDevice8_SetProperty(p,a,b) (p)->SetProperty(a,b)
+#define IDirectInputDevice8_Acquire(p) (p)->Acquire()
+#define IDirectInputDevice8_Unacquire(p) (p)->Unacquire()
+#define IDirectInputDevice8_GetDeviceState(p,a,b) (p)->GetDeviceState(a,b)
+#define IDirectInputDevice8_GetDeviceData(p,a,b,c,d) (p)->GetDeviceData(a,b,c,d)
+#define IDirectInputDevice8_SetDataFormat(p,a) (p)->SetDataFormat(a)
+#define IDirectInputDevice8_SetEventNotification(p,a) (p)->SetEventNotification(a)
+#define IDirectInputDevice8_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectInputDevice8_GetObjectInfo(p,a,b,c) (p)->GetObjectInfo(a,b,c)
+#define IDirectInputDevice8_GetDeviceInfo(p,a) (p)->GetDeviceInfo(a)
+#define IDirectInputDevice8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInputDevice8_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+/*** IDirectInputDevice2 methods ***/
+#define IDirectInputDevice8_CreateEffect(p,a,b,c,d) (p)->CreateEffect(a,b,c,d)
+#define IDirectInputDevice8_EnumEffects(p,a,b,c) (p)->EnumEffects(a,b,c)
+#define IDirectInputDevice8_GetEffectInfo(p,a,b) (p)->GetEffectInfo(a,b)
+#define IDirectInputDevice8_GetForceFeedbackState(p,a) (p)->GetForceFeedbackState(a)
+#define IDirectInputDevice8_SendForceFeedbackCommand(p,a) (p)->SendForceFeedbackCommand(a)
+#define IDirectInputDevice8_EnumCreatedEffectObjects(p,a,b,c) (p)->EnumCreatedEffectObjects(a,b,c)
+#define IDirectInputDevice8_Escape(p,a) (p)->Escape(a)
+#define IDirectInputDevice8_Poll(p) (p)->Poll()
+#define IDirectInputDevice8_SendDeviceData(p,a,b,c,d) (p)->SendDeviceData(a,b,c,d)
+/*** IDirectInputDevice7 methods ***/
+#define IDirectInputDevice8_EnumEffectsInFile(p,a,b,c,d) (p)->EnumEffectsInFile(a,b,c,d)
+#define IDirectInputDevice8_WriteEffectToFile(p,a,b,c,d) (p)->WriteEffectToFile(a,b,c,d)
+/*** IDirectInputDevice8 methods ***/
+#define IDirectInputDevice8_BuildActionMap(p,a,b,c) (p)->BuildActionMap(a,b,c)
+#define IDirectInputDevice8_SetActionMap(p,a,b,c) (p)->SetActionMap(a,b,c)
+#define IDirectInputDevice8_GetImageInfo(p,a) (p)->GetImageInfo(a)
+#endif
+
+#endif /* DI8 */
+
+/* "Standard" Mouse report... */
+typedef struct DIMOUSESTATE {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ BYTE rgbButtons[4];
+} DIMOUSESTATE;
+
+#if DIRECTINPUT_VERSION >= 0x0700
+/* "Standard" Mouse report for DInput 7... */
+typedef struct DIMOUSESTATE2 {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ BYTE rgbButtons[8];
+} DIMOUSESTATE2;
+#endif /* DI7 */
+
+#define DIMOFS_X FIELD_OFFSET(DIMOUSESTATE, lX)
+#define DIMOFS_Y FIELD_OFFSET(DIMOUSESTATE, lY)
+#define DIMOFS_Z FIELD_OFFSET(DIMOUSESTATE, lZ)
+#define DIMOFS_BUTTON0 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 0)
+#define DIMOFS_BUTTON1 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 1)
+#define DIMOFS_BUTTON2 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 2)
+#define DIMOFS_BUTTON3 (FIELD_OFFSET(DIMOUSESTATE, rgbButtons) + 3)
+#if DIRECTINPUT_VERSION >= 0x0700
+#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4)
+#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5)
+#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6)
+#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7)
+#endif /* DI7 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern const DIDATAFORMAT c_dfDIMouse;
+#if DIRECTINPUT_VERSION >= 0x0700
+extern const DIDATAFORMAT c_dfDIMouse2; /* DX 7 */
+#endif /* DI7 */
+extern const DIDATAFORMAT c_dfDIKeyboard;
+#if DIRECTINPUT_VERSION >= 0x0500
+extern const DIDATAFORMAT c_dfDIJoystick;
+extern const DIDATAFORMAT c_dfDIJoystick2;
+#endif /* DI5 */
+#ifdef __cplusplus
+};
+#endif
+
+/*****************************************************************************
+ * IDirectInputA interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputA
+DECLARE_INTERFACE_(IDirectInputA,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputA methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInputW interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInputW
+DECLARE_INTERFACE_(IDirectInputW,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputW methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput methods ***/
+#define IDirectInput_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput_AddRef(p) (p)->AddRef()
+#define IDirectInput_Release(p) (p)->Release()
+/*** IDirectInput methods ***/
+#define IDirectInput_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput_Initialize(p,a,b) (p)->Initialize(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirectInput2A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput2A
+DECLARE_INTERFACE_(IDirectInput2A,IDirectInputA)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputA methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2A methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInput2W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput2W
+DECLARE_INTERFACE_(IDirectInput2W,IDirectInputW)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputW methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2W methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput2_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput methods ***/
+#define IDirectInput2_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput2_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput2_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput2_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput2_AddRef(p) (p)->AddRef()
+#define IDirectInput2_Release(p) (p)->Release()
+/*** IDirectInput methods ***/
+#define IDirectInput2_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput2_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput2_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput2_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput2_Initialize(p,a,b) (p)->Initialize(a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput2_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+#endif
+
+/*****************************************************************************
+ * IDirectInput7A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput7A
+DECLARE_INTERFACE_(IDirectInput7A,IDirectInput2A)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputA methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEA *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2A methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE;
+ /*** IDirectInput7A methods ***/
+ STDMETHOD(CreateDeviceEx)(THIS_ REFGUID rguid, REFIID riid, LPVOID *pvOut, LPUNKNOWN lpUnknownOuter) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInput7W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput7W
+DECLARE_INTERFACE_(IDirectInput7W,IDirectInput2W)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInputW methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICEW *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ /*** IDirectInput2W methods ***/
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE;
+ /*** IDirectInput7W methods ***/
+ STDMETHOD(CreateDeviceEx)(THIS_ REFGUID rguid, REFIID riid, LPVOID *pvOut, LPUNKNOWN lpUnknownOuter) PURE;
+};
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput7_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput7_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput methods ***/
+#define IDirectInput7_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput7_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput7_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput7_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput7_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+/*** IDirectInput7 methods ***/
+#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput7_AddRef(p) (p)->AddRef()
+#define IDirectInput7_Release(p) (p)->Release()
+/*** IDirectInput methods ***/
+#define IDirectInput7_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput7_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput7_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput7_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput7_Initialize(p,a,b) (p)->Initialize(a,b)
+/*** IDirectInput2 methods ***/
+#define IDirectInput7_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+/*** IDirectInput7 methods ***/
+#define IDirectInput7_CreateDeviceEx(p,a,b,c,d) (p)->CreateDeviceEx(a,b,c,d)
+#endif
+
+
+#if DIRECTINPUT_VERSION >= 0x0800
+/*****************************************************************************
+ * IDirectInput8A interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput8A
+DECLARE_INTERFACE_(IDirectInput8A,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInput8A methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8A *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCSTR pszName, LPGUID pguidInstance) PURE;
+ STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBA lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE;
+};
+
+/*****************************************************************************
+ * IDirectInput8W interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirectInput8W
+DECLARE_INTERFACE_(IDirectInput8W,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectInput8W methods ***/
+ STDMETHOD(CreateDevice)(THIS_ REFGUID rguid, LPDIRECTINPUTDEVICE8W *lplpDirectInputDevice, LPUNKNOWN pUnkOuter) PURE;
+ STDMETHOD(EnumDevices)(THIS_ DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(GetDeviceStatus)(THIS_ REFGUID rguidInstance) PURE;
+ STDMETHOD(RunControlPanel)(THIS_ HWND hwndOwner, DWORD dwFlags) PURE;
+ STDMETHOD(Initialize)(THIS_ HINSTANCE hinst, DWORD dwVersion) PURE;
+ STDMETHOD(FindDevice)(THIS_ REFGUID rguid, LPCWSTR pszName, LPGUID pguidInstance) PURE;
+ STDMETHOD(EnumDevicesBySemantics)(THIS_ LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat, LPDIENUMDEVICESBYSEMANTICSCBW lpCallback, LPVOID pvRef, DWORD dwFlags) PURE;
+ STDMETHOD(ConfigureDevices)(THIS_ LPDICONFIGUREDEVICESCALLBACK lpdiCallback, LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectInput8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectInput8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectInput8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectInput8 methods ***/
+#define IDirectInput8_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->lpVtbl->EnumDevices(p,a,b,c,d)
+#define IDirectInput8_GetDeviceStatus(p,a) (p)->lpVtbl->GetDeviceStatus(p,a)
+#define IDirectInput8_RunControlPanel(p,a,b) (p)->lpVtbl->RunControlPanel(p,a,b)
+#define IDirectInput8_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectInput8_FindDevice(p,a,b,c) (p)->lpVtbl->FindDevice(p,a,b,c)
+#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->lpVtbl->EnumDevicesBySemantics(p,a,b,c,d,e)
+#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->lpVtbl->ConfigureDevices(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectInput8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectInput8_AddRef(p) (p)->AddRef()
+#define IDirectInput8_Release(p) (p)->Release()
+/*** IDirectInput8 methods ***/
+#define IDirectInput8_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#define IDirectInput8_EnumDevices(p,a,b,c,d) (p)->EnumDevices(a,b,c,d)
+#define IDirectInput8_GetDeviceStatus(p,a) (p)->GetDeviceStatus(a)
+#define IDirectInput8_RunControlPanel(p,a,b) (p)->RunControlPanel(a,b)
+#define IDirectInput8_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectInput8_FindDevice(p,a,b,c) (p)->FindDevice(a,b,c)
+#define IDirectInput8_EnumDevicesBySemantics(p,a,b,c,d,e) (p)->EnumDevicesBySemantics(a,b,c,d,e)
+#define IDirectInput8_ConfigureDevices(p,a,b,c,d) (p)->ConfigureDevices(a,b,c,d)
+#endif
+
+#endif /* DI8 */
+
+/* Export functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DIRECTINPUT_VERSION >= 0x0800
+HRESULT WINAPI DirectInput8Create(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
+#else /* DI < 8 */
+HRESULT WINAPI DirectInputCreateA(HINSTANCE,DWORD,LPDIRECTINPUTA *,LPUNKNOWN);
+HRESULT WINAPI DirectInputCreateW(HINSTANCE,DWORD,LPDIRECTINPUTW *,LPUNKNOWN);
+#define DirectInputCreate WINELIB_NAME_AW(DirectInputCreate)
+
+HRESULT WINAPI DirectInputCreateEx(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
+#endif /* DI8 */
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* __DINPUT_INCLUDED__ */
diff --git a/src/external/glfw/deps/mingw/xinput.h b/src/external/glfw/deps/mingw/xinput.h
new file mode 100644
index 00000000..d3ca726c
--- /dev/null
+++ b/src/external/glfw/deps/mingw/xinput.h
@@ -0,0 +1,239 @@
+/*
+ * The Wine project - Xinput Joystick Library
+ * Copyright 2008 Andrew Fenn
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_XINPUT_H
+#define __WINE_XINPUT_H
+
+#include <windef.h>
+
+/*
+ * Bitmasks for the joysticks buttons, determines what has
+ * been pressed on the joystick, these need to be mapped
+ * to whatever device you're using instead of an xbox 360
+ * joystick
+ */
+
+#define XINPUT_GAMEPAD_DPAD_UP 0x0001
+#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
+#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
+#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
+#define XINPUT_GAMEPAD_START 0x0010
+#define XINPUT_GAMEPAD_BACK 0x0020
+#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
+#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
+#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
+#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
+#define XINPUT_GAMEPAD_A 0x1000
+#define XINPUT_GAMEPAD_B 0x2000
+#define XINPUT_GAMEPAD_X 0x4000
+#define XINPUT_GAMEPAD_Y 0x8000
+
+/*
+ * Defines the flags used to determine if the user is pushing
+ * down on a button, not holding a button, etc
+ */
+
+#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
+#define XINPUT_KEYSTROKE_KEYUP 0x0002
+#define XINPUT_KEYSTROKE_REPEAT 0x0004
+
+/*
+ * Defines the codes which are returned by XInputGetKeystroke
+ */
+
+#define VK_PAD_A 0x5800
+#define VK_PAD_B 0x5801
+#define VK_PAD_X 0x5802
+#define VK_PAD_Y 0x5803
+#define VK_PAD_RSHOULDER 0x5804
+#define VK_PAD_LSHOULDER 0x5805
+#define VK_PAD_LTRIGGER 0x5806
+#define VK_PAD_RTRIGGER 0x5807
+#define VK_PAD_DPAD_UP 0x5810
+#define VK_PAD_DPAD_DOWN 0x5811
+#define VK_PAD_DPAD_LEFT 0x5812
+#define VK_PAD_DPAD_RIGHT 0x5813
+#define VK_PAD_START 0x5814
+#define VK_PAD_BACK 0x5815
+#define VK_PAD_LTHUMB_PRESS 0x5816
+#define VK_PAD_RTHUMB_PRESS 0x5817
+#define VK_PAD_LTHUMB_UP 0x5820
+#define VK_PAD_LTHUMB_DOWN 0x5821
+#define VK_PAD_LTHUMB_RIGHT 0x5822
+#define VK_PAD_LTHUMB_LEFT 0x5823
+#define VK_PAD_LTHUMB_UPLEFT 0x5824
+#define VK_PAD_LTHUMB_UPRIGHT 0x5825
+#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
+#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
+#define VK_PAD_RTHUMB_UP 0x5830
+#define VK_PAD_RTHUMB_DOWN 0x5831
+#define VK_PAD_RTHUMB_RIGHT 0x5832
+#define VK_PAD_RTHUMB_LEFT 0x5833
+#define VK_PAD_RTHUMB_UPLEFT 0x5834
+#define VK_PAD_RTHUMB_UPRIGHT 0x5835
+#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
+#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
+
+/*
+ * Deadzones are for analogue joystick controls on the joypad
+ * which determine when input should be assumed to be in the
+ * middle of the pad. This is a threshold to stop a joypad
+ * controlling the game when the player isn't touching the
+ * controls.
+ */
+
+#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
+#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
+#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
+
+
+/*
+ * Defines what type of abilities the type of joystick has
+ * DEVTYPE_GAMEPAD is available for all joysticks, however
+ * there may be more specific identifiers for other joysticks
+ * which are being used.
+ */
+
+#define XINPUT_DEVTYPE_GAMEPAD 0x01
+#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
+#define XINPUT_DEVSUBTYPE_WHEEL 0x02
+#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
+#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
+#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
+#define XINPUT_DEVSUBTYPE_GUITAR 0x06
+#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
+
+/*
+ * These are used with the XInputGetCapabilities function to
+ * determine the abilities to the joystick which has been
+ * plugged in.
+ */
+
+#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
+#define XINPUT_FLAG_GAMEPAD 0x00000001
+
+/*
+ * Defines the status of the battery if one is used in the
+ * attached joystick. The first two define if the joystick
+ * supports a battery. Disconnected means that the joystick
+ * isn't connected. Wired shows that the joystick is a wired
+ * joystick.
+ */
+
+#define BATTERY_DEVTYPE_GAMEPAD 0x00
+#define BATTERY_DEVTYPE_HEADSET 0x01
+#define BATTERY_TYPE_DISCONNECTED 0x00
+#define BATTERY_TYPE_WIRED 0x01
+#define BATTERY_TYPE_ALKALINE 0x02
+#define BATTERY_TYPE_NIMH 0x03
+#define BATTERY_TYPE_UNKNOWN 0xFF
+#define BATTERY_LEVEL_EMPTY 0x00
+#define BATTERY_LEVEL_LOW 0x01
+#define BATTERY_LEVEL_MEDIUM 0x02
+#define BATTERY_LEVEL_FULL 0x03
+
+/*
+ * How many joysticks can be used with this library. Games that
+ * use the xinput library will not go over this number.
+ */
+
+#define XUSER_MAX_COUNT 4
+#define XUSER_INDEX_ANY 0x000000FF
+
+/*
+ * Defines the structure of an xbox 360 joystick.
+ */
+
+typedef struct _XINPUT_GAMEPAD {
+ WORD wButtons;
+ BYTE bLeftTrigger;
+ BYTE bRightTrigger;
+ SHORT sThumbLX;
+ SHORT sThumbLY;
+ SHORT sThumbRX;
+ SHORT sThumbRY;
+} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
+
+typedef struct _XINPUT_STATE {
+ DWORD dwPacketNumber;
+ XINPUT_GAMEPAD Gamepad;
+} XINPUT_STATE, *PXINPUT_STATE;
+
+/*
+ * Defines the structure of how much vibration is set on both the
+ * right and left motors in a joystick. If you're not using a 360
+ * joystick you will have to map these to your device.
+ */
+
+typedef struct _XINPUT_VIBRATION {
+ WORD wLeftMotorSpeed;
+ WORD wRightMotorSpeed;
+} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
+
+/*
+ * Defines the structure for what kind of abilities the joystick has
+ * such abilities are things such as if the joystick has the ability
+ * to send and receive audio, if the joystick is in fact a driving
+ * wheel or perhaps if the joystick is some kind of dance pad or
+ * guitar.
+ */
+
+typedef struct _XINPUT_CAPABILITIES {
+ BYTE Type;
+ BYTE SubType;
+ WORD Flags;
+ XINPUT_GAMEPAD Gamepad;
+ XINPUT_VIBRATION Vibration;
+} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
+
+/*
+ * Defines the structure for a joystick input event which is
+ * retrieved using the function XInputGetKeystroke
+ */
+typedef struct _XINPUT_KEYSTROKE {
+ WORD VirtualKey;
+ WCHAR Unicode;
+ WORD Flags;
+ BYTE UserIndex;
+ BYTE HidCode;
+} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
+
+typedef struct _XINPUT_BATTERY_INFORMATION
+{
+ BYTE BatteryType;
+ BYTE BatteryLevel;
+} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void WINAPI XInputEnable(WINBOOL);
+DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
+DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
+DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
+DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
+DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
+DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_XINPUT_H */
diff --git a/src/external/glfw/deps/vs2008/stdint.h b/src/external/glfw/deps/vs2008/stdint.h
new file mode 100644
index 00000000..d02608a5
--- /dev/null
+++ b/src/external/glfw/deps/vs2008/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/project/vs2015/external/glfw3/include/GLFW/glfw3.h b/src/external/glfw/include/GLFW/glfw3.h
index 5a0c4508..6923ba68 100644
--- a/project/vs2015/external/glfw3/include/GLFW/glfw3.h
+++ b/src/external/glfw/include/GLFW/glfw3.h
@@ -1,9 +1,9 @@
/*************************************************************************
- * GLFW 3.2 - www.glfw.org
+ * GLFW 3.3 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
+ * Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -47,32 +47,38 @@ extern "C" {
* For more information about how to use this file, see @ref build_include.
*/
/*! @defgroup context Context reference
+ * @brief Functions and types related to OpenGL and OpenGL ES contexts.
*
* This is the reference documentation for OpenGL and OpenGL ES context related
* functions. For more task-oriented information, see the @ref context_guide.
*/
/*! @defgroup vulkan Vulkan reference
+ * @brief Functions and types related to Vulkan.
*
* This is the reference documentation for Vulkan related functions and types.
* For more task-oriented information, see the @ref vulkan_guide.
*/
/*! @defgroup init Initialization, version and error reference
+ * @brief Functions and types related to initialization and error handling.
*
* This is the reference documentation for initialization and termination of
* the library, version management and error handling. For more task-oriented
* information, see the @ref intro_guide.
*/
/*! @defgroup input Input reference
+ * @brief Functions and types related to input handling.
*
* This is the reference documentation for input related functions and types.
* For more task-oriented information, see the @ref input_guide.
*/
/*! @defgroup monitor Monitor reference
+ * @brief Functions and types related to monitors.
*
* This is the reference documentation for monitor related functions and types.
* For more task-oriented information, see the @ref monitor_guide.
*/
/*! @defgroup window Window reference
+ * @brief Functions and types related to windows.
*
* This is the reference documentation for window related functions and types,
* including creation, deletion and event polling. For more task-oriented
@@ -99,6 +105,7 @@ extern "C" {
#else
#define APIENTRY
#endif
+ #define GLFW_APIENTRY_DEFINED
#endif /* APIENTRY */
/* Some Windows OpenGL headers need this.
@@ -115,65 +122,98 @@ extern "C" {
#define GLFW_CALLBACK_DEFINED
#endif /* CALLBACK */
-/* Most Windows GLU headers need wchar_t.
- * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
+/* Include because most Windows GLU headers need wchar_t and
+ * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h.
* Include it unconditionally to avoid surprising side-effects.
*/
#include <stddef.h>
+
+/* Include because it is needed by Vulkan and related functions.
+ * Include it unconditionally to avoid surprising side-effects.
+ */
#include <stdint.h>
-/* Include the chosen client API headers.
+/* Include the chosen OpenGL or OpenGL ES headers.
*/
-#if defined(__APPLE__)
- #if defined(GLFW_INCLUDE_GLCOREARB)
+#if defined(GLFW_INCLUDE_ES1)
+
+ #include <GLES/gl.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES/glext.h>
+ #endif
+
+#elif defined(GLFW_INCLUDE_ES2)
+
+ #include <GLES2/gl2.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+
+#elif defined(GLFW_INCLUDE_ES3)
+
+ #include <GLES3/gl3.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+
+#elif defined(GLFW_INCLUDE_ES31)
+
+ #include <GLES3/gl31.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+
+#elif defined(GLFW_INCLUDE_ES32)
+
+ #include <GLES3/gl32.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+
+#elif defined(GLFW_INCLUDE_GLCOREARB)
+
+ #if defined(__APPLE__)
+
#include <OpenGL/gl3.h>
#if defined(GLFW_INCLUDE_GLEXT)
#include <OpenGL/gl3ext.h>
- #endif
- #elif !defined(GLFW_INCLUDE_NONE)
+ #endif /*GLFW_INCLUDE_GLEXT*/
+
+ #else /*__APPLE__*/
+
+ #include <GL/glcorearb.h>
+
+ #endif /*__APPLE__*/
+
+#elif !defined(GLFW_INCLUDE_NONE)
+
+ #if defined(__APPLE__)
+
#if !defined(GLFW_INCLUDE_GLEXT)
#define GL_GLEXT_LEGACY
#endif
#include <OpenGL/gl.h>
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include <OpenGL/glu.h>
- #endif
-#else
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include <GL/glcorearb.h>
- #elif defined(GLFW_INCLUDE_ES1)
- #include <GLES/gl.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES/glext.h>
- #endif
- #elif defined(GLFW_INCLUDE_ES2)
- #include <GLES2/gl2.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES2/gl2ext.h>
- #endif
- #elif defined(GLFW_INCLUDE_ES3)
- #include <GLES3/gl3.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES2/gl2ext.h>
- #endif
- #elif defined(GLFW_INCLUDE_ES31)
- #include <GLES3/gl31.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES2/gl2ext.h>
+ #if defined(GLFW_INCLUDE_GLU)
+ #include <OpenGL/glu.h>
#endif
- #elif defined(GLFW_INCLUDE_VULKAN)
- #include <vulkan/vulkan.h>
- #elif !defined(GLFW_INCLUDE_NONE)
+
+ #else /*__APPLE__*/
+
#include <GL/gl.h>
#if defined(GLFW_INCLUDE_GLEXT)
#include <GL/glext.h>
#endif
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include <GL/glu.h>
- #endif
-#endif
+ #if defined(GLFW_INCLUDE_GLU)
+ #include <GL/glu.h>
+ #endif
+
+ #endif /*__APPLE__*/
+
+#endif /* OpenGL and OpenGL ES headers */
+
+#if defined(GLFW_INCLUDE_VULKAN)
+ #include <vulkan/vulkan.h>
+#endif /* Vulkan header */
#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
/* GLFW_DLL must be defined by applications that are linking against the DLL
@@ -219,7 +259,7 @@ extern "C" {
* backward-compatible.
* @ingroup init
*/
-#define GLFW_VERSION_MINOR 2
+#define GLFW_VERSION_MINOR 3
/*! @brief The revision number of the GLFW library.
*
* This is incremented when a bug fix release is made that does not contain any
@@ -234,14 +274,14 @@ extern "C" {
/*! @brief One.
*
* One. Seriously. You don't _need_ to use this symbol in your code. It's
- * just semantic sugar for the number 1. You can use `1` or `true` or `_True`
+ * semantic sugar for the number 1. You can also use `1` or `true` or `_True`
* or `GL_TRUE` or whatever you want.
*/
#define GLFW_TRUE 1
/*! @brief Zero.
*
* Zero. Seriously. You don't _need_ to use this symbol in your code. It's
- * just just semantic sugar for the number 0. You can use `0` or `false` or
+ * semantic sugar for the number 0. You can also use `0` or `false` or
* `_False` or `GL_FALSE` or whatever you want.
*/
#define GLFW_FALSE 0
@@ -272,7 +312,25 @@ extern "C" {
#define GLFW_REPEAT 2
/*! @} */
+/*! @defgroup hat_state Joystick hat states
+ *
+ * See [joystick hat input](@ref joystick_hat) for how these are used.
+ *
+ * @ingroup input
+ * @{ */
+#define GLFW_HAT_CENTERED 0
+#define GLFW_HAT_UP 1
+#define GLFW_HAT_RIGHT 2
+#define GLFW_HAT_DOWN 4
+#define GLFW_HAT_LEFT 8
+#define GLFW_HAT_RIGHT_UP (GLFW_HAT_RIGHT | GLFW_HAT_UP)
+#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
+#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP)
+#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
+/*! @} */
+
/*! @defgroup keys Keyboard keys
+ * @brief Keyboard key IDs.
*
* See [key input](@ref input_key) for how these are used.
*
@@ -427,6 +485,7 @@ extern "C" {
/*! @} */
/*! @defgroup mods Modifier key flags
+ * @brief Modifier key flags.
*
* See [key input](@ref input_key) for how these are used.
*
@@ -449,6 +508,7 @@ extern "C" {
/*! @} */
/*! @defgroup buttons Mouse buttons
+ * @brief Mouse button IDs.
*
* See [mouse button input](@ref input_mouse_button) for how these are used.
*
@@ -469,6 +529,7 @@ extern "C" {
/*! @} */
/*! @defgroup joysticks Joysticks
+ * @brief Joystick IDs.
*
* See [joystick input](@ref joystick) for how these are used.
*
@@ -493,12 +554,66 @@ extern "C" {
#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
/*! @} */
+/*! @defgroup gamepad_buttons Gamepad buttons
+ * @brief Gamepad buttons.
+ *
+ * See @ref gamepad for how these are used.
+ *
+ * @ingroup input
+ * @{ */
+#define GLFW_GAMEPAD_BUTTON_A 0
+#define GLFW_GAMEPAD_BUTTON_B 1
+#define GLFW_GAMEPAD_BUTTON_X 2
+#define GLFW_GAMEPAD_BUTTON_Y 3
+#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4
+#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5
+#define GLFW_GAMEPAD_BUTTON_BACK 6
+#define GLFW_GAMEPAD_BUTTON_START 7
+#define GLFW_GAMEPAD_BUTTON_GUIDE 8
+#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9
+#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10
+#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11
+#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12
+#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13
+#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14
+#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT
+
+#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A
+#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B
+#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X
+#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y
+/*! @} */
+
+/*! @defgroup gamepad_axes Gamepad axes
+ * @brief Gamepad axes.
+ *
+ * See @ref gamepad for how these are used.
+ *
+ * @ingroup input
+ * @{ */
+#define GLFW_GAMEPAD_AXIS_LEFT_X 0
+#define GLFW_GAMEPAD_AXIS_LEFT_Y 1
+#define GLFW_GAMEPAD_AXIS_RIGHT_X 2
+#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3
+#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4
+#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5
+#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
+/*! @} */
+
/*! @defgroup errors Error codes
+ * @brief Error codes.
*
* See [error handling](@ref error_handling) for how these are used.
*
* @ingroup init
* @{ */
+/*! @brief No error has occurred.
+ *
+ * No error has occurred.
+ *
+ * @analysis Yay.
+ */
+#define GLFW_NO_ERROR 0
/*! @brief GLFW has not been initialized.
*
* This occurs if a GLFW function was called that must not be called unless the
@@ -521,8 +636,7 @@ extern "C" {
/*! @brief One of the arguments to the function was an invalid enum value.
*
* One of the arguments to the function was an invalid enum value, for example
- * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref
- * glfwGetWindowAttrib.
+ * requesting @ref GLFW_RED_BITS with @ref glfwGetWindowAttrib.
*
* @analysis Application programmer error. Fix the offending call.
*/
@@ -557,7 +671,7 @@ extern "C" {
* @par
* Some pre-installed Windows graphics drivers do not support OpenGL. AMD only
* supports OpenGL ES via EGL, while Nvidia and Intel only support it via
- * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
+ * a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa
* EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
* driver. Older graphics drivers do not support Vulkan.
*/
@@ -619,44 +733,220 @@ extern "C" {
#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
/*! @} */
+/*! @addtogroup window
+ * @{ */
+/*! @brief Input focus window hint and attribute
+ *
+ * Input focus [window hint](@ref GLFW_FOCUSED_hint) or
+ * [window attribute](@ref GLFW_FOCUSED_attrib).
+ */
#define GLFW_FOCUSED 0x00020001
+/*! @brief Window iconification window attribute
+ *
+ * Window iconification [window attribute](@ref GLFW_ICONIFIED_attrib).
+ */
#define GLFW_ICONIFIED 0x00020002
+/*! @brief Window resize-ability window hint and attribute
+ *
+ * Window resize-ability [window hint](@ref GLFW_RESIZABLE_hint) and
+ * [window attribute](@ref GLFW_RESIZABLE_attrib).
+ */
#define GLFW_RESIZABLE 0x00020003
+/*! @brief Window visibility window hint and attribute
+ *
+ * Window visibility [window hint](@ref GLFW_VISIBLE_hint) and
+ * [window attribute](@ref GLFW_VISIBLE_attrib).
+ */
#define GLFW_VISIBLE 0x00020004
+/*! @brief Window decoration window hint and attribute
+ *
+ * Window decoration [window hint](@ref GLFW_DECORATED_hint) and
+ * [window attribute](@ref GLFW_DECORATED_attrib).
+ */
#define GLFW_DECORATED 0x00020005
+/*! @brief Window auto-iconification window hint and attribute
+ *
+ * Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and
+ * [window attribute](@ref GLFW_AUTO_ICONIFY_attrib).
+ */
#define GLFW_AUTO_ICONIFY 0x00020006
+/*! @brief Window decoration window hint and attribute
+ *
+ * Window decoration [window hint](@ref GLFW_FLOATING_hint) and
+ * [window attribute](@ref GLFW_FLOATING_attrib).
+ */
#define GLFW_FLOATING 0x00020007
+/*! @brief Window maximization window hint and attribute
+ *
+ * Window maximization [window hint](@ref GLFW_MAXIMIZED_hint) and
+ * [window attribute](@ref GLFW_MAXIMIZED_attrib).
+ */
#define GLFW_MAXIMIZED 0x00020008
+/*! @brief Cursor centering window hint
+ *
+ * Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint).
+ */
+#define GLFW_CENTER_CURSOR 0x00020009
+/*! @brief Window framebuffer transparency hint and attribute
+ *
+ * Window framebuffer transparency [window hint](@ref GLFW_TRANSPARENT_hint)
+ * and [window attribute](@ref GLFW_TRANSPARENT_attrib).
+ */
+#define GLFW_TRANSPARENT 0x0002000A
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
+ */
#define GLFW_RED_BITS 0x00021001
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_GREEN_BITS).
+ */
#define GLFW_GREEN_BITS 0x00021002
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_BLUE_BITS).
+ */
#define GLFW_BLUE_BITS 0x00021003
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_ALPHA_BITS).
+ */
#define GLFW_ALPHA_BITS 0x00021004
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_DEPTH_BITS).
+ */
#define GLFW_DEPTH_BITS 0x00021005
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_STENCIL_BITS).
+ */
#define GLFW_STENCIL_BITS 0x00021006
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_RED_BITS).
+ */
#define GLFW_ACCUM_RED_BITS 0x00021007
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_GREEN_BITS).
+ */
#define GLFW_ACCUM_GREEN_BITS 0x00021008
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_BLUE_BITS).
+ */
#define GLFW_ACCUM_BLUE_BITS 0x00021009
+/*! @brief Framebuffer bit depth hint.
+ *
+ * Framebuffer bit depth [hint](@ref GLFW_ACCUM_ALPHA_BITS).
+ */
#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
+/*! @brief Framebuffer auxiliary buffer hint.
+ *
+ * Framebuffer auxiliary buffer [hint](@ref GLFW_AUX_BUFFERS).
+ */
#define GLFW_AUX_BUFFERS 0x0002100B
+/*! @brief OpenGL stereoscopic rendering hint.
+ *
+ * OpenGL stereoscopic rendering [hint](@ref GLFW_STEREO).
+ */
#define GLFW_STEREO 0x0002100C
+/*! @brief Framebuffer MSAA samples hint.
+ *
+ * Framebuffer MSAA samples [hint](@ref GLFW_SAMPLES).
+ */
#define GLFW_SAMPLES 0x0002100D
+/*! @brief Framebuffer sRGB hint.
+ *
+ * Framebuffer sRGB [hint](@ref GLFW_SRGB_CAPABLE).
+ */
#define GLFW_SRGB_CAPABLE 0x0002100E
+/*! @brief Monitor refresh rate hint.
+ *
+ * Monitor refresh rate [hint](@ref GLFW_REFRESH_RATE).
+ */
#define GLFW_REFRESH_RATE 0x0002100F
+/*! @brief Framebuffer double buffering hint.
+ *
+ * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER).
+ */
#define GLFW_DOUBLEBUFFER 0x00021010
+/*! @brief Context client API hint and attribute.
+ *
+ * Context client API [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CLIENT_API 0x00022001
+/*! @brief Context client API major version hint and attribute.
+ *
+ * Context client API major version [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
+/*! @brief Context client API minor version hint and attribute.
+ *
+ * Context client API minor version [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
+/*! @brief Context client API revision number hint and attribute.
+ *
+ * Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_REVISION 0x00022004
+/*! @brief Context robustness hint and attribute.
+ *
+ * Context client API revision number [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
+/*! @brief OpenGL forward-compatibility hint and attribute.
+ *
+ * OpenGL forward-compatibility [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
+/*! @brief OpenGL debug context hint and attribute.
+ *
+ * OpenGL debug context [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
+/*! @brief OpenGL profile hint and attribute.
+ *
+ * OpenGL profile [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_OPENGL_PROFILE 0x00022008
+/*! @brief Context flush-on-release hint and attribute.
+ *
+ * Context flush-on-release [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
+/*! @brief Context error suppression hint and attribute.
+ *
+ * Context error suppression [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_NO_ERROR 0x0002200A
+/*! @brief Context creation API hint and attribute.
+ *
+ * Context creation API [hint](@ref GLFW_CLIENT_API_hint) and
+ * [attribute](@ref GLFW_CLIENT_API_attrib).
+ */
#define GLFW_CONTEXT_CREATION_API 0x0002200B
+#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
+#define GLFW_COCOA_FRAME_AUTOSAVE 0x00023002
+#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003
+/*! @} */
+
#define GLFW_NO_API 0
#define GLFW_OPENGL_API 0x00030001
#define GLFW_OPENGL_ES_API 0x00030002
@@ -683,8 +973,10 @@ extern "C" {
#define GLFW_NATIVE_CONTEXT_API 0x00036001
#define GLFW_EGL_CONTEXT_API 0x00036002
+#define GLFW_OSMESA_CONTEXT_API 0x00036003
/*! @defgroup shapes Standard cursor shapes
+ * @brief Standard system cursor shapes.
*
* See [standard cursor creation](@ref cursor_standard) for how these are used.
*
@@ -726,6 +1018,17 @@ extern "C" {
#define GLFW_CONNECTED 0x00040001
#define GLFW_DISCONNECTED 0x00040002
+/*! @addtogroup init
+ * @{ */
+#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
+
+#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001
+#define GLFW_COCOA_MENUBAR 0x00051002
+
+#define GLFW_X11_WM_CLASS_NAME 0x00052001
+#define GLFW_X11_WM_CLASS_CLASS 0x00052002
+/*! @} */
+
#define GLFW_DONT_CARE -1
@@ -739,7 +1042,7 @@ extern "C" {
* without forcing a cast from a regular pointer.
*
* @sa @ref context_glext
- * @sa glfwGetProcAddress
+ * @sa @ref glfwGetProcAddress
*
* @since Added in version 3.0.
@@ -753,7 +1056,7 @@ typedef void (*GLFWglproc)(void);
* without forcing a cast from a regular pointer.
*
* @sa @ref vulkan_proc
- * @sa glfwGetInstanceProcAddress
+ * @sa @ref glfwGetInstanceProcAddress
*
* @since Added in version 3.2.
*
@@ -805,7 +1108,7 @@ typedef struct GLFWcursor GLFWcursor;
* @param[in] description A UTF-8 encoded string describing the error.
*
* @sa @ref error_handling
- * @sa glfwSetErrorCallback
+ * @sa @ref glfwSetErrorCallback
*
* @since Added in version 3.0.
*
@@ -824,7 +1127,7 @@ typedef void (* GLFWerrorfun)(int,const char*);
* upper-left corner of the client area of the window.
*
* @sa @ref window_pos
- * @sa glfwSetWindowPosCallback
+ * @sa @ref glfwSetWindowPosCallback
*
* @since Added in version 3.0.
*
@@ -841,7 +1144,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
* @param[in] height The new height, in screen coordinates, of the window.
*
* @sa @ref window_size
- * @sa glfwSetWindowSizeCallback
+ * @sa @ref glfwSetWindowSizeCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
@@ -857,7 +1160,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
* @param[in] window The window that the user attempted to close.
*
* @sa @ref window_close
- * @sa glfwSetWindowCloseCallback
+ * @sa @ref glfwSetWindowCloseCallback
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter.
@@ -873,7 +1176,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*);
* @param[in] window The window whose content needs to be refreshed.
*
* @sa @ref window_refresh
- * @sa glfwSetWindowRefreshCallback
+ * @sa @ref glfwSetWindowRefreshCallback
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter.
@@ -891,7 +1194,7 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
* `GLFW_FALSE` if it lost it.
*
* @sa @ref window_focus
- * @sa glfwSetWindowFocusCallback
+ * @sa @ref glfwSetWindowFocusCallback
*
* @since Added in version 3.0.
*
@@ -909,7 +1212,7 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
* `GLFW_FALSE` if it was restored.
*
* @sa @ref window_iconify
- * @sa glfwSetWindowIconifyCallback
+ * @sa @ref glfwSetWindowIconifyCallback
*
* @since Added in version 3.0.
*
@@ -917,6 +1220,24 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
*/
typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
+/*! @brief The function signature for window maximize/restore callbacks.
+ *
+ * This is the function signature for window maximize/restore callback
+ * functions.
+ *
+ * @param[in] window The window that was maximized or restored.
+ * @param[in] iconified `GLFW_TRUE` if the window was maximized, or
+ * `GLFW_FALSE` if it was restored.
+ *
+ * @sa @ref window_maximize
+ * @sa glfwSetWindowMaximizeCallback
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup window
+ */
+typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int);
+
/*! @brief The function signature for framebuffer resize callbacks.
*
* This is the function signature for framebuffer resize callback
@@ -927,7 +1248,7 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
* @param[in] height The new height, in pixels, of the framebuffer.
*
* @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
+ * @sa @ref glfwSetFramebufferSizeCallback
*
* @since Added in version 3.0.
*
@@ -947,7 +1268,7 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
* held down.
*
* @sa @ref input_mouse_button
- * @sa glfwSetMouseButtonCallback
+ * @sa @ref glfwSetMouseButtonCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle and modifier mask parameters.
@@ -967,7 +1288,7 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
* client area.
*
* @sa @ref cursor_pos
- * @sa glfwSetCursorPosCallback
+ * @sa @ref glfwSetCursorPosCallback
*
* @since Added in version 3.0. Replaces `GLFWmouseposfun`.
*
@@ -984,7 +1305,7 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
* area, or `GLFW_FALSE` if it left it.
*
* @sa @ref cursor_enter
- * @sa glfwSetCursorEnterCallback
+ * @sa @ref glfwSetCursorEnterCallback
*
* @since Added in version 3.0.
*
@@ -1001,7 +1322,7 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
* @param[in] yoffset The scroll offset along the y-axis.
*
* @sa @ref scrolling
- * @sa glfwSetScrollCallback
+ * @sa @ref glfwSetScrollCallback
*
* @since Added in version 3.0. Replaces `GLFWmousewheelfun`.
*
@@ -1021,7 +1342,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
* held down.
*
* @sa @ref input_key
- * @sa glfwSetKeyCallback
+ * @sa @ref glfwSetKeyCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle, scancode and modifier mask parameters.
@@ -1038,7 +1359,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
* @param[in] codepoint The Unicode code point of the character.
*
* @sa @ref input_char
- * @sa glfwSetCharCallback
+ * @sa @ref glfwSetCharCallback
*
* @since Added in version 2.4.
* @glfw3 Added window handle parameter.
@@ -1060,7 +1381,7 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
* held down.
*
* @sa @ref input_char
- * @sa glfwSetCharModsCallback
+ * @sa @ref glfwSetCharModsCallback
*
* @since Added in version 3.1.
*
@@ -1077,7 +1398,7 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
* @param[in] paths The UTF-8 encoded file and/or directory path names.
*
* @sa @ref path_drop
- * @sa glfwSetDropCallback
+ * @sa @ref glfwSetDropCallback
*
* @since Added in version 3.1.
*
@@ -1093,7 +1414,7 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
* @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
*
* @sa @ref monitor_event
- * @sa glfwSetMonitorCallback
+ * @sa @ref glfwSetMonitorCallback
*
* @since Added in version 3.0.
*
@@ -1106,11 +1427,11 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
* This is the function signature for joystick configuration callback
* functions.
*
- * @param[in] joy The joystick that was connected or disconnected.
+ * @param[in] jid The joystick that was connected or disconnected.
* @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
*
* @sa @ref joystick_event
- * @sa glfwSetJoystickCallback
+ * @sa @ref glfwSetJoystickCallback
*
* @since Added in version 3.2.
*
@@ -1123,7 +1444,8 @@ typedef void (* GLFWjoystickfun)(int,int);
* This describes a single video mode.
*
* @sa @ref monitor_modes
- * @sa glfwGetVideoMode glfwGetVideoModes
+ * @sa @ref glfwGetVideoMode
+ * @sa @ref glfwGetVideoModes
*
* @since Added in version 1.0.
* @glfw3 Added refresh rate member.
@@ -1157,7 +1479,8 @@ typedef struct GLFWvidmode
* This describes the gamma ramp for a monitor.
*
* @sa @ref monitor_gamma
- * @sa glfwGetGammaRamp glfwSetGammaRamp
+ * @sa @ref glfwGetGammaRamp
+ * @sa @ref glfwSetGammaRamp
*
* @since Added in version 3.0.
*
@@ -1181,7 +1504,11 @@ typedef struct GLFWgammaramp
/*! @brief Image data.
*
+ * This describes a single 2D image. See the documentation for each related
+ * function what the expected pixel format is.
+ *
* @sa @ref cursor_custom
+ * @sa @ref window_icon
*
* @since Added in version 2.1.
* @glfw3 Removed format and bytes-per-pixel members.
@@ -1199,6 +1526,27 @@ typedef struct GLFWimage
unsigned char* pixels;
} GLFWimage;
+/*! @brief Gamepad input state
+ *
+ * This describes the input state of a gamepad.
+ *
+ * @sa @ref gamepad
+ * @sa @ref glfwGetGamepadState
+ *
+ * @since Added in version 3.3.
+ */
+typedef struct GLFWgamepadstate
+{
+ /*! The states of each [gamepad button](@ref gamepad_buttons), `GLFW_PRESS`
+ * or `GLFW_RELEASE`.
+ */
+ unsigned char buttons[15];
+ /*! The states of each [gamepad axis](@ref gamepad_axes), in the range -1.0
+ * to 1.0 inclusive.
+ */
+ float axes[6];
+} GLFWgamepadstate;
+
/*************************************************************************
* GLFW API functions
@@ -1222,15 +1570,15 @@ typedef struct GLFWimage
*
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
*
- * @remark @osx This function will change the current directory of the
+ * @remark @macos This function will change the current directory of the
* application to the `Contents/Resources` subdirectory of the application's
- * bundle, if present. This can be disabled with a
- * [compile-time option](@ref compile_options_osx).
+ * bundle, if present. This can be disabled with the @ref
+ * GLFW_COCOA_CHDIR_RESOURCES init hint.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref intro_init
- * @sa glfwTerminate
+ * @sa @ref glfwTerminate
*
* @since Added in version 1.0.
*
@@ -1262,7 +1610,7 @@ GLFWAPI int glfwInit(void);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref intro_init
- * @sa glfwInit
+ * @sa @ref glfwInit
*
* @since Added in version 1.0.
*
@@ -1270,6 +1618,74 @@ GLFWAPI int glfwInit(void);
*/
GLFWAPI void glfwTerminate(void);
+/*! @brief Sets the specified init hint to the desired value.
+ *
+ * This function sets hints for the next initialization of GLFW. Only integer
+ * type hints can be set with this function.
+ *
+ * The values you set hints to are never reset by GLFW, but they only take
+ * effect during initialization. Once GLFW has been initialized, any values
+ * you set will be ignored until the library is terminated and initialized
+ * again.
+ *
+ * Some hints are platform specific. These may be set on any platform but they
+ * will only affect their specific platform. Other platforms will ignore them.
+ * Setting these hints requires no platform specific headers or functions.
+ *
+ * @param[in] hint The [init hint](@ref init_hints) to set.
+ * @param[in] value The new value of the init hint.
+ *
+ * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref
+ * GLFW_INVALID_VALUE.
+ *
+ * @remarks This function may be called before @ref glfwInit.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa init_hints
+ * @sa glfwInit
+ * @sa glfwInitHintString
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup init
+ */
+GLFWAPI void glfwInitHint(int hint, int value);
+
+/*! @brief Sets the specified init hint to the desired value.
+ *
+ * This function sets hints for the next initialization of GLFW. Only string
+ * type hints can be set with this function.
+ *
+ * The values you set hints to are never reset by GLFW, but they only take
+ * effect during initialization. Once GLFW has been initialized, any values
+ * you set will be ignored until the library is terminated and initialized
+ * again.
+ *
+ * Some hints are platform specific. These may be set on any platform but they
+ * will only affect their specific platform. Other platforms will ignore them.
+ * Setting these hints requires no platform specific headers or functions.
+ *
+ * @param[in] hint The [init hint](@ref init_hints) to set.
+ * @param[in] value The new value of the init hint.
+ *
+ * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref
+ * GLFW_INVALID_VALUE.
+ *
+ * @remarks This function may be called before @ref glfwInit.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa init_hints
+ * @sa glfwInit
+ * @sa glfwInitHint
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup init
+ */
+GLFWAPI void glfwInitHintString(int hint, const char* value);
+
/*! @brief Retrieves the version of the GLFW library.
*
* This function retrieves the major, minor and revision numbers of the GLFW
@@ -1289,7 +1705,7 @@ GLFWAPI void glfwTerminate(void);
* @thread_safety This function may be called from any thread.
*
* @sa @ref intro_version
- * @sa glfwGetVersionString
+ * @sa @ref glfwGetVersionString
*
* @since Added in version 1.0.
*
@@ -1320,7 +1736,7 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
* @thread_safety This function may be called from any thread.
*
* @sa @ref intro_version
- * @sa glfwGetVersion
+ * @sa @ref glfwGetVersion
*
* @since Added in version 3.0.
*
@@ -1328,11 +1744,46 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
*/
GLFWAPI const char* glfwGetVersionString(void);
+/*! @brief Returns and clears the last error for the calling thread.
+ *
+ * This function returns and clears the [error code](@ref errors) of the last
+ * error that occurred on the calling thread, and optionally a UTF-8 encoded
+ * human-readable description of it. If no error has occurred since the last
+ * call, it returns @ref GLFW_NO_ERROR (zero) and the description pointer is
+ * set to `NULL`.
+ *
+ * @param[in] description Where to store the error description pointer, or `NULL`.
+ * @return The last error code for the calling thread, or @ref GLFW_NO_ERROR
+ * (zero).
+ *
+ * @errors None.
+ *
+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
+ * should not free it yourself. It is guaranteed to be valid only until the
+ * next error occurs or the library is terminated.
+ *
+ * @remark This function may be called before @ref glfwInit.
+ *
+ * @thread_safety This function may be called from any thread.
+ *
+ * @sa @ref error_handling
+ * @sa @ref glfwSetErrorCallback
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup init
+ */
+GLFWAPI int glfwGetError(const char** description);
+
/*! @brief Sets the error callback.
*
* This function sets the error callback, which is called with an error code
* and a human-readable description each time a GLFW error occurs.
*
+ * The error code is set before the callback is called. Calling @ref
+ * glfwGetError from the error callback will return the same value as the error
+ * code argument.
+ *
* The error callback is called on the thread where the error occurred. If you
* are using GLFW from multiple threads, your error callback needs to be
* written accordingly.
@@ -1355,6 +1806,7 @@ GLFWAPI const char* glfwGetVersionString(void);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref error_handling
+ * @sa @ref glfwGetError
*
* @since Added in version 3.0.
*
@@ -1383,7 +1835,7 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
*
* @sa @ref monitor_monitors
* @sa @ref monitor_event
- * @sa glfwGetPrimaryMonitor
+ * @sa @ref glfwGetPrimaryMonitor
*
* @since Added in version 3.0.
*
@@ -1407,7 +1859,7 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
* glfwGetMonitors.
*
* @sa @ref monitor_monitors
- * @sa glfwGetMonitors
+ * @sa @ref glfwGetMonitors
*
* @since Added in version 3.0.
*
@@ -1474,6 +1926,36 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
*/
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
+/*! @brief Retrieves the content scale for the specified monitor.
+ *
+ * This function retrieves the content scale for the specified monitor. The
+ * content scale is the ratio between the current DPI and the platform's
+ * default DPI. If you scale all pixel dimensions by this scale then your
+ * content should appear at an appropriate size. This is especially important
+ * for text and any UI elements.
+ *
+ * The content scale may depend on both the monitor resolution and pixel
+ * density and on user settings. It may be very different from the raw DPI
+ * calculated from the physical size and current resolution.
+ *
+ * @param[in] monitor The monitor to query.
+ * @param[out] xscale Where to store the x-axis content scale, or `NULL`.
+ * @param[out] yscale Where to store the y-axis content scale, or `NULL`.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_PLATFORM_ERROR.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref monitor_scale
+ * @sa @ref glfwGetWindowContentScale
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup monitor
+ */
+GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale);
+
/*! @brief Returns the name of the specified monitor.
*
* This function returns a human-readable name, encoded as UTF-8, of the
@@ -1547,7 +2029,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref monitor_modes
- * @sa glfwGetVideoMode
+ * @sa @ref glfwGetVideoMode
*
* @since Added in version 1.0.
* @glfw3 Changed to return an array of modes for a specific monitor.
@@ -1576,7 +2058,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref monitor_modes
- * @sa glfwGetVideoModes
+ * @sa @ref glfwGetVideoModes
*
* @since Added in version 3.0. Replaces `glfwGetDesktopMode`.
*
@@ -1590,12 +2072,23 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* and then calls @ref glfwSetGammaRamp with it. The value must be a finite
* number greater than zero.
*
+ * The software controlled gamma ramp is applied _in addition_ to the hardware
+ * gamma correction, which today is usually an approximation of sRGB gamma.
+ * This means that setting a perfectly linear ramp, or gamma 1.0, will produce
+ * the default (usually sRGB-like) behavior.
+ *
+ * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref
+ * GLFW_SRGB_CAPABLE hint.
+ *
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] gamma The desired exponent.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland Gamma handling is currently unavailable, this function will
+ * always emit @ref GLFW_PLATFORM_ERROR.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref monitor_gamma
@@ -1617,6 +2110,9 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland Gamma handling is currently unavailable, this function will
+ * always return `NULL` and emit @ref GLFW_PLATFORM_ERROR.
+ *
* @pointer_lifetime The returned structure and its arrays are allocated and
* freed by GLFW. You should not free them yourself. They are valid until the
* specified monitor is disconnected, this function is called again for that
@@ -1638,6 +2134,14 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* original gamma ramp for that monitor is saved by GLFW the first time this
* function is called and is restored by @ref glfwTerminate.
*
+ * The software controlled gamma ramp is applied _in addition_ to the hardware
+ * gamma correction, which today is usually an approximation of sRGB gamma.
+ * This means that setting a perfectly linear ramp, or gamma 1.0, will produce
+ * the default (usually sRGB-like) behavior.
+ *
+ * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref
+ * GLFW_SRGB_CAPABLE hint.
+ *
* @param[in] monitor The monitor whose gamma ramp to set.
* @param[in] ramp The gamma ramp to use.
*
@@ -1649,6 +2153,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
*
* @remark @win32 The gamma ramp size must be 256.
*
+ * @remark @wayland Gamma handling is currently unavailable, this function will
+ * always emit @ref GLFW_PLATFORM_ERROR.
+ *
* @pointer_lifetime The specified gamma ramp is copied before this function
* returns.
*
@@ -1672,7 +2179,7 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_hints
- * @sa glfwWindowHint
+ * @sa @ref glfwWindowHint
*
* @since Added in version 3.0.
*
@@ -1700,7 +2207,7 @@ GLFWAPI void glfwDefaultWindowHints(void);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_hints
- * @sa glfwDefaultWindowHints
+ * @sa @ref glfwDefaultWindowHints
*
* @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
*
@@ -1739,9 +2246,13 @@ GLFWAPI void glfwWindowHint(int hint, int value);
* screen windows, including the creation of so called _windowed full screen_
* or _borderless full screen_ windows, see @ref window_windowed_full_screen.
*
+ * Once you have created the window, you can switch it between windowed and
+ * full screen mode with @ref glfwSetWindowMonitor. This will not affect its
+ * OpenGL or OpenGL ES context.
+ *
* By default, newly created windows use the placement recommended by the
* window system. To create the window at a specific position, make it
- * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
+ * initially invisible using the [GLFW_VISIBLE](@ref GLFW_VISIBLE_hint) window
* hint, set its [position](@ref window_pos) and then [show](@ref window_hide)
* it.
*
@@ -1783,27 +2294,41 @@ GLFWAPI void glfwWindowHint(int hint, int value);
* @remark @win32 The context to share resources with must not be current on
* any other thread.
*
- * @remark @osx The GLFW window has no icon, as it is not a document
+ * @remark @macos The OS only supports forward-compatible 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_FORWARD_COMPAT](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) and
+ * [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hints accordingly.
+ * OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
+ *
+ * @remark @macos The GLFW window has no icon, as it is not a document
* window, but the dock icon will be the same as the application bundle's icon.
* For more information on bundles, see the
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
* in the Mac Developer Library.
*
- * @remark @osx The first time a window is created the menu bar is populated
- * with common commands like Hide, Quit and About. The About entry opens
- * a minimal about dialog with information from the application's bundle. The
- * menu bar can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @remark @osx On OS X 10.10 and later the window frame will not be rendered
- * at full resolution on Retina displays unless the `NSHighResolutionCapable`
- * key is enabled in the application bundle's `Info.plist`. For more
- * information, see
+ * @remark @macos The first time a window is created the menu bar is created.
+ * If GLFW finds a `MainMenu.nib` it is loaded and assumed to contain a menu
+ * bar. Otherwise a minimal menu bar is created manually with common commands
+ * like Hide, Quit and About. The About entry opens a minimal about dialog
+ * with information from the application's bundle. Menu bar creation can be
+ * disabled entirely with the @ref GLFW_COCOA_MENUBAR init hint.
+ *
+ * @remark @macos On OS X 10.10 and later the window frame will not be rendered
+ * at full resolution on Retina displays unless the
+ * [GLFW_COCOA_RETINA_FRAMEBUFFER](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint)
+ * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
+ * application bundle's `Info.plist`. For more information, see
* [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
* in the Mac Developer Library. The GLFW test and example programs use
* a custom `Info.plist` template for this, which can be found as
* `CMake/MacOSXBundleInfo.plist.in` in the source tree.
*
+ * @remark @macos When activating frame autosaving with
+ * [GLFW_COCOA_FRAME_AUTOSAVE](@ref GLFW_COCOA_FRAME_AUTOSAVE_hint), the
+ * specified window size may be overriden by a previously saved size and
+ * position.
+ *
* @remark @x11 Some window managers will not respect the placement of
* initially hidden windows.
*
@@ -1812,12 +2337,29 @@ GLFWAPI void glfwWindowHint(int hint, int value);
* query the final size, position or other attributes directly after window
* creation.
*
- * @reentrancy This function must not be called from a callback.
+ * @remark @x11 The name and class of the `WM_CLASS` window property will by
+ * default be set to the window title passed to this function. Set the @ref
+ * GLFW_X11_WM_CLASS_NAME and @ref GLFW_X11_WM_CLASS_CLASS init hints before
+ * initialization to override this.
+ *
+ * @remark @wayland The window frame is currently unimplemented, as if
+ * [GLFW_DECORATED](@ref GLFW_DECORATED_hint) was always set to `GLFW_FALSE`.
+ * A compositor can still emit close, resize or maximize events, using for
+ * example a keybind mechanism.
+ *
+ * @remark @wayland A full screen window will not attempt to change the mode,
+ * no matter what the requested size or refresh rate.
+ *
+ * @remark @wayland The wl_shell protocol does not support window
+ * icons, the window will inherit the one defined in the application's
+ * desktop file, so this function emits @ref GLFW_PLATFORM_ERROR.
+ *
+ * @remark @wayland Screensaver inhibition is currently unimplemented.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_creation
- * @sa glfwDestroyWindow
+ * @sa @ref glfwDestroyWindow
*
* @since Added in version 3.0. Replaces `glfwOpenWindow`.
*
@@ -1846,7 +2388,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_creation
- * @sa glfwCreateWindow
+ * @sa @ref glfwCreateWindow
*
* @since Added in version 3.0. Replaces `glfwCloseWindow`.
*
@@ -1907,7 +2449,7 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
- * @remark @osx The window title will not be updated until the next time you
+ * @remark @macos The window title will not be updated until the next time you
* process events.
*
* @thread_safety This function must only be called from the main thread.
@@ -1928,6 +2470,10 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* selected. If no images are specified, the window reverts to its default
* icon.
*
+ * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
+ * bits per channel with the red channel first. They are arranged canonically
+ * as packed sequential rows, starting from the top-left corner.
+ *
* The desired image sizes varies depending on platform and system settings.
* The selected images will be rescaled as needed. Good sizes include 16x16,
* 32x32 and 48x48.
@@ -1944,12 +2490,16 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* @pointer_lifetime The specified image data is copied before this function
* returns.
*
- * @remark @osx The GLFW window has no icon, as it is not a document
+ * @remark @macos The GLFW window has no icon, as it is not a document
* window, so this function does nothing. The dock icon will be the same as
* the application bundle's icon. For more information on bundles, see the
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
* in the Mac Developer Library.
*
+ * @remark @wayland The wl_shell protocol does not support icons, the window
+ * will inherit the one defined in the application's desktop file, so this
+ * function emits @ref GLFW_PLATFORM_ERROR.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_icon
@@ -1977,10 +2527,14 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland There is no way for an application to retrieve the global
+ * position of its windows, this function will always emit @ref
+ * GLFW_PLATFORM_ERROR.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_pos
- * @sa glfwSetWindowPos
+ * @sa @ref glfwSetWindowPos
*
* @since Added in version 3.0.
*
@@ -2007,10 +2561,14 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland There is no way for an application to set the global
+ * position of its windows, this function will always emit @ref
+ * GLFW_PLATFORM_ERROR.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_pos
- * @sa glfwGetWindowPos
+ * @sa @ref glfwGetWindowPos
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
@@ -2040,7 +2598,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_size
- * @sa glfwSetWindowSize
+ * @sa @ref glfwSetWindowSize
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
@@ -2078,10 +2636,13 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
* @remark If you set size limits and an aspect ratio that conflict, the
* results are undefined.
*
+ * @remark @wayland The size limits will not be applied until the window is
+ * actually resized, either by the user or by the compositor.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_sizelimits
- * @sa glfwSetWindowAspectRatio
+ * @sa @ref glfwSetWindowAspectRatio
*
* @since Added in version 3.2.
*
@@ -2118,10 +2679,13 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
* @remark If you set size limits and an aspect ratio that conflict, the
* results are undefined.
*
+ * @remark @wayland The aspect ratio will not be applied until the window is
+ * actually resized, either by the user or by the compositor.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_sizelimits
- * @sa glfwSetWindowSizeLimits
+ * @sa @ref glfwSetWindowSizeLimits
*
* @since Added in version 3.2.
*
@@ -2154,11 +2718,14 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland A full screen window will not attempt to change the mode,
+ * no matter what the requested size.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_size
- * @sa glfwGetWindowSize
- * @sa glfwSetWindowMonitor
+ * @sa @ref glfwGetWindowSize
+ * @sa @ref glfwSetWindowMonitor
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
@@ -2188,7 +2755,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
+ * @sa @ref glfwSetFramebufferSizeCallback
*
* @since Added in version 3.0.
*
@@ -2223,6 +2790,10 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height)
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland The window frame is currently unimplemented, as if
+ * [GLFW_DECORATED](@ref GLFW_DECORATED_hint) was always set to `GLFW_FALSE`,
+ * so the returned values will always be zero.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_size
@@ -2233,6 +2804,36 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height)
*/
GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
+/*! @brief Retrieves the content scale for the specified window.
+ *
+ * This function retrieves the content scale for the specified window. The
+ * content scale is the ratio between the current DPI and the platform's
+ * default DPI. If you scale all pixel dimensions by this scale then your
+ * content should appear at an appropriate size. This is especially important
+ * for text and any UI elements.
+ *
+ * On systems where each monitors can have its own content scale, the window
+ * content scale will depend on which monitor the system considers the window
+ * to be on.
+ *
+ * @param[in] window The window to query.
+ * @param[out] xscale Where to store the x-axis content scale, or `NULL`.
+ * @param[out] yscale Where to store the y-axis content scale, or `NULL`.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_PLATFORM_ERROR.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref window_scale
+ * @sa @ref glfwGetMonitorContentScale
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup window
+ */
+GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale);
+
/*! @brief Iconifies the specified window.
*
* This function iconifies (minimizes) the specified window if it was
@@ -2247,11 +2848,14 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland There is no concept of iconification in wl_shell, this
+ * function will always emit @ref GLFW_PLATFORM_ERROR.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
- * @sa glfwRestoreWindow
- * @sa glfwMaximizeWindow
+ * @sa @ref glfwRestoreWindow
+ * @sa @ref glfwMaximizeWindow
*
* @since Added in version 2.1.
* @glfw3 Added window handle parameter.
@@ -2277,8 +2881,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwMaximizeWindow
+ * @sa @ref glfwIconifyWindow
+ * @sa @ref glfwMaximizeWindow
*
* @since Added in version 2.1.
* @glfw3 Added window handle parameter.
@@ -2303,8 +2907,8 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
* This function may only be called from the main thread.
*
* @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwRestoreWindow
+ * @sa @ref glfwIconifyWindow
+ * @sa @ref glfwRestoreWindow
*
* @since Added in GLFW 3.2.
*
@@ -2326,7 +2930,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_hide
- * @sa glfwHideWindow
+ * @sa @ref glfwHideWindow
*
* @since Added in version 3.0.
*
@@ -2348,7 +2952,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_hide
- * @sa glfwShowWindow
+ * @sa @ref glfwShowWindow
*
* @since Added in version 3.0.
*
@@ -2362,21 +2966,28 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* The window should already be visible and not iconified.
*
* By default, both windowed and full screen mode windows are focused when
- * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable
- * this behavior.
+ * initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to
+ * disable this behavior.
*
* __Do not use this function__ to steal focus from other applications unless
* you are certain that is what the user wants. Focus stealing can be
* extremely disruptive.
*
+ * For a less disruptive way of getting the user's attention, see
+ * [attention requests](@ref window_attention).
+ *
* @param[in] window The window to give input focus.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland It is not possible for an application to bring its windows
+ * to front, this function will always emit @ref GLFW_PLATFORM_ERROR.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_focus
+ * @sa @ref window_attention
*
* @since Added in version 3.2.
*
@@ -2384,21 +2995,48 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
*/
GLFWAPI void glfwFocusWindow(GLFWwindow* window);
+/*! @brief Requests user attention to the specified window.
+ *
+ * This function requests user attention to the specified window. On
+ * platforms where this is not supported, attention is requested to the
+ * application as a whole.
+ *
+ * Once the user has given attention, usually by focusing the window or
+ * application, the system will end the request automatically.
+ *
+ * @param[in] window The window to request attention to.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_PLATFORM_ERROR.
+ *
+ * @remark @macos Attention is requested to the application as a whole, not the
+ * specific window.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref window_attention
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup window
+ */
+GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window);
+
/*! @brief Returns the monitor that the window uses for full screen mode.
*
* This function returns the handle of the monitor that the specified window is
* in full screen on.
*
* @param[in] window The window to query.
- * @return The monitor, or `NULL` if the window is in windowed mode or an error
- * occurred.
+ * @return The monitor, or `NULL` if the window is in windowed mode or an
+ * [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_monitor
- * @sa glfwSetWindowMonitor
+ * @sa @ref glfwSetWindowMonitor
*
* @since Added in version 3.0.
*
@@ -2424,7 +3062,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
*
* When a window transitions from full screen to windowed mode, this function
* restores any previous window settings such as whether it is decorated,
- * floating, resizable, has size or aspect ratio limits, etc..
+ * floating, resizable, has size or aspect ratio limits, etc.
*
* @param[in] window The window whose monitor, size or video mode to set.
* @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
@@ -2442,12 +3080,22 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark The OpenGL or OpenGL ES context will not be destroyed or otherwise
+ * affected by any resizing or mode switching, although you may need to update
+ * your viewport if the framebuffer size has changed.
+ *
+ * @remark @wayland The desired window position is ignored, as there is no way
+ * for an application to set this property.
+ *
+ * @remark @wayland Setting the window to full screen will not attempt to
+ * change the mode, no matter what the requested size or refresh rate.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_monitor
* @sa @ref window_full_screen
- * @sa glfwGetWindowMonitor
- * @sa glfwSetWindowSize
+ * @sa @ref glfwGetWindowMonitor
+ * @sa @ref glfwSetWindowSize
*
* @since Added in version 3.2.
*
@@ -2480,6 +3128,7 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_attribs
+ * @sa @ref glfwSetWindowAttrib
*
* @since Added in version 3.0. Replaces `glfwGetWindowParam` and
* `glfwGetGLVersion`.
@@ -2488,6 +3137,42 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
*/
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
+/*! @brief Sets an attribute of the specified window.
+ *
+ * This function sets the value of an attribute of the specified window.
+ *
+ * The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
+ * [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib),
+ * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) and
+ * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib).
+ *
+ * Some of these attributes are ignored for full screen windows. The new
+ * value will take effect if the window is later made windowed.
+ *
+ * Some of these attributes are ignored for windowed mode windows. The new
+ * value will take effect if the window is later made full screen.
+ *
+ * @param[in] window The window to set the attribute for.
+ * @param[in] attrib A supported window attribute.
+ * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
+ * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
+ *
+ * @remark Calling @ref glfwGetWindowAttrib will always return the latest
+ * value, even if that value is ignored by the current mode of the window.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref window_attribs
+ * @sa @ref glfwGetWindowAttrib
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup window
+ */
+GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value);
+
/*! @brief Sets the user pointer of the specified window.
*
* This function sets the user-defined pointer of the specified window. The
@@ -2503,7 +3188,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
* synchronized.
*
* @sa @ref window_userptr
- * @sa glfwGetWindowUserPointer
+ * @sa @ref glfwGetWindowUserPointer
*
* @since Added in version 3.0.
*
@@ -2524,7 +3209,7 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
* synchronized.
*
* @sa @ref window_userptr
- * @sa glfwSetWindowUserPointer
+ * @sa @ref glfwSetWindowUserPointer
*
* @since Added in version 3.0.
*
@@ -2535,8 +3220,9 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
/*! @brief Sets the position callback for the specified window.
*
* This function sets the position callback of the specified window, which is
- * called when the window is moved. The callback is provided with the screen
- * position of the upper-left corner of the client area of the window.
+ * called when the window is moved. The callback is provided with the
+ * position, in screen coordinates, of the upper-left corner of the client area
+ * of the window.
*
* @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
@@ -2546,6 +3232,9 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
+ * @remark @wayland This callback will never be called, as there is no way for
+ * an application to know its global position.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_pos
@@ -2600,8 +3289,8 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
- * @remark @osx Selecting Quit from the application menu will trigger the close
- * callback for all windows.
+ * @remark @macos Selecting Quit from the application menu will trigger the
+ * close callback for all windows.
*
* @thread_safety This function must only be called from the main thread.
*
@@ -2620,9 +3309,9 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
* called when the client area of the window needs to be redrawn, for example
* if the window has been exposed after having been covered by another window.
*
- * On compositing window systems such as Aero, Compiz or Aqua, where the window
- * contents are saved off-screen, this callback may be called only very
- * infrequently or never at all.
+ * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where
+ * the window contents are saved off-screen, this callback may be called only
+ * very infrequently or never at all.
*
* @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
@@ -2684,6 +3373,9 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
+ * @remark @wayland The wl_shell protocol has no concept of iconification,
+ * this callback will never be called.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_iconify
@@ -2694,6 +3386,29 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*/
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);
+/*! @brief Sets the maximize callback for the specified window.
+ *
+ * This function sets the maximization callback of the specified window, which
+ * is called when the window is maximized or restored.
+ *
+ * @param[in] window The window whose callback to set.
+ * @param[in] cbfun The new callback, or `NULL` to remove the currently set
+ * callback.
+ * @return The previously set callback, or `NULL` if no callback was set or the
+ * library had not been [initialized](@ref intro_init).
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref window_maximize
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup window
+ */
+GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun cbfun);
+
/*! @brief Sets the framebuffer resize callback for the specified window.
*
* This function sets the framebuffer resize callback of the specified window,
@@ -2729,9 +3444,12 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window
* [window refresh callback](@ref window_refresh) to redraw the contents of
* your window when necessary during such operations.
*
- * On some platforms, certain events are sent directly to the application
- * without going through the event queue, causing callbacks to be called
- * outside of a call to one of the event processing functions.
+ * Do not assume that callbacks you set will _only_ be called in response to
+ * event processing functions like this one. While it is necessary to poll for
+ * events, window systems that require GLFW to register callbacks of its own
+ * can pass events to GLFW in response to many window system function calls.
+ * GLFW will pass those events on to the application callbacks before
+ * returning.
*
* Event processing is not required for joystick input to work.
*
@@ -2743,8 +3461,8 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
- * @sa glfwWaitEvents
- * @sa glfwWaitEventsTimeout
+ * @sa @ref glfwWaitEvents
+ * @sa @ref glfwWaitEventsTimeout
*
* @since Added in version 1.0.
*
@@ -2771,8 +3489,12 @@ GLFWAPI void glfwPollEvents(void);
* [window refresh callback](@ref window_refresh) to redraw the contents of
* your window when necessary during such operations.
*
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
+ * Do not assume that callbacks you set will _only_ be called in response to
+ * event processing functions like this one. While it is necessary to poll for
+ * events, window systems that require GLFW to register callbacks of its own
+ * can pass events to GLFW in response to many window system function calls.
+ * GLFW will pass those events on to the application callbacks before
+ * returning.
*
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
@@ -2788,8 +3510,8 @@ GLFWAPI void glfwPollEvents(void);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEventsTimeout
+ * @sa @ref glfwPollEvents
+ * @sa @ref glfwWaitEventsTimeout
*
* @since Added in version 2.5.
*
@@ -2818,8 +3540,12 @@ GLFWAPI void glfwWaitEvents(void);
* [window refresh callback](@ref window_refresh) to redraw the contents of
* your window when necessary during such operations.
*
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
+ * Do not assume that callbacks you set will _only_ be called in response to
+ * event processing functions like this one. While it is necessary to poll for
+ * events, window systems that require GLFW to register callbacks of its own
+ * can pass events to GLFW in response to many window system function calls.
+ * GLFW will pass those events on to the application callbacks before
+ * returning.
*
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
@@ -2834,8 +3560,8 @@ GLFWAPI void glfwWaitEvents(void);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEvents
+ * @sa @ref glfwPollEvents
+ * @sa @ref glfwWaitEvents
*
* @since Added in version 3.2.
*
@@ -2846,7 +3572,7 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
/*! @brief Posts an empty event to the event queue.
*
* This function posts an empty event from the current thread to the event
- * queue, causing @ref glfwWaitEvents to return.
+ * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.
*
* If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading
@@ -2858,7 +3584,8 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
* @thread_safety This function may be called from any thread.
*
* @sa @ref events
- * @sa glfwWaitEvents
+ * @sa @ref glfwWaitEvents
+ * @sa @ref glfwWaitEventsTimeout
*
* @since Added in version 3.1.
*
@@ -2869,8 +3596,8 @@ GLFWAPI void glfwPostEmptyEvent(void);
/*! @brief Returns the value of an input option for the specified window.
*
* This function returns the value of an input option for the specified window.
- * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
+ * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS or
+ * @ref GLFW_STICKY_MOUSE_BUTTONS.
*
* @param[in] window The window to query.
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
@@ -2881,7 +3608,7 @@ GLFWAPI void glfwPostEmptyEvent(void);
*
* @thread_safety This function must only be called from the main thread.
*
- * @sa glfwSetInputMode
+ * @sa @ref glfwSetInputMode
*
* @since Added in version 3.0.
*
@@ -2892,8 +3619,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
/*! @brief Sets an input option for the specified window.
*
* This function sets an input mode option for the specified window. The mode
- * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
+ * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS or
+ * @ref GLFW_STICKY_MOUSE_BUTTONS.
*
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
* modes:
@@ -2929,7 +3656,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
*
* @thread_safety This function must only be called from the main thread.
*
- * @sa glfwGetInputMode
+ * @sa @ref glfwGetInputMode
*
* @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`.
*
@@ -2937,17 +3664,22 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
*/
GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
-/*! @brief Returns the localized name of the specified printable key.
+/*! @brief Returns the layout-specific name of the specified printable key.
*
- * This function returns the localized name of the specified printable key.
- * This is intended for displaying key bindings to the user.
+ * This function returns the name of the specified printable key, encoded as
+ * UTF-8. This is typically the character that key would produce without any
+ * modifier keys, intended for displaying key bindings to the user. For dead
+ * keys, it is typically the diacritic it would add to a character.
*
- * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise
- * the scancode is ignored. If a non-printable key or (if the key is
- * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is
- * specified, this function returns `NULL`.
+ * __Do not use this function__ for [text input](@ref input_char). You will
+ * break text input for many languages even if it happens to work for yours.
*
- * This behavior allows you to pass in the arguments passed to the
+ * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used to identify the key,
+ * otherwise the scancode is ignored. If you specify a non-printable key, or
+ * `GLFW_KEY_UNKNOWN` and a scancode that maps to a non-printable key, this
+ * function returns `NULL` but does not emit an error.
+ *
+ * This behavior allows you to always pass in the arguments in the
* [key callback](@ref input_key) without modification.
*
* The printable keys are:
@@ -2973,9 +3705,13 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
* - `GLFW_KEY_KP_ADD`
* - `GLFW_KEY_KP_EQUAL`
*
+ * Names for printable keys depend on keyboard layout, while names for
+ * non-printable keys are the same across layouts but depend on the application
+ * language and should be localized along with other user interface text.
+ *
* @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.
* @param[in] scancode The scancode of the key to query.
- * @return The localized name of the key, or `NULL`.
+ * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
@@ -2994,6 +3730,30 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
*/
GLFWAPI const char* glfwGetKeyName(int key, int scancode);
+/*! @brief Returns the platform-specific scancode of the specified key.
+ *
+ * This function returns the platform-specific scancode of the specified key.
+ *
+ * If the key is `GLFW_KEY_UNKNOWN` or does not exist on the keyboard this
+ * method will return `-1`.
+ *
+ * @param[in] key Any [named key](@ref keys).
+ * @return The platform-specific scancode for the key, or `-1` if an
+ * [error](@ref error_handling) occurred.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
+ *
+ * @thread_safety This function may be called from any thread.
+ *
+ * @sa @ref input_key
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI int glfwGetKeyScancode(int key);
+
/*! @brief Returns the last reported state of a keyboard key for the specified
* window.
*
@@ -3002,7 +3762,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode);
* `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
* the key callback.
*
- * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns
+ * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns
* `GLFW_PRESS` the first time you call it for a key that was pressed, even if
* that key has already been released.
*
@@ -3041,7 +3801,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* to the specified window. The returned state is one of `GLFW_PRESS` or
* `GLFW_RELEASE`.
*
- * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function
+ * If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function
* `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
* even if that mouse button has already been released.
*
@@ -3093,7 +3853,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_pos
- * @sa glfwSetCursorPos
+ * @sa @ref glfwSetCursorPos
*
* @since Added in version 3.0. Replaces `glfwGetMousePos`.
*
@@ -3127,10 +3887,13 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland This function will only work when the cursor mode is
+ * `GLFW_CURSOR_DISABLED`, otherwise it will do nothing.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_pos
- * @sa glfwGetCursorPos
+ * @sa @ref glfwGetCursorPos
*
* @since Added in version 3.0. Replaces `glfwSetMousePos`.
*
@@ -3145,8 +3908,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
* Any remaining cursors are destroyed by @ref glfwTerminate.
*
* The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
- * bits per channel. They are arranged canonically as packed sequential rows,
- * starting from the top-left corner.
+ * bits per channel with the red channel first. They are arranged canonically
+ * as packed sequential rows, starting from the top-left corner.
*
* The cursor hotspot is specified in pixels, relative to the upper-left corner
* of the cursor image. Like all other coordinate systems in GLFW, the X-axis
@@ -3164,13 +3927,11 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
* @pointer_lifetime The specified image data is copied before this function
* returns.
*
- * @reentrancy This function must not be called from a callback.
- *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_object
- * @sa glfwDestroyCursor
- * @sa glfwCreateStandardCursor
+ * @sa @ref glfwDestroyCursor
+ * @sa @ref glfwCreateStandardCursor
*
* @since Added in version 3.1.
*
@@ -3190,12 +3951,10 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
*
- * @reentrancy This function must not be called from a callback.
- *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_object
- * @sa glfwCreateCursor
+ * @sa @ref glfwCreateCursor
*
* @since Added in version 3.1.
*
@@ -3209,6 +3968,9 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
* glfwCreateCursor. Any remaining cursors will be destroyed by @ref
* glfwTerminate.
*
+ * If the specified cursor is current for any window, that window will be
+ * reverted to the default cursor. This does not affect the cursor mode.
+ *
* @param[in] cursor The cursor object to destroy.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@@ -3219,7 +3981,7 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_object
- * @sa glfwCreateCursor
+ * @sa @ref glfwCreateCursor
*
* @since Added in version 3.1.
*
@@ -3311,7 +4073,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
*
* The character callback behaves as system text input normally does and will
* not be called if modifier keys are held down that would prevent normal text
- * input on that platform, for example a Super (Command) key on OS X or Alt key
+ * input on that platform, for example a Super (Command) key on macOS or Alt key
* on Windows. There is a
* [character with modifiers callback](@ref glfwSetCharModsCallback) that
* receives these events.
@@ -3354,7 +4116,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
* callback.
* @return The previously set callback, or `NULL` if no callback was set or an
- * error occurred.
+ * [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
@@ -3492,6 +4254,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
+ * @remark @wayland File drop is currently unimplemented.
+ *
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref path_drop
@@ -3506,7 +4270,11 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
*
* This function returns whether the specified joystick is present.
*
- * @param[in] joy The [joystick](@ref joysticks) to query.
+ * There is no need to call this function before other functions that accept
+ * a joystick ID, as they all check for presence before performing any other
+ * work.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
@@ -3520,29 +4288,30 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
*
* @ingroup input
*/
-GLFWAPI int glfwJoystickPresent(int joy);
+GLFWAPI int glfwJoystickPresent(int jid);
/*! @brief Returns the values of all axes of the specified joystick.
*
* This function returns the values of all axes of the specified joystick.
* Each element in the array is a value between -1.0 and 1.0.
*
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
+ * If the specified joystick is not present this function will return `NULL`
+ * but will not generate an error. This can be used instead of first calling
+ * @ref glfwJoystickPresent.
*
- * @param[in] joy The [joystick](@ref joysticks) to query.
+ * @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of axis values in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of axis values, or `NULL` if the joystick is not present.
+ * array. This is set to zero if the joystick is not present or an error
+ * occurred.
+ * @return An array of axis values, or `NULL` if the joystick is not present or
+ * an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
+ * disconnected or the library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
@@ -3552,29 +4321,37 @@ GLFWAPI int glfwJoystickPresent(int joy);
*
* @ingroup input
*/
-GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
+GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
/*! @brief Returns the state of all buttons of the specified joystick.
*
* This function returns the state of all buttons of the specified joystick.
* Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
*
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
+ * For backward compatibility with earlier versions that did not have @ref
+ * glfwGetJoystickHats, the button array also includes all hats, each
+ * represented as four buttons. The hats are in the same order as returned by
+ * __glfwGetJoystickHats__ and are in the order _up_, _right_, _down_ and
+ * _left_. To disable these extra buttons, set the @ref
+ * GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization.
*
- * @param[in] joy The [joystick](@ref joysticks) to query.
+ * If the specified joystick is not present this function will return `NULL`
+ * but will not generate an error. This can be used instead of first calling
+ * @ref glfwJoystickPresent.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of button states in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of button states, or `NULL` if the joystick is not present.
+ * array. This is set to zero if the joystick is not present or an error
+ * occurred.
+ * @return An array of button states, or `NULL` if the joystick is not present
+ * or an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
+ * disconnected or the library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
@@ -3585,7 +4362,64 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
*
* @ingroup input
*/
-GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
+GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
+
+/*! @brief Returns the state of all hats of the specified joystick.
+ *
+ * This function returns the state of all hats of the specified joystick.
+ * Each element in the array is one of the following values:
+ *
+ * Name | Value
+ * --------------------- | --------------------------------
+ * `GLFW_HAT_CENTERED` | 0
+ * `GLFW_HAT_UP` | 1
+ * `GLFW_HAT_RIGHT` | 2
+ * `GLFW_HAT_DOWN` | 4
+ * `GLFW_HAT_LEFT` | 8
+ * `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
+ * `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
+ * `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
+ * `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`
+ *
+ * The diagonal directions are bitwise combinations of the primary (up, right,
+ * down and left) directions and you can test for these individually by ANDing
+ * it with the corresponding direction.
+ *
+ * @code
+ * if (hats[2] & GLFW_HAT_RIGHT)
+ * {
+ * // State of hat 2 could be right-up, right or right-down
+ * }
+ * @endcode
+ *
+ * If the specified joystick is not present this function will return `NULL`
+ * but will not generate an error. This can be used instead of first calling
+ * @ref glfwJoystickPresent.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
+ * @param[out] count Where to store the number of hat states in the returned
+ * array. This is set to zero if the joystick is not present or an error
+ * occurred.
+ * @return An array of hat states, or `NULL` if the joystick is not present
+ * or an [error](@ref error_handling) occurred.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
+ *
+ * @pointer_lifetime The returned array is allocated and freed by GLFW. You
+ * should not free it yourself. It is valid until the specified joystick is
+ * disconnected, this function is called again for that joystick or the library
+ * is terminated.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref joystick_hat
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
/*! @brief Returns the name of the specified joystick.
*
@@ -3593,21 +4427,20 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
* The returned string is allocated and freed by GLFW. You should not free it
* yourself.
*
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
+ * If the specified joystick is not present this function will return `NULL`
+ * but will not generate an error. This can be used instead of first calling
+ * @ref glfwJoystickPresent.
*
- * @param[in] joy The [joystick](@ref joysticks) to query.
+ * @param[in] jid The [joystick](@ref joysticks) to query.
* @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
- * is not present.
+ * is not present or an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
+ * disconnected or the library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
@@ -3617,7 +4450,76 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
*
* @ingroup input
*/
-GLFWAPI const char* glfwGetJoystickName(int joy);
+GLFWAPI const char* glfwGetJoystickName(int jid);
+
+/*! @brief Returns the SDL comaptible GUID of the specified joystick.
+ *
+ * This function returns the SDL compatible GUID, as a UTF-8 encoded
+ * hexadecimal string, of the specified joystick. The returned string is
+ * allocated and freed by GLFW. You should not free it yourself.
+ *
+ * The GUID is what connects a joystick to a gamepad mapping. A connected
+ * joystick will always have a GUID even if there is no gamepad mapping
+ * assigned to it.
+ *
+ * If the specified joystick is not present this function will return `NULL`
+ * but will not generate an error. This can be used instead of first calling
+ * @ref glfwJoystickPresent.
+ *
+ * The GUID uses the format introduced in SDL 2.0.5. This GUID tries to
+ * uniquely identify the make and model of a joystick but does not identify
+ * a specific unit, e.g. all wired Xbox 360 controllers will have the same
+ * GUID on that platform. The GUID for a unit may vary between platforms
+ * depending on what hardware information the platform specific APIs provide.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
+ * @return The UTF-8 encoded GUID of the joystick, or `NULL` if the joystick
+ * is not present or an [error](@ref error_handling) occurred.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
+ * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
+ *
+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
+ * should not free it yourself. It is valid until the specified joystick is
+ * disconnected or the library is terminated.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref gamepad
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI const char* glfwGetJoystickGUID(int jid);
+
+/*! @brief Returns whether the specified joystick has a gamepad mapping.
+ *
+ * This function returns whether the specified joystick is both present and has
+ * a gamepad mapping.
+ *
+ * If the specified joystick is present but does not have a gamepad mapping
+ * this function will return `GLFW_FALSE` but will not generate an error. Call
+ * @ref glfwJoystickPresent to check if a joystick is present regardless of
+ * whether it has a mapping.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
+ * @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
+ * or `GLFW_FALSE` otherwise.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_INVALID_ENUM.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref gamepad
+ * @sa @ref glfwGetGamepadState
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI int glfwJoystickIsGamepad(int jid);
/*! @brief Sets the joystick configuration callback.
*
@@ -3625,6 +4527,12 @@ GLFWAPI const char* glfwGetJoystickName(int joy);
* currently set callback. This is called when a joystick is connected to or
* disconnected from the system.
*
+ * For joystick connection and disconnection events to be delivered on all
+ * platforms, you need to call one of the [event processing](@ref events)
+ * functions. Joystick disconnection may also be detected and the callback
+ * called by joystick functions. The function will then return whatever it
+ * returns if the joystick is not present.
+ *
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
* callback.
* @return The previously set callback, or `NULL` if no callback was set or the
@@ -3642,6 +4550,106 @@ GLFWAPI const char* glfwGetJoystickName(int joy);
*/
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
+/*! @brief Adds the specified SDL_GameControllerDB gamepad mappings.
+ *
+ * This function parses the specified ASCII encoded string and updates the
+ * internal list with any gamepad mappings it finds. This string may
+ * contain either a single gamepad mapping or many mappings separated by
+ * newlines. The parser supports the full format of the `gamecontrollerdb.txt`
+ * source file including empty lines and comments.
+ *
+ * See @ref gamepad_mapping for a description of the format.
+ *
+ * If there is already a gamepad mapping for a given GUID in the internal list,
+ * it will be replaced by the one passed to this function. If the library is
+ * terminated and re-initialized the internal list will revert to the built-in
+ * default.
+ *
+ * @param[in] string The string containing the gamepad mappings.
+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
+ * [error](@ref error_handling) occurred.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_INVALID_VALUE.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref gamepad
+ * @sa @ref glfwJoystickIsGamepad
+ * @sa @ref glfwGetGamepadName
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI int glfwUpdateGamepadMappings(const char* string);
+
+/*! @brief Returns the human-readable gamepad name for the specified joystick.
+ *
+ * This function returns the human-readable name of the gamepad from the
+ * gamepad mapping assigned to the specified joystick.
+ *
+ * If the specified joystick is not present or does not have a gamepad mapping
+ * this function will return `NULL` but will not generate an error. Call
+ * @ref glfwJoystickPresent to check whether it is present regardless of
+ * whether it has a mapping.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
+ * @return The UTF-8 encoded name of the gamepad, or `NULL` if the
+ * joystick is not present, does not have a mapping or an
+ * [error](@ref error_handling) occurred.
+ *
+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
+ * should not free it yourself. It is valid until the specified joystick is
+ * disconnected, the gamepad mappings are updated or the library is terminated.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref gamepad
+ * @sa @ref glfwJoystickIsGamepad
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI const char* glfwGetGamepadName(int jid);
+
+/*! @brief Retrieves the state of the specified joystick remapped as a gamepad.
+ *
+ * This function retrives the state of the specified joystick remapped to
+ * an Xbox-like gamepad.
+ *
+ * If the specified joystick is not present or does not have a gamepad mapping
+ * this function will return `GLFW_FALSE` but will not generate an error. Call
+ * @ref glfwJoystickPresent to check whether it is present regardless of
+ * whether it has a mapping.
+ *
+ * The Guide button may not be available for input as it is often hooked by the
+ * system or the Steam client.
+ *
+ * Not all devices have all the buttons or axes provided by @ref
+ * GLFWgamepadstate. Unavailable buttons and axes will always report
+ * `GLFW_RELEASE` and 1.0 respectively.
+ *
+ * @param[in] jid The [joystick](@ref joysticks) to query.
+ * @param[out] state The gamepad input state of the joystick.
+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
+ * connected, it has no gamepad mapping or an [error](@ref error_handling)
+ * occurred.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_INVALID_ENUM.
+ *
+ * @sa @ref gamepad
+ * @sa @ref glfwUpdateGamepadMappings
+ * @sa @ref glfwJoystickIsGamepad
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup input
+ */
+GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
+
/*! @brief Sets the clipboard to the specified string.
*
* This function sets the system clipboard to the specified, UTF-8 encoded
@@ -3653,13 +4661,15 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland Clipboard is currently unimplemented.
+ *
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
- * @sa glfwGetClipboardString
+ * @sa @ref glfwGetClipboardString
*
* @since Added in version 3.0.
*
@@ -3681,6 +4691,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
+ * @remark @wayland Clipboard is currently unimplemented.
+ *
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref
* glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
@@ -3689,7 +4701,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
- * @sa glfwSetClipboardString
+ * @sa @ref glfwSetClipboardString
*
* @since Added in version 3.0.
*
@@ -3765,7 +4777,7 @@ GLFWAPI void glfwSetTime(double time);
* @thread_safety This function may be called from any thread.
*
* @sa @ref time
- * @sa glfwGetTimerFrequency
+ * @sa @ref glfwGetTimerFrequency
*
* @since Added in version 3.2.
*
@@ -3785,7 +4797,7 @@ GLFWAPI uint64_t glfwGetTimerValue(void);
* @thread_safety This function may be called from any thread.
*
* @sa @ref time
- * @sa glfwGetTimerValue
+ * @sa @ref glfwGetTimerValue
*
* @since Added in version 3.2.
*
@@ -3804,7 +4816,8 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
* By default, making a context non-current implicitly forces a pipeline flush.
* On machines that support `GL_KHR_context_flush_control`, you can control
* whether a context performs this flush by setting the
- * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.
+ * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint)
+ * hint.
*
* The specified window must have an OpenGL or OpenGL ES context. Specifying
* a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
@@ -3819,7 +4832,7 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void);
* @thread_safety This function may be called from any thread.
*
* @sa @ref context_current
- * @sa glfwGetCurrentContext
+ * @sa @ref glfwGetCurrentContext
*
* @since Added in version 3.0.
*
@@ -3840,7 +4853,7 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
* @thread_safety This function may be called from any thread.
*
* @sa @ref context_current
- * @sa glfwMakeContextCurrent
+ * @sa @ref glfwMakeContextCurrent
*
* @since Added in version 3.0.
*
@@ -3873,7 +4886,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
* @thread_safety This function may be called from any thread.
*
* @sa @ref buffer_swap
- * @sa glfwSwapInterval
+ * @sa @ref glfwSwapInterval
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
@@ -3921,7 +4934,7 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
* @thread_safety This function may be called from any thread.
*
* @sa @ref buffer_swap
- * @sa glfwSwapBuffers
+ * @sa @ref glfwSwapBuffers
*
* @since Added in version 1.0.
*
@@ -3959,7 +4972,7 @@ GLFWAPI void glfwSwapInterval(int interval);
* @thread_safety This function may be called from any thread.
*
* @sa @ref context_glext
- * @sa glfwGetProcAddress
+ * @sa @ref glfwGetProcAddress
*
* @since Added in version 1.0.
*
@@ -4001,7 +5014,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
* @thread_safety This function may be called from any thread.
*
* @sa @ref context_glext
- * @sa glfwExtensionSupported
+ * @sa @ref glfwExtensionSupported
*
* @since Added in version 1.0.
*
@@ -4009,19 +5022,21 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
*/
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
-/*! @brief Returns whether the Vulkan loader has been found.
+/*! @brief Returns whether the Vulkan loader and an ICD have been found.
*
- * This function returns whether the Vulkan loader has been found. This check
- * is performed by @ref glfwInit.
+ * This function returns whether the Vulkan loader and any minimally functional
+ * ICD have been found.
*
- * The availability of a Vulkan loader does not by itself guarantee that window
- * surface creation or even device creation is possible. Call @ref
- * glfwGetRequiredInstanceExtensions to check whether the extensions necessary
- * for Vulkan surface creation are available and @ref
- * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of
- * a physical device supports image presentation.
+ * The availability of a Vulkan loader and even an ICD does not by itself
+ * guarantee that surface creation or even instance creation is possible.
+ * For example, on Fermi systems Nvidia will install an ICD that provides no
+ * actual Vulkan support. Call @ref glfwGetRequiredInstanceExtensions to check
+ * whether the extensions necessary for Vulkan surface creation are available
+ * and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue
+ * family of a physical device supports image presentation.
*
- * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.
+ * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE`
+ * otherwise.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
@@ -4045,7 +5060,7 @@ GLFWAPI int glfwVulkanSupported(void);
*
* If Vulkan is not available on the machine, this function returns `NULL` and
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
+ * to check whether Vulkan is at least minimally available.
*
* If Vulkan is available but no set of extensions allowing window surface
* creation was found, this function returns `NULL`. You may still use Vulkan
@@ -4059,11 +5074,14 @@ GLFWAPI int glfwVulkanSupported(void);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_API_UNAVAILABLE.
*
- * @remarks Additional extensions may be required by future versions of GLFW.
+ * @remark Additional extensions may be required by future versions of GLFW.
* You should check if any extensions you wish to enable are already in the
* returned array, as it is an error to specify an extension more than once in
* the `VkInstanceCreateInfo` struct.
*
+ * @remark @macos This function currently only supports the
+ * `VK_MVK_macos_surface` extension from MoltenVK.
+ *
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
* should not free it yourself. It is guaranteed to be valid only until the
* library is terminated.
@@ -4071,7 +5089,7 @@ GLFWAPI int glfwVulkanSupported(void);
* @thread_safety This function may be called from any thread.
*
* @sa @ref vulkan_ext
- * @sa glfwCreateWindowSurface
+ * @sa @ref glfwCreateWindowSurface
*
* @since Added in version 3.2.
*
@@ -4095,7 +5113,7 @@ GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
*
* If Vulkan is not available on the machine, this function returns `NULL` and
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
+ * to check whether Vulkan is at least minimally available.
*
* This function is equivalent to calling `vkGetInstanceProcAddr` with
* a platform-specific query of the Vulkan loader as a fallback.
@@ -4131,7 +5149,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* not available on the machine, or if the specified instance was not created
* with the required extensions, this function returns `GLFW_FALSE` and
* generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available and @ref
+ * to check whether Vulkan is at least minimally available and @ref
* glfwGetRequiredInstanceExtensions to check what instance extensions are
* required.
*
@@ -4144,6 +5162,10 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
+ * @remark @macos This function currently always returns `GLFW_TRUE`, as the
+ * `VK_MVK_macos_surface` extension does not provide
+ * a `vkGetPhysicalDevice*PresentationSupport` type function.
+ *
* @thread_safety This function may be called from any thread. For
* synchronization details of Vulkan objects, see the Vulkan specification.
*
@@ -4159,10 +5181,10 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
*
* This function creates a Vulkan surface for the specified window.
*
- * If the Vulkan loader was not found at initialization, this function returns
- * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE
- * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was
- * found.
+ * If the Vulkan loader or at least one minimally functional ICD were not found,
+ * this function returns `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref
+ * GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported to check whether
+ * Vulkan is at least minimally available.
*
* If the required window surface creation instance extensions are not
* available or if the specified instance was not created with these extensions
@@ -4188,16 +5210,22 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
- * @remarks If an error occurs before the creation call is made, GLFW returns
+ * @remark If an error occurs before the creation call is made, GLFW returns
* the Vulkan error code most appropriate for the error. Appropriate use of
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
* eliminate almost all occurrences of these errors.
*
+ * @remark @macos This function currently only supports the
+ * `VK_MVK_macos_surface` extension from MoltenVK.
+ *
+ * @remark @macos This function creates and sets a `CAMetalLayer` instance for
+ * the window content view, which is required for MoltenVK to function.
+ *
* @thread_safety This function may be called from any thread. For
* synchronization details of Vulkan objects, see the Vulkan specification.
*
* @sa @ref vulkan_surface
- * @sa glfwGetRequiredInstanceExtensions
+ * @sa @ref glfwGetRequiredInstanceExtensions
*
* @since Added in version 3.2.
*
@@ -4224,6 +5252,13 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window
#undef GLFW_CALLBACK_DEFINED
#endif
+/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally
+ * defined by some gl.h variants (OpenBSD) so define it after if needed.
+ */
+#ifndef GLAPIENTRY
+ #define GLAPIENTRY APIENTRY
+#endif
+
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
diff --git a/src/external/include/GLFW/glfw3native.h b/src/external/glfw/include/GLFW/glfw3native.h
index 30e1a570..4372cb76 100644
--- a/src/external/include/GLFW/glfw3native.h
+++ b/src/external/glfw/include/GLFW/glfw3native.h
@@ -1,9 +1,9 @@
/*************************************************************************
- * GLFW 3.2 - www.glfw.org
+ * GLFW 3.3 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
+ * Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -45,12 +45,13 @@ extern "C" {
* more information.
*/
/*! @defgroup native Native access
+ * @brief Functions related to accessing native handles.
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
- * Before the inclusion of @ref glfw3native.h, you may define exactly one
+ * Before the inclusion of @ref glfw3native.h, you may define zero or more
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
@@ -68,6 +69,7 @@ extern "C" {
* * `GLFW_EXPOSE_NATIVE_NSGL`
* * `GLFW_EXPOSE_NATIVE_GLX`
* * `GLFW_EXPOSE_NATIVE_EGL`
+ * * `GLFW_EXPOSE_NATIVE_OSMESA`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
@@ -84,7 +86,10 @@ extern "C" {
// 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
- #undef APIENTRY
+ #if defined(GLFW_APIENTRY_DEFINED)
+ #undef APIENTRY
+ #undef GLFW_APIENTRY_DEFINED
+ #endif
#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
#include <ApplicationServices/ApplicationServices.h>
@@ -114,6 +119,9 @@ extern "C" {
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
+#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
+ #include <GL/osmesa.h>
+#endif
/*************************************************************************
@@ -284,6 +292,56 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
+
+/*! @brief Sets the current primary selection to the specified string.
+ *
+ * @param[in] string A UTF-8 encoded string.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_PLATFORM_ERROR.
+ *
+ * @pointer_lifetime The specified string is copied before this function
+ * returns.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref clipboard
+ * @sa glfwGetX11SelectionString
+ * @sa glfwSetClipboardString
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup native
+ */
+GLFWAPI void glfwSetX11SelectionString(const char* string);
+
+/*! @brief Returns the contents of the current primary selection as a string.
+ *
+ * If the selection is empty or if its contents cannot be converted, `NULL`
+ * is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
+ *
+ * @return The contents of the selection as a UTF-8 encoded string, or `NULL`
+ * if an [error](@ref error_handling) occurred.
+ *
+ * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
+ * GLFW_PLATFORM_ERROR.
+ *
+ * @pointer_lifetime The returned string is allocated and freed by GLFW. You
+ * should not free it yourself. It is valid until the next call to @ref
+ * glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
+ * library is terminated.
+ *
+ * @thread_safety This function must only be called from the main thread.
+ *
+ * @sa @ref clipboard
+ * @sa glfwSetX11SelectionString
+ * @sa glfwGetClipboardString
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup native
+ */
+GLFWAPI const char* glfwGetX11SelectionString(void);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
@@ -389,9 +447,9 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void);
*/
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
-/*! @brief Returns the `MirSurface*` of the specified window.
+/*! @brief Returns the `MirWindow*` of the specified window.
*
- * @return The `MirSurface*` of the specified window, or `NULL` if an
+ * @return The `MirWindow*` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
@@ -401,7 +459,7 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
*
* @ingroup native
*/
-GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
+GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
@@ -448,6 +506,64 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
#endif
+#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
+/*! @brief Retrieves the color buffer associated with the specified window.
+ *
+ * @param[in] window The window whose color buffer to retrieve.
+ * @param[out] width Where to store the width of the color buffer, or `NULL`.
+ * @param[out] height Where to store the height of the color buffer, or `NULL`.
+ * @param[out] format Where to store the OSMesa pixel format of the color
+ * buffer, or `NULL`.
+ * @param[out] buffer Where to store the address of the color buffer, or
+ * `NULL`.
+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
+ * [error](@ref error_handling) occurred.
+ *
+ * @thread_safety This function may be called from any thread. Access is not
+ * synchronized.
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup native
+ */
+GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
+
+/*! @brief Retrieves the depth buffer associated with the specified window.
+ *
+ * @param[in] window The window whose depth buffer to retrieve.
+ * @param[out] width Where to store the width of the depth buffer, or `NULL`.
+ * @param[out] height Where to store the height of the depth buffer, or `NULL`.
+ * @param[out] bytesPerValue Where to store the number of bytes per depth
+ * buffer element, or `NULL`.
+ * @param[out] buffer Where to store the address of the depth buffer, or
+ * `NULL`.
+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
+ * [error](@ref error_handling) occurred.
+ *
+ * @thread_safety This function may be called from any thread. Access is not
+ * synchronized.
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup native
+ */
+GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
+
+/*! @brief Returns the `OSMesaContext` of the specified window.
+ *
+ * @return The `OSMesaContext` of the specified window, or `NULL` if an
+ * [error](@ref error_handling) occurred.
+ *
+ * @thread_safety This function may be called from any thread. Access is not
+ * synchronized.
+ *
+ * @since Added in version 3.3.
+ *
+ * @ingroup native
+ */
+GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/src/external/glfw/src/cocoa_init.m b/src/external/glfw/src/cocoa_init.m
new file mode 100644
index 00000000..01a746ba
--- /dev/null
+++ b/src/external/glfw/src/cocoa_init.m
@@ -0,0 +1,374 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+#include <sys/param.h> // For MAXPATHLEN
+
+
+// Change to our application bundle's resources directory, if present
+//
+static void changeToResourcesDirectory(void)
+{
+ char resourcesPath[MAXPATHLEN];
+
+ CFBundleRef bundle = CFBundleGetMainBundle();
+ if (!bundle)
+ return;
+
+ CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
+
+ CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
+ if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo)
+ {
+ CFRelease(last);
+ CFRelease(resourcesURL);
+ return;
+ }
+
+ CFRelease(last);
+
+ if (!CFURLGetFileSystemRepresentation(resourcesURL,
+ true,
+ (UInt8*) resourcesPath,
+ MAXPATHLEN))
+ {
+ CFRelease(resourcesURL);
+ return;
+ }
+
+ CFRelease(resourcesURL);
+
+ chdir(resourcesPath);
+}
+
+// Create key code translation tables
+//
+static void createKeyTables(void)
+{
+ int scancode;
+
+ memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
+ memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
+
+ _glfw.ns.keycodes[0x1D] = GLFW_KEY_0;
+ _glfw.ns.keycodes[0x12] = GLFW_KEY_1;
+ _glfw.ns.keycodes[0x13] = GLFW_KEY_2;
+ _glfw.ns.keycodes[0x14] = GLFW_KEY_3;
+ _glfw.ns.keycodes[0x15] = GLFW_KEY_4;
+ _glfw.ns.keycodes[0x17] = GLFW_KEY_5;
+ _glfw.ns.keycodes[0x16] = GLFW_KEY_6;
+ _glfw.ns.keycodes[0x1A] = GLFW_KEY_7;
+ _glfw.ns.keycodes[0x1C] = GLFW_KEY_8;
+ _glfw.ns.keycodes[0x19] = GLFW_KEY_9;
+ _glfw.ns.keycodes[0x00] = GLFW_KEY_A;
+ _glfw.ns.keycodes[0x0B] = GLFW_KEY_B;
+ _glfw.ns.keycodes[0x08] = GLFW_KEY_C;
+ _glfw.ns.keycodes[0x02] = GLFW_KEY_D;
+ _glfw.ns.keycodes[0x0E] = GLFW_KEY_E;
+ _glfw.ns.keycodes[0x03] = GLFW_KEY_F;
+ _glfw.ns.keycodes[0x05] = GLFW_KEY_G;
+ _glfw.ns.keycodes[0x04] = GLFW_KEY_H;
+ _glfw.ns.keycodes[0x22] = GLFW_KEY_I;
+ _glfw.ns.keycodes[0x26] = GLFW_KEY_J;
+ _glfw.ns.keycodes[0x28] = GLFW_KEY_K;
+ _glfw.ns.keycodes[0x25] = GLFW_KEY_L;
+ _glfw.ns.keycodes[0x2E] = GLFW_KEY_M;
+ _glfw.ns.keycodes[0x2D] = GLFW_KEY_N;
+ _glfw.ns.keycodes[0x1F] = GLFW_KEY_O;
+ _glfw.ns.keycodes[0x23] = GLFW_KEY_P;
+ _glfw.ns.keycodes[0x0C] = GLFW_KEY_Q;
+ _glfw.ns.keycodes[0x0F] = GLFW_KEY_R;
+ _glfw.ns.keycodes[0x01] = GLFW_KEY_S;
+ _glfw.ns.keycodes[0x11] = GLFW_KEY_T;
+ _glfw.ns.keycodes[0x20] = GLFW_KEY_U;
+ _glfw.ns.keycodes[0x09] = GLFW_KEY_V;
+ _glfw.ns.keycodes[0x0D] = GLFW_KEY_W;
+ _glfw.ns.keycodes[0x07] = GLFW_KEY_X;
+ _glfw.ns.keycodes[0x10] = GLFW_KEY_Y;
+ _glfw.ns.keycodes[0x06] = GLFW_KEY_Z;
+
+ _glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE;
+ _glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH;
+ _glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA;
+ _glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL;
+ _glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT;
+ _glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET;
+ _glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS;
+ _glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD;
+ _glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET;
+ _glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON;
+ _glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH;
+ _glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1;
+
+ _glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE;
+ _glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK;
+ _glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE;
+ _glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN;
+ _glfw.ns.keycodes[0x77] = GLFW_KEY_END;
+ _glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER;
+ _glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE;
+ _glfw.ns.keycodes[0x7A] = GLFW_KEY_F1;
+ _glfw.ns.keycodes[0x78] = GLFW_KEY_F2;
+ _glfw.ns.keycodes[0x63] = GLFW_KEY_F3;
+ _glfw.ns.keycodes[0x76] = GLFW_KEY_F4;
+ _glfw.ns.keycodes[0x60] = GLFW_KEY_F5;
+ _glfw.ns.keycodes[0x61] = GLFW_KEY_F6;
+ _glfw.ns.keycodes[0x62] = GLFW_KEY_F7;
+ _glfw.ns.keycodes[0x64] = GLFW_KEY_F8;
+ _glfw.ns.keycodes[0x65] = GLFW_KEY_F9;
+ _glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
+ _glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
+ _glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
+ _glfw.ns.keycodes[0x69] = GLFW_KEY_F13;
+ _glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
+ _glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
+ _glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
+ _glfw.ns.keycodes[0x40] = GLFW_KEY_F17;
+ _glfw.ns.keycodes[0x4F] = GLFW_KEY_F18;
+ _glfw.ns.keycodes[0x50] = GLFW_KEY_F19;
+ _glfw.ns.keycodes[0x5A] = GLFW_KEY_F20;
+ _glfw.ns.keycodes[0x73] = GLFW_KEY_HOME;
+ _glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT;
+ _glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT;
+ _glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT;
+ _glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL;
+ _glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT;
+ _glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER;
+ _glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU;
+ _glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK;
+ _glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN;
+ _glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP;
+ _glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT;
+ _glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT;
+ _glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL;
+ _glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT;
+ _glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER;
+ _glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE;
+ _glfw.ns.keycodes[0x30] = GLFW_KEY_TAB;
+ _glfw.ns.keycodes[0x7E] = GLFW_KEY_UP;
+
+ _glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0;
+ _glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1;
+ _glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2;
+ _glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3;
+ _glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4;
+ _glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5;
+ _glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6;
+ _glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7;
+ _glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8;
+ _glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9;
+ _glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD;
+ _glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL;
+ _glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE;
+ _glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER;
+ _glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL;
+ _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
+ _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
+
+ for (scancode = 0; scancode < 256; scancode++)
+ {
+ // Store the reverse translation for faster key name lookup
+ if (_glfw.ns.keycodes[scancode] >= 0)
+ _glfw.ns.scancodes[_glfw.ns.keycodes[scancode]] = scancode;
+ }
+}
+
+// Retrieve Unicode data for the current keyboard layout
+//
+static GLFWbool updateUnicodeDataNS(void)
+{
+ if (_glfw.ns.inputSource)
+ {
+ CFRelease(_glfw.ns.inputSource);
+ _glfw.ns.inputSource = NULL;
+ _glfw.ns.unicodeData = nil;
+ }
+
+ _glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
+ if (!_glfw.ns.inputSource)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to retrieve keyboard layout input source");
+ return GLFW_FALSE;
+ }
+
+ _glfw.ns.unicodeData =
+ TISGetInputSourceProperty(_glfw.ns.inputSource,
+ kTISPropertyUnicodeKeyLayoutData);
+ if (!_glfw.ns.unicodeData)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to retrieve keyboard layout Unicode data");
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+// Load HIToolbox.framework and the TIS symbols we need from it
+//
+static GLFWbool initializeTIS(void)
+{
+ // This works only because Cocoa has already loaded it properly
+ _glfw.ns.tis.bundle =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
+ if (!_glfw.ns.tis.bundle)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to load HIToolbox.framework");
+ return GLFW_FALSE;
+ }
+
+ CFStringRef* kPropertyUnicodeKeyLayoutData =
+ CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
+ CFSTR("kTISPropertyUnicodeKeyLayoutData"));
+ _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
+ CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
+ CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
+ _glfw.ns.tis.GetInputSourceProperty =
+ CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
+ CFSTR("TISGetInputSourceProperty"));
+ _glfw.ns.tis.GetKbdType =
+ CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
+ CFSTR("LMGetKbdType"));
+
+ if (!kPropertyUnicodeKeyLayoutData ||
+ !TISCopyCurrentKeyboardLayoutInputSource ||
+ !TISGetInputSourceProperty ||
+ !LMGetKbdType)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to load TIS API symbols");
+ return GLFW_FALSE;
+ }
+
+ _glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
+ *kPropertyUnicodeKeyLayoutData;
+
+ return updateUnicodeDataNS();
+}
+
+@interface GLFWLayoutListener : NSObject
+@end
+
+@implementation GLFWLayoutListener
+
+- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
+{
+ updateUnicodeDataNS();
+}
+
+@end
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformInit(void)
+{
+ _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
+
+ if (_glfw.hints.init.ns.chdir)
+ changeToResourcesDirectory();
+
+ _glfw.ns.listener = [[GLFWLayoutListener alloc] init];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:_glfw.ns.listener
+ selector:@selector(selectedKeyboardInputSourceChanged:)
+ name:NSTextInputContextKeyboardSelectionDidChangeNotification
+ object:nil];
+
+ createKeyTables();
+
+ _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
+ if (!_glfw.ns.eventSource)
+ return GLFW_FALSE;
+
+ CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
+
+ if (!initializeTIS())
+ return GLFW_FALSE;
+
+ _glfwInitTimerNS();
+ _glfwInitJoysticksNS();
+
+ _glfwPollMonitorsNS();
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformTerminate(void)
+{
+ if (_glfw.ns.inputSource)
+ {
+ CFRelease(_glfw.ns.inputSource);
+ _glfw.ns.inputSource = NULL;
+ _glfw.ns.unicodeData = nil;
+ }
+
+ if (_glfw.ns.eventSource)
+ {
+ CFRelease(_glfw.ns.eventSource);
+ _glfw.ns.eventSource = NULL;
+ }
+
+ if (_glfw.ns.delegate)
+ {
+ [NSApp setDelegate:nil];
+ [_glfw.ns.delegate release];
+ _glfw.ns.delegate = nil;
+ }
+
+ if (_glfw.ns.listener)
+ {
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:_glfw.ns.listener
+ name:NSTextInputContextKeyboardSelectionDidChangeNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:_glfw.ns.listener];
+ [_glfw.ns.listener release];
+ _glfw.ns.listener = nil;
+ }
+
+ free(_glfw.ns.clipboardString);
+
+ _glfwTerminateNSGL();
+ _glfwTerminateJoysticksNS();
+
+ [_glfw.ns.autoreleasePool release];
+ _glfw.ns.autoreleasePool = nil;
+}
+
+const char* _glfwPlatformGetVersionString(void)
+{
+ return _GLFW_VERSION_NUMBER " Cocoa NSGL"
+#if defined(_GLFW_BUILD_DLL)
+ " dynamic"
+#endif
+ ;
+}
+
diff --git a/src/external/glfw/src/cocoa_joystick.h b/src/external/glfw/src/cocoa_joystick.h
new file mode 100644
index 00000000..d18d032a
--- /dev/null
+++ b/src/external/glfw/src/cocoa_joystick.h
@@ -0,0 +1,50 @@
+//========================================================================
+// GLFW 3.3 Cocoa - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDKeys.h>
+
+#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
+#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
+
+#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
+
+// Cocoa-specific per-joystick data
+//
+typedef struct _GLFWjoystickNS
+{
+ IOHIDDeviceRef device;
+ CFMutableArrayRef axes;
+ CFMutableArrayRef buttons;
+ CFMutableArrayRef hats;
+} _GLFWjoystickNS;
+
+
+void _glfwInitJoysticksNS(void);
+void _glfwTerminateJoysticksNS(void);
+
diff --git a/src/external/glfw/src/cocoa_joystick.m b/src/external/glfw/src/cocoa_joystick.m
new file mode 100644
index 00000000..3a5751ef
--- /dev/null
+++ b/src/external/glfw/src/cocoa_joystick.m
@@ -0,0 +1,462 @@
+//========================================================================
+// GLFW 3.3 Cocoa - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+// Copyright (c) 2012 Torsten Walluhn <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
+
+
+// Joystick element information
+//
+typedef struct _GLFWjoyelementNS
+{
+ IOHIDElementRef native;
+ uint32_t usage;
+ int index;
+ long minimum;
+ long maximum;
+
+} _GLFWjoyelementNS;
+
+
+// Returns the value of the specified element of the specified joystick
+//
+static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
+{
+ IOHIDValueRef valueRef;
+ long value = 0;
+
+ if (js->ns.device)
+ {
+ if (IOHIDDeviceGetValue(js->ns.device,
+ element->native,
+ &valueRef) == kIOReturnSuccess)
+ {
+ value = IOHIDValueGetIntegerValue(valueRef);
+ }
+ }
+
+ return value;
+}
+
+// Comparison function for matching the SDL element order
+//
+static CFComparisonResult compareElements(const void* fp,
+ const void* sp,
+ void* user)
+{
+ const _GLFWjoyelementNS* fe = fp;
+ const _GLFWjoyelementNS* se = sp;
+ if (fe->usage < se->usage)
+ return kCFCompareLessThan;
+ if (fe->usage > se->usage)
+ return kCFCompareGreaterThan;
+ if (fe->index < se->index)
+ return kCFCompareLessThan;
+ if (fe->index > se->index)
+ return kCFCompareGreaterThan;
+ return kCFCompareEqualTo;
+}
+
+// Removes the specified joystick
+//
+static void closeJoystick(_GLFWjoystick* js)
+{
+ int i;
+
+ if (!js->present)
+ return;
+
+ for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
+ free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
+ CFRelease(js->ns.axes);
+
+ for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
+ free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
+ CFRelease(js->ns.buttons);
+
+ for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
+ free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
+ CFRelease(js->ns.hats);
+
+ _glfwFreeJoystick(js);
+ _glfwInputJoystick(js, GLFW_DISCONNECTED);
+}
+
+// Callback for user-initiated joystick addition
+//
+static void matchCallback(void* context,
+ IOReturn result,
+ void* sender,
+ IOHIDDeviceRef device)
+{
+ int jid;
+ char name[256];
+ char guid[33];
+ CFIndex i;
+ CFTypeRef property;
+ uint32_t vendor = 0, product = 0, version = 0;
+ _GLFWjoystick* js;
+ CFMutableArrayRef axes, buttons, hats;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ if (_glfw.joysticks[jid].ns.device == device)
+ return;
+ }
+
+ axes = CFArrayCreateMutable(NULL, 0, NULL);
+ buttons = CFArrayCreateMutable(NULL, 0, NULL);
+ hats = CFArrayCreateMutable(NULL, 0, NULL);
+
+ property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
+ if (property)
+ {
+ CFStringGetCString(property,
+ name,
+ sizeof(name),
+ kCFStringEncodingUTF8);
+ }
+ else
+ strncpy(name, "Unknown", sizeof(name));
+
+ property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
+ if (property)
+ CFNumberGetValue(property, kCFNumberSInt32Type, &vendor);
+
+ property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
+ if (property)
+ CFNumberGetValue(property, kCFNumberSInt32Type, &product);
+
+ property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey));
+ if (property)
+ CFNumberGetValue(property, kCFNumberSInt32Type, &version);
+
+ // Generate a joystick GUID that matches the SDL 2.0.5+ one
+ if (vendor && product)
+ {
+ sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
+ (uint8_t) vendor, (uint8_t) (vendor >> 8),
+ (uint8_t) product, (uint8_t) (product >> 8),
+ (uint8_t) version, (uint8_t) (version >> 8));
+ }
+ else
+ {
+ sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
+ name[0], name[1], name[2], name[3],
+ name[4], name[5], name[6], name[7],
+ name[8], name[9], name[10]);
+ }
+
+ CFArrayRef elements =
+ IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
+
+ for (i = 0; i < CFArrayGetCount(elements); i++)
+ {
+ IOHIDElementRef native = (IOHIDElementRef)
+ CFArrayGetValueAtIndex(elements, i);
+ if (CFGetTypeID(native) != IOHIDElementGetTypeID())
+ continue;
+
+ const IOHIDElementType type = IOHIDElementGetType(native);
+ if ((type != kIOHIDElementTypeInput_Axis) &&
+ (type != kIOHIDElementTypeInput_Button) &&
+ (type != kIOHIDElementTypeInput_Misc))
+ {
+ continue;
+ }
+
+ CFMutableArrayRef target = NULL;
+
+ const uint32_t usage = IOHIDElementGetUsage(native);
+ const uint32_t page = IOHIDElementGetUsagePage(native);
+ if (page == kHIDPage_GenericDesktop)
+ {
+ switch (usage)
+ {
+ case kHIDUsage_GD_X:
+ case kHIDUsage_GD_Y:
+ case kHIDUsage_GD_Z:
+ case kHIDUsage_GD_Rx:
+ case kHIDUsage_GD_Ry:
+ case kHIDUsage_GD_Rz:
+ case kHIDUsage_GD_Slider:
+ case kHIDUsage_GD_Dial:
+ case kHIDUsage_GD_Wheel:
+ target = axes;
+ break;
+ case kHIDUsage_GD_Hatswitch:
+ target = hats;
+ break;
+ }
+ }
+ else if (page == kHIDPage_Button)
+ target = buttons;
+
+ if (target)
+ {
+ _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
+ element->native = native;
+ element->usage = usage;
+ element->index = (int) CFArrayGetCount(target);
+ element->minimum = IOHIDElementGetLogicalMin(native);
+ element->maximum = IOHIDElementGetLogicalMax(native);
+ CFArrayAppendValue(target, element);
+ }
+ }
+
+ CFRelease(elements);
+
+ CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
+ compareElements, NULL);
+ CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
+ compareElements, NULL);
+ CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
+ compareElements, NULL);
+
+ js = _glfwAllocJoystick(name, guid,
+ CFArrayGetCount(axes),
+ CFArrayGetCount(buttons),
+ CFArrayGetCount(hats));
+
+ js->ns.device = device;
+ js->ns.axes = axes;
+ js->ns.buttons = buttons;
+ js->ns.hats = hats;
+
+ _glfwInputJoystick(js, GLFW_CONNECTED);
+}
+
+// Callback for user-initiated joystick removal
+//
+static void removeCallback(void* context,
+ IOReturn result,
+ void* sender,
+ IOHIDDeviceRef device)
+{
+ int jid;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ if (_glfw.joysticks[jid].ns.device == device)
+ {
+ closeJoystick(_glfw.joysticks + jid);
+ break;
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize joystick interface
+//
+void _glfwInitJoysticksNS(void)
+{
+ CFMutableArrayRef matching;
+ const long usages[] =
+ {
+ kHIDUsage_GD_Joystick,
+ kHIDUsage_GD_GamePad,
+ kHIDUsage_GD_MultiAxisController
+ };
+
+ _glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
+ kIOHIDOptionsTypeNone);
+
+ matching = CFArrayCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeArrayCallBacks);
+ if (!matching)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
+ return;
+ }
+
+ for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
+ {
+ const long page = kHIDPage_GenericDesktop;
+
+ CFMutableDictionaryRef dict =
+ CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!dict)
+ continue;
+
+ CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberLongType,
+ &page);
+ CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberLongType,
+ &usages[i]);
+ if (pageRef && usageRef)
+ {
+ CFDictionarySetValue(dict,
+ CFSTR(kIOHIDDeviceUsagePageKey),
+ pageRef);
+ CFDictionarySetValue(dict,
+ CFSTR(kIOHIDDeviceUsageKey),
+ usageRef);
+ CFArrayAppendValue(matching, dict);
+ }
+
+ if (pageRef)
+ CFRelease(pageRef);
+ if (usageRef)
+ CFRelease(usageRef);
+
+ CFRelease(dict);
+ }
+
+ IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching);
+ CFRelease(matching);
+
+ IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
+ &matchCallback, NULL);
+ IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
+ &removeCallback, NULL);
+ IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
+ CFRunLoopGetMain(),
+ kCFRunLoopDefaultMode);
+ IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
+
+ // Execute the run loop once in order to register any initially-attached
+ // joysticks
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
+}
+
+// Close all opened joystick handles
+//
+void _glfwTerminateJoysticksNS(void)
+{
+ int jid;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ closeJoystick(_glfw.joysticks + jid);
+
+ CFRelease(_glfw.ns.hidManager);
+ _glfw.ns.hidManager = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
+{
+ if (mode & _GLFW_POLL_AXES)
+ {
+ CFIndex i;
+
+ for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
+ {
+ _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
+ CFArrayGetValueAtIndex(js->ns.axes, i);
+
+ const long raw = getElementValue(js, axis);
+ // Perform auto calibration
+ if (raw < axis->minimum)
+ axis->minimum = raw;
+ if (raw > axis->maximum)
+ axis->maximum = raw;
+
+ const long delta = axis->maximum - axis->minimum;
+ if (delta == 0)
+ _glfwInputJoystickAxis(js, i, 0.f);
+ else
+ {
+ const float value = (2.f * (raw - axis->minimum) / delta) - 1.f;
+ _glfwInputJoystickAxis(js, i, value);
+ }
+ }
+ }
+
+ if (mode & _GLFW_POLL_BUTTONS)
+ {
+ CFIndex i;
+
+ for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
+ {
+ _GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
+ CFArrayGetValueAtIndex(js->ns.buttons, i);
+ const char value = getElementValue(js, button) - button->minimum;
+ _glfwInputJoystickButton(js, i, value);
+ }
+
+ for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
+ {
+ const int states[9] =
+ {
+ GLFW_HAT_UP,
+ GLFW_HAT_RIGHT_UP,
+ GLFW_HAT_RIGHT,
+ GLFW_HAT_RIGHT_DOWN,
+ GLFW_HAT_DOWN,
+ GLFW_HAT_LEFT_DOWN,
+ GLFW_HAT_LEFT,
+ GLFW_HAT_LEFT_UP,
+ GLFW_HAT_CENTERED
+ };
+
+ _GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
+ CFArrayGetValueAtIndex(js->ns.hats, i);
+ long state = getElementValue(js, hat) - hat->minimum;
+ if (state < 0 || state > 8)
+ state = 8;
+
+ _glfwInputJoystickHat(js, i, states[state]);
+ }
+ }
+
+ return js->present;
+}
+
+void _glfwPlatformUpdateGamepadGUID(char* guid)
+{
+ if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
+ (strncmp(guid + 20, "000000000000", 12) == 0))
+ {
+ char original[33];
+ strcpy(original, guid);
+ sprintf(guid, "03000000%.4s0000%.4s000000000000",
+ original, original + 16);
+ }
+}
+
diff --git a/src/external/glfw/src/cocoa_monitor.m b/src/external/glfw/src/cocoa_monitor.m
new file mode 100644
index 00000000..6108342c
--- /dev/null
+++ b/src/external/glfw/src/cocoa_monitor.m
@@ -0,0 +1,531 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include <IOKit/graphics/IOGraphicsLib.h>
+#include <CoreVideo/CVBase.h>
+#include <CoreVideo/CVDisplayLink.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+
+// Get the name of the specified display, or NULL
+//
+static char* getDisplayName(CGDirectDisplayID displayID)
+{
+ io_iterator_t it;
+ io_service_t service;
+ CFDictionaryRef info;
+
+ if (IOServiceGetMatchingServices(kIOMasterPortDefault,
+ IOServiceMatching("IODisplayConnect"),
+ &it) != 0)
+ {
+ // This may happen if a desktop Mac is running headless
+ return NULL;
+ }
+
+ while ((service = IOIteratorNext(it)) != 0)
+ {
+ info = IODisplayCreateInfoDictionary(service,
+ kIODisplayOnlyPreferredName);
+
+ CFNumberRef vendorIDRef =
+ CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
+ CFNumberRef productIDRef =
+ CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
+ if (!vendorIDRef || !productIDRef)
+ {
+ CFRelease(info);
+ continue;
+ }
+
+ unsigned int vendorID, productID;
+ CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID);
+ CFNumberGetValue(productIDRef, kCFNumberIntType, &productID);
+
+ if (CGDisplayVendorNumber(displayID) == vendorID &&
+ CGDisplayModelNumber(displayID) == productID)
+ {
+ // Info dictionary is used and freed below
+ break;
+ }
+
+ CFRelease(info);
+ }
+
+ IOObjectRelease(it);
+
+ if (!service)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to find service port for display");
+ return NULL;
+ }
+
+ CFDictionaryRef names =
+ CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
+
+ CFStringRef nameRef;
+
+ if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
+ (const void**) &nameRef))
+ {
+ // This may happen if a desktop Mac is running headless
+ CFRelease(info);
+ return NULL;
+ }
+
+ const CFIndex size =
+ CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
+ kCFStringEncodingUTF8);
+ char* name = calloc(size + 1, 1);
+ CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
+
+ CFRelease(info);
+ return name;
+}
+
+// Check whether the display mode should be included in enumeration
+//
+static GLFWbool modeIsGood(CGDisplayModeRef mode)
+{
+ uint32_t flags = CGDisplayModeGetIOFlags(mode);
+
+ if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
+ return GLFW_FALSE;
+ if (flags & kDisplayModeInterlacedFlag)
+ return GLFW_FALSE;
+ if (flags & kDisplayModeStretchedFlag)
+ return GLFW_FALSE;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
+ CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
+ {
+ CFRelease(format);
+ return GLFW_FALSE;
+ }
+
+ CFRelease(format);
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
+ return GLFW_TRUE;
+}
+
+// Convert Core Graphics display mode to GLFW video mode
+//
+static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
+ CVDisplayLinkRef link)
+{
+ GLFWvidmode result;
+ result.width = (int) CGDisplayModeGetWidth(mode);
+ result.height = (int) CGDisplayModeGetHeight(mode);
+ result.refreshRate = (int) CGDisplayModeGetRefreshRate(mode);
+
+ if (result.refreshRate == 0)
+ {
+ 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
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
+ {
+ result.redBits = 5;
+ result.greenBits = 5;
+ result.blueBits = 5;
+ }
+ else
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
+ {
+ result.redBits = 8;
+ result.greenBits = 8;
+ result.blueBits = 8;
+ }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
+ CFRelease(format);
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
+ return result;
+}
+
+// Starts reservation for display fading
+//
+static CGDisplayFadeReservationToken beginFadeReservation(void)
+{
+ CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
+
+ if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
+ {
+ CGDisplayFade(token, 0.3,
+ kCGDisplayBlendNormal,
+ kCGDisplayBlendSolidColor,
+ 0.0, 0.0, 0.0,
+ TRUE);
+ }
+
+ return token;
+}
+
+// Ends reservation for display fading
+//
+static void endFadeReservation(CGDisplayFadeReservationToken token)
+{
+ if (token != kCGDisplayFadeReservationInvalidToken)
+ {
+ CGDisplayFade(token, 0.5,
+ kCGDisplayBlendSolidColor,
+ kCGDisplayBlendNormal,
+ 0.0, 0.0, 0.0,
+ FALSE);
+ CGReleaseDisplayFadeReservation(token);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Poll for changes in the set of connected monitors
+//
+void _glfwPollMonitorsNS(void)
+{
+ uint32_t i, j, displayCount, disconnectedCount;
+ CGDirectDisplayID* displays;
+ _GLFWmonitor** disconnected = NULL;
+
+ CGGetOnlineDisplayList(0, NULL, &displayCount);
+ displays = calloc(displayCount, sizeof(CGDirectDisplayID));
+ CGGetOnlineDisplayList(displayCount, displays, &displayCount);
+
+ for (i = 0; i < _glfw.monitorCount; i++)
+ _glfw.monitors[i]->ns.screen = nil;
+
+ disconnectedCount = _glfw.monitorCount;
+ if (disconnectedCount)
+ {
+ disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
+ memcpy(disconnected,
+ _glfw.monitors,
+ _glfw.monitorCount * sizeof(_GLFWmonitor*));
+ }
+
+ for (i = 0; i < displayCount; i++)
+ {
+ _GLFWmonitor* monitor;
+ const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
+
+ if (CGDisplayIsAsleep(displays[i]))
+ continue;
+
+ for (j = 0; j < disconnectedCount; j++)
+ {
+ // HACK: Compare unit numbers instead of display IDs to work around
+ // display replacement on machines with automatic graphics
+ // switching
+ if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
+ {
+ disconnected[j] = NULL;
+ break;
+ }
+ }
+
+ const CGSize size = CGDisplayScreenSize(displays[i]);
+ char* name = getDisplayName(displays[i]);
+ if (!name)
+ name = strdup("Unknown");
+
+ monitor = _glfwAllocMonitor(name, size.width, size.height);
+ monitor->ns.displayID = displays[i];
+ monitor->ns.unitNumber = unitNumber;
+
+ free(name);
+
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
+ }
+
+ for (i = 0; i < disconnectedCount; i++)
+ {
+ if (disconnected[i])
+ _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
+ }
+
+ free(disconnected);
+ free(displays);
+}
+
+// Change the current video mode
+//
+GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
+{
+ CFArrayRef modes;
+ CFIndex count, i;
+ CVDisplayLinkRef link;
+ CGDisplayModeRef native = NULL;
+ GLFWvidmode current;
+ const GLFWvidmode* best;
+
+ best = _glfwChooseVideoMode(monitor, desired);
+ _glfwPlatformGetVideoMode(monitor, &current);
+ if (_glfwCompareVideoModes(&current, best) == 0)
+ return GLFW_TRUE;
+
+ CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
+
+ modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
+ count = CFArrayGetCount(modes);
+
+ for (i = 0; i < count; i++)
+ {
+ CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+ if (!modeIsGood(dm))
+ continue;
+
+ const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
+ if (_glfwCompareVideoModes(best, &mode) == 0)
+ {
+ native = dm;
+ break;
+ }
+ }
+
+ if (native)
+ {
+ if (monitor->ns.previousMode == NULL)
+ monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
+
+ CGDisplayFadeReservationToken token = beginFadeReservation();
+ CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL);
+ endFadeReservation(token);
+ }
+
+ CFRelease(modes);
+ CVDisplayLinkRelease(link);
+
+ if (!native)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Monitor mode list changed");
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+// Restore the previously saved (original) video mode
+//
+void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
+{
+ if (monitor->ns.previousMode)
+ {
+ CGDisplayFadeReservationToken token = beginFadeReservation();
+ CGDisplaySetDisplayMode(monitor->ns.displayID,
+ monitor->ns.previousMode, NULL);
+ endFadeReservation(token);
+
+ CGDisplayModeRelease(monitor->ns.previousMode);
+ monitor->ns.previousMode = NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
+{
+ const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
+
+ if (xpos)
+ *xpos = (int) bounds.origin.x;
+ if (ypos)
+ *ypos = (int) bounds.origin.y;
+}
+
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
+ float* xscale, float* yscale)
+{
+ if (!monitor->ns.screen)
+ {
+ NSUInteger i;
+ NSArray* screens = [NSScreen screens];
+
+ for (i = 0; i < [screens count]; i++)
+ {
+ NSScreen* screen = [screens objectAtIndex:i];
+ NSNumber* displayID =
+ [[screen deviceDescription] objectForKey:@"NSScreenNumber"];
+
+ // 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;
+ break;
+ }
+ }
+
+ if (i == [screens count])
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to find a screen for monitor");
+ return;
+ }
+ }
+
+ const NSRect points = [monitor->ns.screen frame];
+ const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
+
+ if (xscale)
+ *xscale = (float) (pixels.size.width / points.size.width);
+ if (yscale)
+ *yscale = (float) (pixels.size.height / points.size.height);
+}
+
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
+{
+ CFArrayRef modes;
+ CFIndex found, i, j;
+ GLFWvidmode* result;
+ CVDisplayLinkRef link;
+
+ *count = 0;
+
+ CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
+
+ modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
+ found = CFArrayGetCount(modes);
+ result = calloc(found, sizeof(GLFWvidmode));
+
+ for (i = 0; i < found; i++)
+ {
+ CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+ if (!modeIsGood(dm))
+ continue;
+
+ const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
+
+ for (j = 0; j < *count; j++)
+ {
+ if (_glfwCompareVideoModes(result + j, &mode) == 0)
+ break;
+ }
+
+ // Skip duplicate modes
+ if (i < *count)
+ continue;
+
+ (*count)++;
+ result[*count - 1] = mode;
+ }
+
+ CFRelease(modes);
+ CVDisplayLinkRelease(link);
+ return result;
+}
+
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
+{
+ CGDisplayModeRef displayMode;
+ CVDisplayLinkRef link;
+
+ CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
+
+ displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
+ *mode = vidmodeFromCGDisplayMode(displayMode, link);
+ CGDisplayModeRelease(displayMode);
+
+ CVDisplayLinkRelease(link);
+}
+
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
+{
+ uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
+ CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
+
+ CGGetDisplayTransferByTable(monitor->ns.displayID,
+ size,
+ values,
+ values + size,
+ values + size * 2,
+ &size);
+
+ _glfwAllocGammaArrays(ramp, size);
+
+ for (i = 0; i < size; i++)
+ {
+ ramp->red[i] = (unsigned short) (values[i] * 65535);
+ ramp->green[i] = (unsigned short) (values[i + size] * 65535);
+ ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
+ }
+
+ free(values);
+}
+
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
+{
+ int i;
+ CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
+
+ for (i = 0; i < ramp->size; i++)
+ {
+ values[i] = ramp->red[i] / 65535.f;
+ values[i + ramp->size] = ramp->green[i] / 65535.f;
+ values[i + ramp->size * 2] = ramp->blue[i] / 65535.f;
+ }
+
+ CGSetDisplayTransferByTable(monitor->ns.displayID,
+ ramp->size,
+ values,
+ values + ramp->size,
+ values + ramp->size * 2);
+
+ free(values);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
+ return monitor->ns.displayID;
+}
+
diff --git a/src/external/glfw/src/cocoa_platform.h b/src/external/glfw/src/cocoa_platform.h
new file mode 100644
index 00000000..61d0ee91
--- /dev/null
+++ b/src/external/glfw/src/cocoa_platform.h
@@ -0,0 +1,164 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <stdint.h>
+#include <dlfcn.h>
+
+#if defined(__OBJC__)
+#import <Carbon/Carbon.h>
+#import <Cocoa/Cocoa.h>
+#else
+#include <Carbon/Carbon.h>
+#include <ApplicationServices/ApplicationServices.h>
+typedef void* id;
+#endif
+
+typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
+
+typedef struct VkMacOSSurfaceCreateInfoMVK
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkMacOSSurfaceCreateFlagsMVK flags;
+ const void* pView;
+} VkMacOSSurfaceCreateInfoMVK;
+
+typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
+
+#include "posix_thread.h"
+#include "cocoa_joystick.h"
+#include "nsgl_context.h"
+#include "egl_context.h"
+#include "osmesa_context.h"
+
+#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
+#define _glfw_dlclose(handle) dlclose(handle)
+#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
+#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
+typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
+#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource
+typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef);
+#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty
+typedef UInt8 (*PFN_LMGetKbdType)(void);
+#define LMGetKbdType _glfw.ns.tis.GetKbdType
+
+
+// Cocoa-specific per-window data
+//
+typedef struct _GLFWwindowNS
+{
+ id object;
+ id delegate;
+ id view;
+ id layer;
+
+ GLFWbool maximized;
+
+ // The total sum of the distances the cursor has been warped
+ // since the last cursor motion event was processed
+ // This is kept to counteract Cocoa doing the same internally
+ double cursorWarpDeltaX, cursorWarpDeltaY;
+
+} _GLFWwindowNS;
+
+// Cocoa-specific global data
+//
+typedef struct _GLFWlibraryNS
+{
+ CGEventSourceRef eventSource;
+ id delegate;
+ id autoreleasePool;
+ GLFWbool cursorHidden;
+ TISInputSourceRef inputSource;
+ IOHIDManagerRef hidManager;
+ id unicodeData;
+ id listener;
+
+ char keyName[64];
+ short int keycodes[256];
+ short int scancodes[GLFW_KEY_LAST + 1];
+ char* clipboardString;
+ CGPoint cascadePoint;
+ // Where to place the cursor when re-enabled
+ double restoreCursorPosX, restoreCursorPosY;
+ // The window whose disabled cursor mode is active
+ _GLFWwindow* disabledCursorWindow;
+
+ struct {
+ CFBundleRef bundle;
+ PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
+ PFN_TISGetInputSourceProperty GetInputSourceProperty;
+ PFN_LMGetKbdType GetKbdType;
+ CFStringRef kPropertyUnicodeKeyLayoutData;
+ } tis;
+
+} _GLFWlibraryNS;
+
+// Cocoa-specific per-monitor data
+//
+typedef struct _GLFWmonitorNS
+{
+ CGDirectDisplayID displayID;
+ CGDisplayModeRef previousMode;
+ uint32_t unitNumber;
+ id screen;
+
+} _GLFWmonitorNS;
+
+// Cocoa-specific per-cursor data
+//
+typedef struct _GLFWcursorNS
+{
+ id object;
+
+} _GLFWcursorNS;
+
+// Cocoa-specific global timer data
+//
+typedef struct _GLFWtimerNS
+{
+ uint64_t frequency;
+
+} _GLFWtimerNS;
+
+
+void _glfwInitTimerNS(void);
+
+void _glfwPollMonitorsNS(void);
+GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
+void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
+
diff --git a/src/external/glfw/src/cocoa_time.c b/src/external/glfw/src/cocoa_time.c
new file mode 100644
index 00000000..3b270351
--- /dev/null
+++ b/src/external/glfw/src/cocoa_time.c
@@ -0,0 +1,60 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <mach/mach_time.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialise timer
+//
+void _glfwInitTimerNS(void)
+{
+ mach_timebase_info_data_t info;
+ mach_timebase_info(&info);
+
+ _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+uint64_t _glfwPlatformGetTimerValue(void)
+{
+ return mach_absolute_time();
+}
+
+uint64_t _glfwPlatformGetTimerFrequency(void)
+{
+ return _glfw.timer.ns.frequency;
+}
+
diff --git a/src/external/glfw/src/cocoa_window.m b/src/external/glfw/src/cocoa_window.m
new file mode 100644
index 00000000..1ee85bc6
--- /dev/null
+++ b/src/external/glfw/src/cocoa_window.m
@@ -0,0 +1,1863 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <float.h>
+#include <string.h>
+
+// Needed for _NSGetProgname
+#include <crt_externs.h>
+
+// HACK: The 10.12 SDK adds new symbols and immediately deprecates the old ones
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
+ #define NSWindowStyleMaskBorderless NSBorderlessWindowMask
+ #define NSWindowStyleMaskClosable NSClosableWindowMask
+ #define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
+ #define NSWindowStyleMaskResizable NSResizableWindowMask
+ #define NSWindowStyleMaskTitled NSTitledWindowMask
+ #define NSEventModifierFlagCommand NSCommandKeyMask
+ #define NSEventModifierFlagControl NSControlKeyMask
+ #define NSEventModifierFlagOption NSAlternateKeyMask
+ #define NSEventModifierFlagShift NSShiftKeyMask
+ #define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
+ #define NSEventMaskAny NSAnyEventMask
+ #define NSEventTypeApplicationDefined NSApplicationDefined
+ #define NSEventTypeKeyUp NSKeyUp
+#endif
+
+
+// Returns the style mask corresponding to the window settings
+//
+static NSUInteger getStyleMask(_GLFWwindow* window)
+{
+ NSUInteger styleMask = 0;
+
+ if (window->monitor || !window->decorated)
+ styleMask |= NSWindowStyleMaskBorderless;
+ else
+ {
+ styleMask |= NSWindowStyleMaskTitled |
+ NSWindowStyleMaskClosable |
+ NSWindowStyleMaskMiniaturizable;
+
+ if (window->resizable)
+ styleMask |= NSWindowStyleMaskResizable;
+ }
+
+ return styleMask;
+}
+
+// Center the cursor in the view of the window
+//
+static void centerCursor(_GLFWwindow *window)
+{
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
+}
+
+// Returns whether the cursor is in the client area of the specified window
+//
+static GLFWbool cursorInClientArea(_GLFWwindow* window)
+{
+ const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
+ return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
+}
+
+// Hides the cursor if not already hidden
+//
+static void hideCursor(_GLFWwindow* window)
+{
+ if (!_glfw.ns.cursorHidden)
+ {
+ [NSCursor hide];
+ _glfw.ns.cursorHidden = GLFW_TRUE;
+ }
+}
+
+// Shows the cursor if not already shown
+//
+static void showCursor(_GLFWwindow* window)
+{
+ if (_glfw.ns.cursorHidden)
+ {
+ [NSCursor unhide];
+ _glfw.ns.cursorHidden = GLFW_FALSE;
+ }
+}
+
+// Updates the cursor image according to its cursor mode
+//
+static void updateCursorImage(_GLFWwindow* window)
+{
+ if (window->cursorMode == GLFW_CURSOR_NORMAL)
+ {
+ showCursor(window);
+
+ if (window->cursor)
+ [(NSCursor*) window->cursor->ns.object set];
+ else
+ [[NSCursor arrowCursor] set];
+ }
+ else
+ hideCursor(window);
+}
+
+// Transforms the specified y-coordinate between the CG display and NS screen
+// coordinate systems
+//
+static float transformY(float y)
+{
+ return CGDisplayBounds(CGMainDisplayID()).size.height - y;
+}
+
+// Make the specified window and its video mode active on its monitor
+//
+static GLFWbool acquireMonitor(_GLFWwindow* window)
+{
+ const GLFWbool status = _glfwSetVideoModeNS(window->monitor, &window->videoMode);
+ const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);
+ const NSRect frame = NSMakeRect(bounds.origin.x,
+ transformY(bounds.origin.y + bounds.size.height),
+ bounds.size.width,
+ bounds.size.height);
+
+ [window->ns.object setFrame:frame display:YES];
+
+ _glfwInputMonitorWindow(window->monitor, window);
+ return status;
+}
+
+// Remove the window and restore the original video mode
+//
+static void releaseMonitor(_GLFWwindow* window)
+{
+ if (window->monitor->window != window)
+ return;
+
+ _glfwInputMonitorWindow(window->monitor, NULL);
+ _glfwRestoreVideoModeNS(window->monitor);
+}
+
+// Translates macOS key modifiers into GLFW ones
+//
+static int translateFlags(NSUInteger flags)
+{
+ int mods = 0;
+
+ if (flags & NSEventModifierFlagShift)
+ mods |= GLFW_MOD_SHIFT;
+ if (flags & NSEventModifierFlagControl)
+ mods |= GLFW_MOD_CONTROL;
+ if (flags & NSEventModifierFlagOption)
+ mods |= GLFW_MOD_ALT;
+ if (flags & NSEventModifierFlagCommand)
+ mods |= GLFW_MOD_SUPER;
+
+ return mods;
+}
+
+// Translates a macOS keycode to a GLFW keycode
+//
+static int translateKey(unsigned int key)
+{
+ if (key >= sizeof(_glfw.ns.keycodes) / sizeof(_glfw.ns.keycodes[0]))
+ return GLFW_KEY_UNKNOWN;
+
+ return _glfw.ns.keycodes[key];
+}
+
+// Translate a GLFW keycode to a Cocoa modifier flag
+//
+static NSUInteger translateKeyToModifierFlag(int key)
+{
+ switch (key)
+ {
+ case GLFW_KEY_LEFT_SHIFT:
+ case GLFW_KEY_RIGHT_SHIFT:
+ return NSEventModifierFlagShift;
+ case GLFW_KEY_LEFT_CONTROL:
+ case GLFW_KEY_RIGHT_CONTROL:
+ return NSEventModifierFlagControl;
+ case GLFW_KEY_LEFT_ALT:
+ case GLFW_KEY_RIGHT_ALT:
+ return NSEventModifierFlagOption;
+ case GLFW_KEY_LEFT_SUPER:
+ case GLFW_KEY_RIGHT_SUPER:
+ return NSEventModifierFlagCommand;
+ }
+
+ return 0;
+}
+
+// Defines a constant for empty ranges in NSTextInputClient
+//
+static const NSRange kEmptyRange = { NSNotFound, 0 };
+
+
+//------------------------------------------------------------------------
+// Delegate for window related notifications
+//------------------------------------------------------------------------
+
+@interface GLFWWindowDelegate : NSObject
+{
+ _GLFWwindow* window;
+}
+
+- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
+
+@end
+
+@implementation GLFWWindowDelegate
+
+- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
+{
+ self = [super init];
+ if (self != nil)
+ window = initWindow;
+
+ return self;
+}
+
+- (BOOL)windowShouldClose:(id)sender
+{
+ _glfwInputWindowCloseRequest(window);
+ return NO;
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+ if (window->context.client != GLFW_NO_API)
+ [window->context.nsgl.object update];
+
+ if (_glfw.ns.disabledCursorWindow == window)
+ centerCursor(window);
+
+ const int maximized = [window->ns.object isZoomed];
+ if (window->ns.maximized != maximized)
+ {
+ window->ns.maximized = maximized;
+ _glfwInputWindowMaximize(window, maximized);
+ }
+
+ const NSRect contentRect = [window->ns.view frame];
+ const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
+
+ _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
+ _glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height);
+}
+
+- (void)windowDidMove:(NSNotification *)notification
+{
+ if (window->context.client != GLFW_NO_API)
+ [window->context.nsgl.object update];
+
+ if (_glfw.ns.disabledCursorWindow == window)
+ centerCursor(window);
+
+ int x, y;
+ _glfwPlatformGetWindowPos(window, &x, &y);
+ _glfwInputWindowPos(window, x, y);
+}
+
+- (void)windowDidMiniaturize:(NSNotification *)notification
+{
+ if (window->monitor)
+ releaseMonitor(window);
+
+ _glfwInputWindowIconify(window, GLFW_TRUE);
+}
+
+- (void)windowDidDeminiaturize:(NSNotification *)notification
+{
+ if (window->monitor)
+ acquireMonitor(window);
+
+ _glfwInputWindowIconify(window, GLFW_FALSE);
+}
+
+- (void)windowDidBecomeKey:(NSNotification *)notification
+{
+ if (_glfw.ns.disabledCursorWindow == window)
+ centerCursor(window);
+
+ _glfwInputWindowFocus(window, GLFW_TRUE);
+ _glfwPlatformSetCursorMode(window, window->cursorMode);
+}
+
+- (void)windowDidResignKey:(NSNotification *)notification
+{
+ if (window->monitor && window->autoIconify)
+ _glfwPlatformIconifyWindow(window);
+
+ _glfwInputWindowFocus(window, GLFW_FALSE);
+}
+
+@end
+
+
+//------------------------------------------------------------------------
+// Delegate for application related notifications
+//------------------------------------------------------------------------
+
+@interface GLFWApplicationDelegate : NSObject
+@end
+
+@implementation GLFWApplicationDelegate
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+ _GLFWwindow* window;
+
+ for (window = _glfw.windowListHead; window; window = window->next)
+ _glfwInputWindowCloseRequest(window);
+
+ return NSTerminateCancel;
+}
+
+- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
+{
+ _GLFWwindow* window;
+
+ for (window = _glfw.windowListHead; window; window = window->next)
+ {
+ if (window->context.client != GLFW_NO_API)
+ [window->context.nsgl.object update];
+ }
+
+ _glfwPollMonitorsNS();
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+ [NSApp stop:nil];
+
+ _glfwPlatformPostEmptyEvent();
+}
+
+- (void)applicationDidHide:(NSNotification *)notification
+{
+ int i;
+
+ for (i = 0; i < _glfw.monitorCount; i++)
+ _glfwRestoreVideoModeNS(_glfw.monitors[i]);
+}
+
+@end
+
+
+//------------------------------------------------------------------------
+// Content view class for the GLFW window
+//------------------------------------------------------------------------
+
+@interface GLFWContentView : NSView <NSTextInputClient>
+{
+ _GLFWwindow* window;
+ NSTrackingArea* trackingArea;
+ NSMutableAttributedString* markedText;
+}
+
+- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
+
+@end
+
+@implementation GLFWContentView
+
+- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
+{
+ self = [super init];
+ if (self != nil)
+ {
+ window = initWindow;
+ trackingArea = nil;
+ markedText = [[NSMutableAttributedString alloc] init];
+
+ [self updateTrackingAreas];
+ [self registerForDraggedTypes:[NSArray arrayWithObjects:
+ NSFilenamesPboardType, nil]];
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [trackingArea release];
+ [markedText release];
+ [super dealloc];
+}
+
+- (BOOL)isOpaque
+{
+ return [window->ns.object isOpaque];
+}
+
+- (BOOL)canBecomeKeyView
+{
+ return YES;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
+- (BOOL)wantsUpdateLayer
+{
+ return YES;
+}
+
+- (id)makeBackingLayer
+{
+ if (window->ns.layer)
+ return window->ns.layer;
+
+ return [super makeBackingLayer];
+}
+
+- (void)cursorUpdate:(NSEvent *)event
+{
+ updateCursorImage(window);
+}
+
+- (void)mouseDown:(NSEvent *)event
+{
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_LEFT,
+ GLFW_PRESS,
+ translateFlags([event modifierFlags]));
+}
+
+- (void)mouseDragged:(NSEvent *)event
+{
+ [self mouseMoved:event];
+}
+
+- (void)mouseUp:(NSEvent *)event
+{
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_LEFT,
+ GLFW_RELEASE,
+ translateFlags([event modifierFlags]));
+}
+
+- (void)mouseMoved:(NSEvent *)event
+{
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ {
+ const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;
+ const double dy = [event deltaY] - window->ns.cursorWarpDeltaY;
+
+ _glfwInputCursorPos(window,
+ window->virtualCursorPosX + dx,
+ window->virtualCursorPosY + dy);
+ }
+ else
+ {
+ const NSRect contentRect = [window->ns.view frame];
+ const NSPoint pos = [event locationInWindow];
+
+ _glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);
+ }
+
+ window->ns.cursorWarpDeltaX = 0;
+ window->ns.cursorWarpDeltaY = 0;
+}
+
+- (void)rightMouseDown:(NSEvent *)event
+{
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_RIGHT,
+ GLFW_PRESS,
+ translateFlags([event modifierFlags]));
+}
+
+- (void)rightMouseDragged:(NSEvent *)event
+{
+ [self mouseMoved:event];
+}
+
+- (void)rightMouseUp:(NSEvent *)event
+{
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_RIGHT,
+ GLFW_RELEASE,
+ translateFlags([event modifierFlags]));
+}
+
+- (void)otherMouseDown:(NSEvent *)event
+{
+ _glfwInputMouseClick(window,
+ (int) [event buttonNumber],
+ GLFW_PRESS,
+ translateFlags([event modifierFlags]));
+}
+
+- (void)otherMouseDragged:(NSEvent *)event
+{
+ [self mouseMoved:event];
+}
+
+- (void)otherMouseUp:(NSEvent *)event
+{
+ _glfwInputMouseClick(window,
+ (int) [event buttonNumber],
+ GLFW_RELEASE,
+ translateFlags([event modifierFlags]));
+}
+
+- (void)mouseExited:(NSEvent *)event
+{
+ if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ showCursor(window);
+
+ _glfwInputCursorEnter(window, GLFW_FALSE);
+}
+
+- (void)mouseEntered:(NSEvent *)event
+{
+ if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ hideCursor(window);
+
+ _glfwInputCursorEnter(window, GLFW_TRUE);
+}
+
+- (void)viewDidChangeBackingProperties
+{
+ const NSRect contentRect = [window->ns.view frame];
+ const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
+
+ _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ _glfwInputWindowDamage(window);
+}
+
+- (void)updateTrackingAreas
+{
+ if (trackingArea != nil)
+ {
+ [self removeTrackingArea:trackingArea];
+ [trackingArea release];
+ }
+
+ const NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited |
+ NSTrackingActiveInKeyWindow |
+ NSTrackingEnabledDuringMouseDrag |
+ NSTrackingCursorUpdate |
+ NSTrackingInVisibleRect |
+ NSTrackingAssumeInside;
+
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:options
+ owner:self
+ userInfo:nil];
+
+ [self addTrackingArea:trackingArea];
+ [super updateTrackingAreas];
+}
+
+- (void)keyDown:(NSEvent *)event
+{
+ const int key = translateKey([event keyCode]);
+ const int mods = translateFlags([event modifierFlags]);
+
+ _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
+
+ [self interpretKeyEvents:[NSArray arrayWithObject:event]];
+}
+
+- (void)flagsChanged:(NSEvent *)event
+{
+ int action;
+ const unsigned int modifierFlags =
+ [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
+ const int key = translateKey([event keyCode]);
+ const int mods = translateFlags(modifierFlags);
+ const NSUInteger keyFlag = translateKeyToModifierFlag(key);
+
+ if (keyFlag & modifierFlags)
+ {
+ if (window->keys[key] == GLFW_PRESS)
+ action = GLFW_RELEASE;
+ else
+ action = GLFW_PRESS;
+ }
+ else
+ action = GLFW_RELEASE;
+
+ _glfwInputKey(window, key, [event keyCode], action, mods);
+}
+
+- (void)keyUp:(NSEvent *)event
+{
+ const int key = translateKey([event keyCode]);
+ const int mods = translateFlags([event modifierFlags]);
+ _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
+}
+
+- (void)scrollWheel:(NSEvent *)event
+{
+ double deltaX, deltaY;
+
+ deltaX = [event scrollingDeltaX];
+ deltaY = [event scrollingDeltaY];
+
+ if ([event hasPreciseScrollingDeltas])
+ {
+ deltaX *= 0.1;
+ deltaY *= 0.1;
+ }
+
+ if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0)
+ _glfwInputScroll(window, deltaX, deltaY);
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
+ == NSDragOperationGeneric)
+ {
+ [self setNeedsDisplay:YES];
+ return NSDragOperationGeneric;
+ }
+
+ return NSDragOperationNone;
+}
+
+- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
+{
+ [self setNeedsDisplay:YES];
+ return YES;
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ NSPasteboard* pasteboard = [sender draggingPasteboard];
+ NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
+
+ const NSRect contentRect = [window->ns.view frame];
+ _glfwInputCursorPos(window,
+ [sender draggingLocation].x,
+ contentRect.size.height - [sender draggingLocation].y);
+
+ const int count = [files count];
+ if (count)
+ {
+ NSEnumerator* e = [files objectEnumerator];
+ char** paths = calloc(count, sizeof(char*));
+ int i;
+
+ for (i = 0; i < count; i++)
+ paths[i] = strdup([[e nextObject] UTF8String]);
+
+ _glfwInputDrop(window, count, (const char**) paths);
+
+ for (i = 0; i < count; i++)
+ free(paths[i]);
+ free(paths);
+ }
+
+ return YES;
+}
+
+- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
+{
+ [self setNeedsDisplay:YES];
+}
+
+- (BOOL)hasMarkedText
+{
+ return [markedText length] > 0;
+}
+
+- (NSRange)markedRange
+{
+ if ([markedText length] > 0)
+ return NSMakeRange(0, [markedText length] - 1);
+ else
+ return kEmptyRange;
+}
+
+- (NSRange)selectedRange
+{
+ return kEmptyRange;
+}
+
+- (void)setMarkedText:(id)string
+ selectedRange:(NSRange)selectedRange
+ replacementRange:(NSRange)replacementRange
+{
+ [markedText release];
+ if ([string isKindOfClass:[NSAttributedString class]])
+ markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string];
+ else
+ markedText = [[NSMutableAttributedString alloc] initWithString:string];
+}
+
+- (void)unmarkText
+{
+ [[markedText mutableString] setString:@""];
+}
+
+- (NSArray*)validAttributesForMarkedText
+{
+ return [NSArray array];
+}
+
+- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range
+ actualRange:(NSRangePointer)actualRange
+{
+ return nil;
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)point
+{
+ return 0;
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)range
+ actualRange:(NSRangePointer)actualRange
+{
+ int xpos, ypos;
+ _glfwPlatformGetWindowPos(window, &xpos, &ypos);
+ const NSRect contentRect = [window->ns.view frame];
+ return NSMakeRect(xpos, transformY(ypos + contentRect.size.height), 0.0, 0.0);
+}
+
+- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
+{
+ NSString* characters;
+ NSEvent* event = [NSApp currentEvent];
+ const int mods = translateFlags([event modifierFlags]);
+ const int plain = !(mods & GLFW_MOD_SUPER);
+
+ if ([string isKindOfClass:[NSAttributedString class]])
+ characters = [string string];
+ else
+ characters = (NSString*) string;
+
+ NSUInteger i, length = [characters length];
+
+ for (i = 0; i < length; i++)
+ {
+ const unichar codepoint = [characters characterAtIndex:i];
+ if ((codepoint & 0xff00) == 0xf700)
+ continue;
+
+ _glfwInputChar(window, codepoint, mods, plain);
+ }
+}
+
+- (void)doCommandBySelector:(SEL)selector
+{
+}
+
+@end
+
+
+//------------------------------------------------------------------------
+// GLFW window class
+//------------------------------------------------------------------------
+
+@interface GLFWWindow : NSWindow {}
+@end
+
+@implementation GLFWWindow
+
+- (BOOL)canBecomeKeyWindow
+{
+ // Required for NSWindowStyleMaskBorderless windows
+ return YES;
+}
+
+- (BOOL)canBecomeMainWindow
+{
+ return YES;
+}
+
+@end
+
+
+//------------------------------------------------------------------------
+// GLFW application class
+//------------------------------------------------------------------------
+
+@interface GLFWApplication : NSApplication
+{
+ NSArray* nibObjects;
+}
+
+@end
+
+@implementation GLFWApplication
+
+// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
+// This works around an AppKit bug, where key up events while holding
+// down the command key don't get sent to the key window.
+- (void)sendEvent:(NSEvent *)event
+{
+ if ([event type] == NSEventTypeKeyUp &&
+ ([event modifierFlags] & NSEventModifierFlagCommand))
+ {
+ [[self keyWindow] sendEvent:event];
+ }
+ else
+ [super sendEvent:event];
+}
+
+
+// No-op thread entry point
+//
+- (void)doNothing:(id)object
+{
+}
+
+- (void)loadMainMenu
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 100800
+ [[NSBundle mainBundle] loadNibNamed:@"MainMenu"
+ owner:NSApp
+ topLevelObjects:&nibObjects];
+#else
+ [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp];
+#endif
+}
+@end
+
+// Set up the menu bar (manually)
+// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
+// could go away at any moment, lots of stuff that really should be
+// localize(d|able), etc. Add a nib to save us this horror.
+//
+static void createMenuBar(void)
+{
+ size_t i;
+ NSString* appName = nil;
+ NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
+ NSString* nameKeys[] =
+ {
+ @"CFBundleDisplayName",
+ @"CFBundleName",
+ @"CFBundleExecutable",
+ };
+
+ // Try to figure out what the calling application is called
+
+ for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
+ {
+ id name = [bundleInfo objectForKey:nameKeys[i]];
+ if (name &&
+ [name isKindOfClass:[NSString class]] &&
+ ![name isEqualToString:@""])
+ {
+ appName = name;
+ break;
+ }
+ }
+
+ if (!appName)
+ {
+ char** progname = _NSGetProgname();
+ if (progname && *progname)
+ appName = [NSString stringWithUTF8String:*progname];
+ else
+ appName = @"GLFW Application";
+ }
+
+ NSMenu* bar = [[NSMenu alloc] init];
+ [NSApp setMainMenu:bar];
+
+ NSMenuItem* appMenuItem =
+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+ NSMenu* appMenu = [[NSMenu alloc] init];
+ [appMenuItem setSubmenu:appMenu];
+
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
+ action:@selector(orderFrontStandardAboutPanel:)
+ keyEquivalent:@""];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+ NSMenu* servicesMenu = [[NSMenu alloc] init];
+ [NSApp setServicesMenu:servicesMenu];
+ [[appMenu addItemWithTitle:@"Services"
+ action:NULL
+ keyEquivalent:@""] setSubmenu:servicesMenu];
+ [servicesMenu release];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
+ action:@selector(hide:)
+ keyEquivalent:@"h"];
+ [[appMenu addItemWithTitle:@"Hide Others"
+ action:@selector(hideOtherApplications:)
+ keyEquivalent:@"h"]
+ setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
+ [appMenu addItemWithTitle:@"Show All"
+ action:@selector(unhideAllApplications:)
+ keyEquivalent:@""];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
+ action:@selector(terminate:)
+ keyEquivalent:@"q"];
+
+ NSMenuItem* windowMenuItem =
+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+ [bar release];
+ NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+ [NSApp setWindowsMenu:windowMenu];
+ [windowMenuItem setSubmenu:windowMenu];
+
+ [windowMenu addItemWithTitle:@"Minimize"
+ action:@selector(performMiniaturize:)
+ keyEquivalent:@"m"];
+ [windowMenu addItemWithTitle:@"Zoom"
+ action:@selector(performZoom:)
+ keyEquivalent:@""];
+ [windowMenu addItem:[NSMenuItem separatorItem]];
+ [windowMenu addItemWithTitle:@"Bring All to Front"
+ action:@selector(arrangeInFront:)
+ keyEquivalent:@""];
+
+ // TODO: Make this appear at the bottom of the menu (for consistency)
+ [windowMenu addItem:[NSMenuItem separatorItem]];
+ [[windowMenu addItemWithTitle:@"Enter Full Screen"
+ action:@selector(toggleFullScreen:)
+ keyEquivalent:@"f"]
+ setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
+
+ // Prior to Snow Leopard, we need to use this oddly-named semi-private API
+ // to get the application menu working properly.
+ SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:");
+ [NSApp performSelector:setAppleMenuSelector withObject:appMenu];
+}
+
+// Initialize the Cocoa Application Kit
+//
+static GLFWbool initializeAppKit(void)
+{
+ if (NSApp)
+ return GLFW_TRUE;
+
+ // Implicitly create shared NSApplication instance
+ [GLFWApplication sharedApplication];
+
+ // Make Cocoa enter multi-threaded mode
+ [NSThread detachNewThreadSelector:@selector(doNothing:)
+ toTarget:NSApp
+ withObject:nil];
+
+ if (_glfw.hints.init.ns.menubar)
+ {
+ // In case we are unbundled, make us a proper UI application
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+
+ // 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"])
+ [NSApp loadMainMenu];
+ else
+ createMenuBar();
+ }
+
+ // There can only be one application delegate, but we allocate it the
+ // first time a window is created to keep all window code in this file
+ _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
+ if (_glfw.ns.delegate == nil)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to create application delegate");
+ return GLFW_FALSE;
+ }
+
+ [NSApp setDelegate:_glfw.ns.delegate];
+ [NSApp run];
+
+ // Press and Hold prevents some keys from emitting repeated characters
+ NSDictionary* defaults =
+ [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],
+ @"ApplePressAndHoldEnabled",
+ nil];
+ [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
+
+ return GLFW_TRUE;
+}
+
+// Create the Cocoa window
+//
+static GLFWbool createNativeWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
+ if (window->ns.delegate == nil)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to create window delegate");
+ return GLFW_FALSE;
+ }
+
+ NSRect contentRect;
+
+ if (window->monitor)
+ {
+ GLFWvidmode mode;
+ int xpos, ypos;
+
+ _glfwPlatformGetVideoMode(window->monitor, &mode);
+ _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
+
+ contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height);
+ }
+ else
+ contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height);
+
+ window->ns.object = [[GLFWWindow alloc]
+ initWithContentRect:contentRect
+ styleMask:getStyleMask(window)
+ backing:NSBackingStoreBuffered
+ defer:NO];
+
+ if (window->ns.object == nil)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create window");
+ return GLFW_FALSE;
+ }
+
+ if (window->monitor)
+ [window->ns.object setLevel:NSMainMenuWindowLevel + 1];
+ else
+ {
+ [window->ns.object center];
+ _glfw.ns.cascadePoint =
+ NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
+ NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
+
+ if (wndconfig->resizable)
+ {
+ const NSWindowCollectionBehavior behavior =
+ NSWindowCollectionBehaviorFullScreenPrimary |
+ NSWindowCollectionBehaviorManaged;
+ [window->ns.object setCollectionBehavior:behavior];
+ }
+
+ if (wndconfig->floating)
+ [window->ns.object setLevel:NSFloatingWindowLevel];
+
+ if (wndconfig->maximized)
+ [window->ns.object zoom:nil];
+ }
+
+ if (wndconfig->ns.frame)
+ [window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->title]];
+
+ window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
+
+ if (wndconfig->ns.retina)
+ [window->ns.view setWantsBestResolutionOpenGLSurface:YES];
+
+ if (fbconfig->transparent)
+ {
+ [window->ns.object setOpaque:NO];
+ [window->ns.object setBackgroundColor:[NSColor clearColor]];
+ }
+
+ [window->ns.object setContentView:window->ns.view];
+ [window->ns.object makeFirstResponder:window->ns.view];
+ [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
+ [window->ns.object setDelegate:window->ns.delegate];
+ [window->ns.object setAcceptsMouseMovedEvents:YES];
+ [window->ns.object setRestorable:NO];
+
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ if (!initializeAppKit())
+ return GLFW_FALSE;
+
+ if (!createNativeWindow(window, wndconfig, fbconfig))
+ return GLFW_FALSE;
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
+ {
+ if (!_glfwInitNSGL())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
+ {
+ if (!_glfwInitEGL())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwInitOSMesa())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ }
+
+ if (window->monitor)
+ {
+ _glfwPlatformShowWindow(window);
+ _glfwPlatformFocusWindow(window);
+ if (!acquireMonitor(window))
+ return GLFW_FALSE;
+
+ if (wndconfig->centerCursor)
+ centerCursor(window);
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+{
+ if (_glfw.ns.disabledCursorWindow == window)
+ _glfw.ns.disabledCursorWindow = NULL;
+
+ [window->ns.object orderOut:nil];
+
+ if (window->monitor)
+ releaseMonitor(window);
+
+ if (window->context.destroy)
+ window->context.destroy(window);
+
+ [window->ns.object setDelegate:nil];
+ [window->ns.delegate release];
+ window->ns.delegate = nil;
+
+ [window->ns.view release];
+ window->ns.view = nil;
+
+ [window->ns.object close];
+ window->ns.object = nil;
+
+ [_glfw.ns.autoreleasePool drain];
+ _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
+}
+
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
+{
+ NSString* string = [NSString stringWithUTF8String:title];
+ [window->ns.object setTitle:string];
+ // HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
+ // if the window lacks NSWindowStyleMaskTitled
+ [window->ns.object setMiniwindowTitle:string];
+}
+
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
+ int count, const GLFWimage* images)
+{
+ // Regular windows do not have icons
+}
+
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+{
+ const NSRect contentRect =
+ [window->ns.object contentRectForFrameRect:[window->ns.object frame]];
+
+ if (xpos)
+ *xpos = contentRect.origin.x;
+ if (ypos)
+ *ypos = transformY(contentRect.origin.y + contentRect.size.height);
+}
+
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
+{
+ const NSRect contentRect = [window->ns.view frame];
+ const NSRect dummyRect = NSMakeRect(x, transformY(y + contentRect.size.height), 0, 0);
+ const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect];
+ [window->ns.object setFrameOrigin:frameRect.origin];
+}
+
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
+{
+ const NSRect contentRect = [window->ns.view frame];
+
+ if (width)
+ *width = contentRect.size.width;
+ if (height)
+ *height = contentRect.size.height;
+}
+
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
+{
+ if (window->monitor)
+ {
+ if (window->monitor->window == window)
+ acquireMonitor(window);
+ }
+ else
+ [window->ns.object setContentSize:NSMakeSize(width, height)];
+}
+
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+ if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
+ [window->ns.object setContentMinSize:NSMakeSize(0, 0)];
+ else
+ [window->ns.object setContentMinSize:NSMakeSize(minwidth, minheight)];
+
+ if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)
+ [window->ns.object setContentMaxSize:NSMakeSize(DBL_MAX, DBL_MAX)];
+ else
+ [window->ns.object setContentMaxSize:NSMakeSize(maxwidth, maxheight)];
+}
+
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
+{
+ if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
+ [window->ns.object setResizeIncrements:NSMakeSize(1.0, 1.0)];
+ else
+ [window->ns.object setContentAspectRatio:NSMakeSize(numer, denom)];
+}
+
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
+{
+ const NSRect contentRect = [window->ns.view frame];
+ const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
+
+ if (width)
+ *width = (int) fbRect.size.width;
+ if (height)
+ *height = (int) fbRect.size.height;
+}
+
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+ const NSRect contentRect = [window->ns.view frame];
+ const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect];
+
+ if (left)
+ *left = contentRect.origin.x - frameRect.origin.x;
+ if (top)
+ *top = frameRect.origin.y + frameRect.size.height -
+ contentRect.origin.y - contentRect.size.height;
+ if (right)
+ *right = frameRect.origin.x + frameRect.size.width -
+ contentRect.origin.x - contentRect.size.width;
+ if (bottom)
+ *bottom = contentRect.origin.y - frameRect.origin.y;
+}
+
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+ float* xscale, float* yscale)
+{
+ const NSRect points = [window->ns.view frame];
+ const NSRect pixels = [window->ns.view convertRectToBacking:points];
+
+ if (xscale)
+ *xscale = (float) (pixels.size.width / points.size.width);
+ if (yscale)
+ *yscale = (float) (pixels.size.height / points.size.height);
+}
+
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
+{
+ [window->ns.object miniaturize:nil];
+}
+
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
+{
+ if ([window->ns.object isMiniaturized])
+ [window->ns.object deminiaturize:nil];
+ else if ([window->ns.object isZoomed])
+ [window->ns.object zoom:nil];
+}
+
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
+{
+ if (![window->ns.object isZoomed])
+ [window->ns.object zoom:nil];
+}
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+ [window->ns.object orderFront:nil];
+}
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+ [window->ns.object orderOut:nil];
+}
+
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+{
+ [NSApp requestUserAttention:NSInformationalRequest];
+}
+
+void _glfwPlatformFocusWindow(_GLFWwindow* window)
+{
+ // Make us the active application
+ // HACK: This has been moved here from initializeAppKit to prevent
+ // applications using only hidden windows from being activated, but
+ // should probably not be done every time any window is shown
+ [NSApp activateIgnoringOtherApps:YES];
+
+ [window->ns.object makeKeyAndOrderFront:nil];
+}
+
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+ _GLFWmonitor* monitor,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+ if (window->monitor == monitor)
+ {
+ if (monitor)
+ {
+ if (monitor->window == window)
+ acquireMonitor(window);
+ }
+ else
+ {
+ const NSRect contentRect =
+ NSMakeRect(xpos, transformY(ypos + height), width, height);
+ const NSRect frameRect =
+ [window->ns.object frameRectForContentRect:contentRect
+ styleMask:getStyleMask(window)];
+
+ [window->ns.object setFrame:frameRect display:YES];
+ }
+
+ return;
+ }
+
+ if (window->monitor)
+ releaseMonitor(window);
+
+ _glfwInputWindowMonitor(window, monitor);
+
+ // HACK: Allow the state cached in Cocoa to catch up to reality
+ // TODO: Solve this in a less terrible way
+ _glfwPlatformPollEvents();
+
+ const NSUInteger styleMask = getStyleMask(window);
+ [window->ns.object setStyleMask:styleMask];
+ [window->ns.object makeFirstResponder:window->ns.view];
+
+ NSRect contentRect;
+
+ if (monitor)
+ {
+ GLFWvidmode mode;
+
+ _glfwPlatformGetVideoMode(window->monitor, &mode);
+ _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
+
+ contentRect = NSMakeRect(xpos, transformY(ypos + mode.height),
+ mode.width, mode.height);
+ }
+ else
+ {
+ contentRect = NSMakeRect(xpos, transformY(ypos + height),
+ width, height);
+ }
+
+ NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect
+ styleMask:styleMask];
+ [window->ns.object setFrame:frameRect display:YES];
+
+ if (monitor)
+ {
+ [window->ns.object setLevel:NSMainMenuWindowLevel + 1];
+ [window->ns.object setHasShadow:NO];
+
+ acquireMonitor(window);
+ }
+ else
+ {
+ if (window->numer != GLFW_DONT_CARE &&
+ window->denom != GLFW_DONT_CARE)
+ {
+ [window->ns.object setContentAspectRatio:NSMakeSize(window->numer,
+ window->denom)];
+ }
+
+ if (window->minwidth != GLFW_DONT_CARE &&
+ window->minheight != GLFW_DONT_CARE)
+ {
+ [window->ns.object setContentMinSize:NSMakeSize(window->minwidth,
+ window->minheight)];
+ }
+
+ if (window->maxwidth != GLFW_DONT_CARE &&
+ window->maxheight != GLFW_DONT_CARE)
+ {
+ [window->ns.object setContentMaxSize:NSMakeSize(window->maxwidth,
+ window->maxheight)];
+ }
+
+ if (window->floating)
+ [window->ns.object setLevel:NSFloatingWindowLevel];
+ else
+ [window->ns.object setLevel:NSNormalWindowLevel];
+
+ [window->ns.object setHasShadow:YES];
+ // HACK: Clearing NSWindowStyleMaskTitled resets and disables the window
+ // title property but the miniwindow title property is unaffected
+ [window->ns.object setTitle:[window->ns.object miniwindowTitle]];
+ }
+}
+
+int _glfwPlatformWindowFocused(_GLFWwindow* window)
+{
+ return [window->ns.object isKeyWindow];
+}
+
+int _glfwPlatformWindowIconified(_GLFWwindow* window)
+{
+ return [window->ns.object isMiniaturized];
+}
+
+int _glfwPlatformWindowVisible(_GLFWwindow* window)
+{
+ return [window->ns.object isVisible];
+}
+
+int _glfwPlatformWindowMaximized(_GLFWwindow* window)
+{
+ return [window->ns.object isZoomed];
+}
+
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
+{
+ return ![window->ns.object isOpaque] && ![window->ns.view isOpaque];
+}
+
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
+{
+ [window->ns.object setStyleMask:getStyleMask(window)];
+}
+
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
+{
+ [window->ns.object setStyleMask:getStyleMask(window)];
+ [window->ns.object makeFirstResponder:window->ns.view];
+}
+
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
+{
+ if (enabled)
+ [window->ns.object setLevel:NSFloatingWindowLevel];
+ else
+ [window->ns.object setLevel:NSNormalWindowLevel];
+}
+
+void _glfwPlatformPollEvents(void)
+{
+ for (;;)
+ {
+ NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
+ untilDate:[NSDate distantPast]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event == nil)
+ break;
+
+ [NSApp sendEvent:event];
+ }
+
+ [_glfw.ns.autoreleasePool drain];
+ _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
+}
+
+void _glfwPlatformWaitEvents(void)
+{
+ // I wanted to pass NO to dequeue:, and rely on PollEvents to
+ // dequeue and send. For reasons not at all clear to me, passing
+ // NO to dequeue: causes this method never to return.
+ NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny
+ untilDate:[NSDate distantFuture]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ [NSApp sendEvent:event];
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformWaitEventsTimeout(double timeout)
+{
+ NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
+ NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
+ untilDate:date
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event)
+ [NSApp sendEvent:event];
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformPostEmptyEvent(void)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
+ location:NSMakePoint(0, 0)
+ modifierFlags:0
+ timestamp:0
+ windowNumber:0
+ context:nil
+ subtype:0
+ data1:0
+ data2:0];
+ [NSApp postEvent:event atStart:YES];
+ [pool drain];
+}
+
+void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
+{
+ const NSRect contentRect = [window->ns.view frame];
+ const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
+
+ if (xpos)
+ *xpos = pos.x;
+ if (ypos)
+ *ypos = contentRect.size.height - pos.y - 1;
+}
+
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
+{
+ updateCursorImage(window);
+
+ const NSRect contentRect = [window->ns.view frame];
+ const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
+
+ window->ns.cursorWarpDeltaX += x - pos.x;
+ window->ns.cursorWarpDeltaY += y - contentRect.size.height + pos.y;
+
+ if (window->monitor)
+ {
+ CGDisplayMoveCursorToPoint(window->monitor->ns.displayID,
+ CGPointMake(x, y));
+ }
+ else
+ {
+ const NSRect localRect = NSMakeRect(x, contentRect.size.height - y - 1, 0, 0);
+ const NSRect globalRect = [window->ns.object convertRectToScreen:localRect];
+ const NSPoint globalPoint = globalRect.origin;
+
+ CGWarpMouseCursorPosition(CGPointMake(globalPoint.x,
+ transformY(globalPoint.y)));
+ }
+}
+
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
+{
+ if (mode == GLFW_CURSOR_DISABLED)
+ {
+ _glfw.ns.disabledCursorWindow = window;
+ _glfwPlatformGetCursorPos(window,
+ &_glfw.ns.restoreCursorPosX,
+ &_glfw.ns.restoreCursorPosY);
+ centerCursor(window);
+ CGAssociateMouseAndMouseCursorPosition(false);
+ }
+ else if (_glfw.ns.disabledCursorWindow == window)
+ {
+ _glfw.ns.disabledCursorWindow = NULL;
+ CGAssociateMouseAndMouseCursorPosition(true);
+ _glfwPlatformSetCursorPos(window,
+ _glfw.ns.restoreCursorPosX,
+ _glfw.ns.restoreCursorPosY);
+ }
+
+ if (cursorInClientArea(window))
+ updateCursorImage(window);
+}
+
+const char* _glfwPlatformGetScancodeName(int scancode)
+{
+ UInt32 deadKeyState = 0;
+ UniChar characters[8];
+ UniCharCount characterCount = 0;
+
+ if (UCKeyTranslate([(NSData*) _glfw.ns.unicodeData bytes],
+ scancode,
+ kUCKeyActionDisplay,
+ 0,
+ LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysBit,
+ &deadKeyState,
+ sizeof(characters) / sizeof(characters[0]),
+ &characterCount,
+ characters) != noErr)
+ {
+ return NULL;
+ }
+
+ if (!characterCount)
+ return NULL;
+
+ CFStringRef string = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
+ characters,
+ characterCount,
+ kCFAllocatorNull);
+ CFStringGetCString(string,
+ _glfw.ns.keyName,
+ sizeof(_glfw.ns.keyName),
+ kCFStringEncodingUTF8);
+ CFRelease(string);
+
+ return _glfw.ns.keyName;
+}
+
+int _glfwPlatformGetKeyScancode(int key)
+{
+ return _glfw.ns.scancodes[key];
+}
+
+int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
+ const GLFWimage* image,
+ int xhot, int yhot)
+{
+ NSImage* native;
+ NSBitmapImageRep* rep;
+
+ if (!initializeAppKit())
+ return GLFW_FALSE;
+
+ rep = [[NSBitmapImageRep alloc]
+ initWithBitmapDataPlanes:NULL
+ pixelsWide:image->width
+ pixelsHigh:image->height
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSCalibratedRGBColorSpace
+ bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
+ bytesPerRow:image->width * 4
+ bitsPerPixel:32];
+
+ if (rep == nil)
+ return GLFW_FALSE;
+
+ memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);
+
+ native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)];
+ [native addRepresentation:rep];
+
+ cursor->ns.object = [[NSCursor alloc] initWithImage:native
+ hotSpot:NSMakePoint(xhot, yhot)];
+
+ [native release];
+ [rep release];
+
+ if (cursor->ns.object == nil)
+ return GLFW_FALSE;
+
+ return GLFW_TRUE;
+}
+
+int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
+{
+ if (!initializeAppKit())
+ return GLFW_FALSE;
+
+ if (shape == GLFW_ARROW_CURSOR)
+ cursor->ns.object = [NSCursor arrowCursor];
+ else if (shape == GLFW_IBEAM_CURSOR)
+ cursor->ns.object = [NSCursor IBeamCursor];
+ else if (shape == GLFW_CROSSHAIR_CURSOR)
+ cursor->ns.object = [NSCursor crosshairCursor];
+ else if (shape == GLFW_HAND_CURSOR)
+ cursor->ns.object = [NSCursor pointingHandCursor];
+ else if (shape == GLFW_HRESIZE_CURSOR)
+ cursor->ns.object = [NSCursor resizeLeftRightCursor];
+ else if (shape == GLFW_VRESIZE_CURSOR)
+ cursor->ns.object = [NSCursor resizeUpDownCursor];
+
+ if (!cursor->ns.object)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to retrieve standard cursor");
+ return GLFW_FALSE;
+ }
+
+ [cursor->ns.object retain];
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
+{
+ if (cursor->ns.object)
+ [(NSCursor*) cursor->ns.object release];
+}
+
+void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+{
+ if (cursorInClientArea(window))
+ updateCursorImage(window);
+}
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
+
+ NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+ [pasteboard declareTypes:types owner:nil];
+ [pasteboard setString:[NSString stringWithUTF8String:string]
+ forType:NSStringPboardType];
+}
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+
+ if (![[pasteboard types] containsObject:NSStringPboardType])
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "Cocoa: Failed to retrieve string from pasteboard");
+ return NULL;
+ }
+
+ NSString* object = [pasteboard stringForType:NSStringPboardType];
+ if (!object)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to retrieve object from pasteboard");
+ return NULL;
+ }
+
+ free(_glfw.ns.clipboardString);
+ _glfw.ns.clipboardString = strdup([object UTF8String]);
+
+ return _glfw.ns.clipboardString;
+}
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
+{
+ if (!_glfw.vk.KHR_surface || !_glfw.vk.MVK_macos_surface)
+ return;
+
+ extensions[0] = "VK_KHR_surface";
+ extensions[1] = "VK_MVK_macos_surface";
+}
+
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ return GLFW_TRUE;
+}
+
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
+ _GLFWwindow* window,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
+ VkResult err;
+ VkMacOSSurfaceCreateInfoMVK sci;
+ PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
+
+ vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)
+ vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
+ if (!vkCreateMacOSSurfaceMVK)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ // HACK: Dynamically load Core Animation to avoid adding an extra
+ // dependency for the majority who don't use MoltenVK
+ NSBundle* bundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];
+ if (!bundle)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to find QuartzCore.framework");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ // NOTE: Create the layer here as makeBackingLayer should not return nil
+ window->ns.layer = [[bundle classNamed:@"CAMetalLayer"] layer];
+ if (!window->ns.layer)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to create layer for view");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ [window->ns.view setWantsLayer:YES];
+
+ memset(&sci, 0, sizeof(sci));
+ sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
+ sci.pView = window->ns.view;
+
+ err = vkCreateMacOSSurfaceMVK(instance, &sci, allocator, surface);
+ if (err)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Cocoa: Failed to create Vulkan surface: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ return err;
+#else
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(nil);
+ return window->ns.object;
+}
+
diff --git a/src/external/glfw/src/context.c b/src/external/glfw/src/context.c
new file mode 100644
index 00000000..3842f0a3
--- /dev/null
+++ b/src/external/glfw/src/context.c
@@ -0,0 +1,723 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
+{
+ if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
+ ctxconfig->source != GLFW_EGL_CONTEXT_API &&
+ ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid context creation API 0x%08X",
+ ctxconfig->source);
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->client != GLFW_NO_API &&
+ ctxconfig->client != GLFW_OPENGL_API &&
+ ctxconfig->client != GLFW_OPENGL_ES_API)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid client API 0x%08X",
+ ctxconfig->client);
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
+ (ctxconfig->major == 1 && ctxconfig->minor > 5) ||
+ (ctxconfig->major == 2 && ctxconfig->minor > 1) ||
+ (ctxconfig->major == 3 && ctxconfig->minor > 3))
+ {
+ // OpenGL 1.0 is the smallest valid version
+ // OpenGL 1.x series ended with version 1.5
+ // OpenGL 2.x series ended with version 2.1
+ // OpenGL 3.x series ended with version 3.3
+ // For now, let everything else through
+
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid OpenGL version %i.%i",
+ ctxconfig->major, ctxconfig->minor);
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->profile)
+ {
+ if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE &&
+ ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid OpenGL profile 0x%08X",
+ ctxconfig->profile);
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->major <= 2 ||
+ (ctxconfig->major == 3 && ctxconfig->minor < 2))
+ {
+ // Desktop OpenGL context profiles are only defined for version 3.2
+ // and above
+
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Context profiles are only defined for OpenGL version 3.2 and above");
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->forward && ctxconfig->major <= 2)
+ {
+ // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Forward-compatibility is only defined for OpenGL version 3.0 and above");
+ return GLFW_FALSE;
+ }
+ }
+ else if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
+ (ctxconfig->major == 1 && ctxconfig->minor > 1) ||
+ (ctxconfig->major == 2 && ctxconfig->minor > 0))
+ {
+ // OpenGL ES 1.0 is the smallest valid version
+ // OpenGL ES 1.x series ended with version 1.1
+ // OpenGL ES 2.x series ended with version 2.0
+ // For now, let everything else through
+
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid OpenGL ES version %i.%i",
+ ctxconfig->major, ctxconfig->minor);
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->robustness)
+ {
+ if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
+ ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid context robustness mode 0x%08X",
+ ctxconfig->robustness);
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->release)
+ {
+ if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
+ ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid context release behavior 0x%08X",
+ ctxconfig->release);
+ return GLFW_FALSE;
+ }
+ }
+
+ return GLFW_TRUE;
+}
+
+const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
+ const _GLFWfbconfig* alternatives,
+ unsigned int count)
+{
+ unsigned int i;
+ unsigned int missing, leastMissing = UINT_MAX;
+ unsigned int colorDiff, leastColorDiff = UINT_MAX;
+ unsigned int extraDiff, leastExtraDiff = UINT_MAX;
+ const _GLFWfbconfig* current;
+ const _GLFWfbconfig* closest = NULL;
+
+ for (i = 0; i < count; i++)
+ {
+ current = alternatives + i;
+
+ if (desired->stereo > 0 && current->stereo == 0)
+ {
+ // Stereo is a hard constraint
+ continue;
+ }
+
+ if (desired->doublebuffer != current->doublebuffer)
+ {
+ // Double buffering is a hard constraint
+ continue;
+ }
+
+ // Count number of missing buffers
+ {
+ missing = 0;
+
+ if (desired->alphaBits > 0 && current->alphaBits == 0)
+ missing++;
+
+ if (desired->depthBits > 0 && current->depthBits == 0)
+ missing++;
+
+ if (desired->stencilBits > 0 && current->stencilBits == 0)
+ missing++;
+
+ if (desired->auxBuffers > 0 &&
+ current->auxBuffers < desired->auxBuffers)
+ {
+ missing += desired->auxBuffers - current->auxBuffers;
+ }
+
+ if (desired->samples > 0 && current->samples == 0)
+ {
+ // Technically, several multisampling buffers could be
+ // involved, but that's a lower level implementation detail and
+ // not important to us here, so we count them as one
+ missing++;
+ }
+
+ if (desired->transparent != current->transparent)
+ missing++;
+ }
+
+ // These polynomials make many small channel size differences matter
+ // less than one large channel size difference
+
+ // Calculate color channel size difference value
+ {
+ colorDiff = 0;
+
+ if (desired->redBits != GLFW_DONT_CARE)
+ {
+ colorDiff += (desired->redBits - current->redBits) *
+ (desired->redBits - current->redBits);
+ }
+
+ if (desired->greenBits != GLFW_DONT_CARE)
+ {
+ colorDiff += (desired->greenBits - current->greenBits) *
+ (desired->greenBits - current->greenBits);
+ }
+
+ if (desired->blueBits != GLFW_DONT_CARE)
+ {
+ colorDiff += (desired->blueBits - current->blueBits) *
+ (desired->blueBits - current->blueBits);
+ }
+ }
+
+ // Calculate non-color channel size difference value
+ {
+ extraDiff = 0;
+
+ if (desired->alphaBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->alphaBits - current->alphaBits) *
+ (desired->alphaBits - current->alphaBits);
+ }
+
+ if (desired->depthBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->depthBits - current->depthBits) *
+ (desired->depthBits - current->depthBits);
+ }
+
+ if (desired->stencilBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->stencilBits - current->stencilBits) *
+ (desired->stencilBits - current->stencilBits);
+ }
+
+ if (desired->accumRedBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->accumRedBits - current->accumRedBits) *
+ (desired->accumRedBits - current->accumRedBits);
+ }
+
+ if (desired->accumGreenBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
+ (desired->accumGreenBits - current->accumGreenBits);
+ }
+
+ if (desired->accumBlueBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
+ (desired->accumBlueBits - current->accumBlueBits);
+ }
+
+ if (desired->accumAlphaBits != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
+ (desired->accumAlphaBits - current->accumAlphaBits);
+ }
+
+ if (desired->samples != GLFW_DONT_CARE)
+ {
+ extraDiff += (desired->samples - current->samples) *
+ (desired->samples - current->samples);
+ }
+
+ if (desired->sRGB && !current->sRGB)
+ extraDiff++;
+ }
+
+ // Figure out if the current one is better than the best one found so far
+ // Least number of missing buffers is the most important heuristic,
+ // then color buffer size match and lastly size match for other buffers
+
+ if (missing < leastMissing)
+ closest = current;
+ else if (missing == leastMissing)
+ {
+ if ((colorDiff < leastColorDiff) ||
+ (colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
+ {
+ closest = current;
+ }
+ }
+
+ if (current == closest)
+ {
+ leastMissing = missing;
+ leastColorDiff = colorDiff;
+ leastExtraDiff = extraDiff;
+ }
+ }
+
+ return closest;
+}
+
+GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
+{
+ int i;
+ _GLFWwindow* window;
+ const char* version;
+ const char* prefixes[] =
+ {
+ "OpenGL ES-CM ",
+ "OpenGL ES-CL ",
+ "OpenGL ES ",
+ NULL
+ };
+
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
+
+ window->context.source = ctxconfig->source;
+ window->context.client = GLFW_OPENGL_API;
+
+ window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
+ window->context.getProcAddress("glGetIntegerv");
+ window->context.GetString = (PFNGLGETSTRINGPROC)
+ window->context.getProcAddress("glGetString");
+ if (!window->context.GetIntegerv || !window->context.GetString)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
+ return GLFW_FALSE;
+ }
+
+ version = (const char*) window->context.GetString(GL_VERSION);
+ if (!version)
+ {
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OpenGL version string retrieval is broken");
+ }
+ else
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OpenGL ES version string retrieval is broken");
+ }
+
+ return GLFW_FALSE;
+ }
+
+ for (i = 0; prefixes[i]; i++)
+ {
+ const size_t length = strlen(prefixes[i]);
+
+ if (strncmp(version, prefixes[i], length) == 0)
+ {
+ version += length;
+ window->context.client = GLFW_OPENGL_ES_API;
+ break;
+ }
+ }
+
+ if (!sscanf(version, "%d.%d.%d",
+ &window->context.major,
+ &window->context.minor,
+ &window->context.revision))
+ {
+ if (window->context.client == GLFW_OPENGL_API)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "No version found in OpenGL version string");
+ }
+ else
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "No version found in OpenGL ES version string");
+ }
+
+ return GLFW_FALSE;
+ }
+
+ if (window->context.major < ctxconfig->major ||
+ (window->context.major == ctxconfig->major &&
+ window->context.minor < ctxconfig->minor))
+ {
+ // The desired OpenGL version is greater than the actual version
+ // This only happens if the machine lacks {GLX|WGL}_ARB_create_context
+ // /and/ the user has requested an OpenGL version greater than 1.0
+
+ // For API consistency, we emulate the behavior of the
+ // {GLX|WGL}_ARB_create_context extension and fail here
+
+ if (window->context.client == GLFW_OPENGL_API)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "Requested OpenGL version %i.%i, got version %i.%i",
+ ctxconfig->major, ctxconfig->minor,
+ window->context.major, window->context.minor);
+ }
+ else
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "Requested OpenGL ES version %i.%i, got version %i.%i",
+ ctxconfig->major, ctxconfig->minor,
+ window->context.major, window->context.minor);
+ }
+
+ return GLFW_FALSE;
+ }
+
+ if (window->context.major >= 3)
+ {
+ // OpenGL 3.0+ uses a different function for extension string retrieval
+ // We cache it here instead of in glfwExtensionSupported mostly to alert
+ // users as early as possible that their build may be broken
+
+ window->context.GetStringi = (PFNGLGETSTRINGIPROC)
+ window->context.getProcAddress("glGetStringi");
+ if (!window->context.GetStringi)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Entry point retrieval is broken");
+ return GLFW_FALSE;
+ }
+ }
+
+ if (window->context.client == GLFW_OPENGL_API)
+ {
+ // Read back context flags (OpenGL 3.0 and above)
+ if (window->context.major >= 3)
+ {
+ GLint flags;
+ window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
+
+ if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
+ window->context.forward = GLFW_TRUE;
+
+ if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
+ window->context.debug = GLFW_TRUE;
+ else if (glfwExtensionSupported("GL_ARB_debug_output") &&
+ ctxconfig->debug)
+ {
+ // HACK: This is a workaround for older drivers (pre KHR_debug)
+ // not setting the debug bit in the context flags for
+ // debug contexts
+ window->context.debug = GLFW_TRUE;
+ }
+
+ if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
+ window->context.noerror = GLFW_TRUE;
+ }
+
+ // Read back OpenGL context profile (OpenGL 3.2 and above)
+ if (window->context.major >= 4 ||
+ (window->context.major == 3 && window->context.minor >= 2))
+ {
+ GLint mask;
+ window->context.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
+
+ if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
+ window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
+ else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
+ window->context.profile = GLFW_OPENGL_CORE_PROFILE;
+ else if (glfwExtensionSupported("GL_ARB_compatibility"))
+ {
+ // HACK: This is a workaround for the compatibility profile bit
+ // not being set in the context flags if an OpenGL 3.2+
+ // context was created without having requested a specific
+ // version
+ window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
+ }
+ }
+
+ // Read back robustness strategy
+ if (glfwExtensionSupported("GL_ARB_robustness"))
+ {
+ // NOTE: We avoid using the context flags for detection, as they are
+ // only present from 3.0 while the extension applies from 1.1
+
+ GLint strategy;
+ window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
+ &strategy);
+
+ if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
+ window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
+ else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
+ window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
+ }
+ }
+ else
+ {
+ // Read back robustness strategy
+ if (glfwExtensionSupported("GL_EXT_robustness"))
+ {
+ // NOTE: The values of these constants match those of the OpenGL ARB
+ // one, so we can reuse them here
+
+ GLint strategy;
+ window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
+ &strategy);
+
+ if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
+ window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
+ else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
+ window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
+ }
+ }
+
+ if (glfwExtensionSupported("GL_KHR_context_flush_control"))
+ {
+ GLint behavior;
+ window->context.GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);
+
+ if (behavior == GL_NONE)
+ window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;
+ else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)
+ window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
+ }
+
+ // Clearing the front buffer to black to avoid garbage pixels left over from
+ // previous uses of our bit of VRAM
+ {
+ PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
+ window->context.getProcAddress("glClear");
+ glClear(GL_COLOR_BUFFER_BIT);
+ window->context.swapBuffers(window);
+ }
+
+ return GLFW_TRUE;
+}
+
+GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
+{
+ const char* start = extensions;
+
+ for (;;)
+ {
+ const char* where;
+ const char* terminator;
+
+ where = strstr(start, string);
+ if (!where)
+ return GLFW_FALSE;
+
+ terminator = where + strlen(string);
+ if (where == start || *(where - 1) == ' ')
+ {
+ if (*terminator == ' ' || *terminator == '\0')
+ break;
+ }
+
+ start = terminator;
+ }
+
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window && window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return;
+ }
+
+ if (previous)
+ {
+ if (!window || window->context.source != previous->context.source)
+ previous->context.makeCurrent(NULL);
+ }
+
+ if (window)
+ window->context.makeCurrent(window);
+}
+
+GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return _glfwPlatformGetTls(&_glfw.contextSlot);
+}
+
+GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return;
+ }
+
+ window->context.swapBuffers(window);
+}
+
+GLFWAPI void glfwSwapInterval(int interval)
+{
+ _GLFWwindow* window;
+
+ _GLFW_REQUIRE_INIT();
+
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ if (!window)
+ {
+ _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
+ return;
+ }
+
+ window->context.swapInterval(interval);
+}
+
+GLFWAPI int glfwExtensionSupported(const char* extension)
+{
+ _GLFWwindow* window;
+ assert(extension != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ if (!window)
+ {
+ _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
+ return GLFW_FALSE;
+ }
+
+ if (*extension == '\0')
+ {
+ _glfwInputError(GLFW_INVALID_VALUE, "Extension name is empty string");
+ return GLFW_FALSE;
+ }
+
+ if (window->context.major >= 3)
+ {
+ int i;
+ GLint count;
+
+ // Check if extension is in the modern OpenGL extensions string list
+
+ window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count);
+
+ for (i = 0; i < count; i++)
+ {
+ const char* en = (const char*)
+ window->context.GetStringi(GL_EXTENSIONS, i);
+ if (!en)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Extension string retrieval is broken");
+ return GLFW_FALSE;
+ }
+
+ if (strcmp(en, extension) == 0)
+ return GLFW_TRUE;
+ }
+ }
+ else
+ {
+ // Check if extension is in the old style OpenGL extensions string
+
+ const char* extensions = (const char*)
+ window->context.GetString(GL_EXTENSIONS);
+ if (!extensions)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Extension string retrieval is broken");
+ return GLFW_FALSE;
+ }
+
+ if (_glfwStringInExtensionString(extension, extensions))
+ return GLFW_TRUE;
+ }
+
+ // Check if extension is in the platform-specific string
+ return window->context.extensionSupported(extension);
+}
+
+GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
+{
+ _GLFWwindow* window;
+ assert(procname != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ if (!window)
+ {
+ _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
+ return NULL;
+ }
+
+ return window->context.getProcAddress(procname);
+}
+
diff --git a/src/external/glfw/src/egl_context.c b/src/external/glfw/src/egl_context.c
new file mode 100644
index 00000000..b2d11a47
--- /dev/null
+++ b/src/external/glfw/src/egl_context.c
@@ -0,0 +1,786 @@
+//========================================================================
+// GLFW 3.3 EGL - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+
+// Return a description of the specified EGL error
+//
+static const char* getEGLErrorString(EGLint error)
+{
+ switch (error)
+ {
+ case EGL_SUCCESS:
+ return "Success";
+ case EGL_NOT_INITIALIZED:
+ return "EGL is not or could not be initialized";
+ case EGL_BAD_ACCESS:
+ return "EGL cannot access a requested resource";
+ case EGL_BAD_ALLOC:
+ return "EGL failed to allocate resources for the requested operation";
+ case EGL_BAD_ATTRIBUTE:
+ return "An unrecognized attribute or attribute value was passed in the attribute list";
+ case EGL_BAD_CONTEXT:
+ return "An EGLContext argument does not name a valid EGL rendering context";
+ case EGL_BAD_CONFIG:
+ return "An EGLConfig argument does not name a valid EGL frame buffer configuration";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";
+ case EGL_BAD_DISPLAY:
+ return "An EGLDisplay argument does not name a valid EGL display connection";
+ case EGL_BAD_SURFACE:
+ return "An EGLSurface argument does not name a valid surface configured for GL rendering";
+ case EGL_BAD_MATCH:
+ return "Arguments are inconsistent";
+ case EGL_BAD_PARAMETER:
+ return "One or more argument values are invalid";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "A NativePixmapType argument does not refer to a valid native pixmap";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "A NativeWindowType argument does not refer to a valid native window";
+ case EGL_CONTEXT_LOST:
+ return "The application must destroy all contexts and reinitialise";
+ default:
+ return "ERROR: UNKNOWN EGL ERROR";
+ }
+}
+
+// Returns the specified attribute of the specified EGLConfig
+//
+static int getEGLConfigAttrib(EGLConfig config, int attrib)
+{
+ int value;
+ eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
+ return value;
+}
+
+// Return the EGLConfig most closely matching the specified hints
+//
+static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* desired,
+ EGLConfig* result)
+{
+ EGLConfig* nativeConfigs;
+ _GLFWfbconfig* usableConfigs;
+ const _GLFWfbconfig* closest;
+ int i, nativeCount, usableCount;
+
+ eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
+ if (!nativeCount)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
+ return GLFW_FALSE;
+ }
+
+ nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
+ eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
+
+ usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
+ usableCount = 0;
+
+ for (i = 0; i < nativeCount; i++)
+ {
+ const EGLConfig n = nativeConfigs[i];
+ _GLFWfbconfig* u = usableConfigs + usableCount;
+
+ // Only consider RGB(A) EGLConfigs
+ if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
+ continue;
+
+ // Only consider window EGLConfigs
+ if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
+ continue;
+
+#if defined(_GLFW_X11)
+ XVisualInfo vi = {0};
+
+ // Only consider EGLConfigs with associated Visuals
+ vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
+ if (!vi.visualid)
+ continue;
+
+ if (desired->transparent)
+ {
+ int count;
+ XVisualInfo* vis = XGetVisualInfo(_glfw.x11.display,
+ VisualIDMask, &vi,
+ &count);
+ if (vis)
+ {
+ u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
+ XFree(vis);
+ }
+ }
+#endif // _GLFW_X11
+
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ if (ctxconfig->major == 1)
+ {
+ if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
+ continue;
+ }
+ else
+ {
+ if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
+ continue;
+ }
+ }
+ else if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
+ continue;
+ }
+
+ u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
+ u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
+ u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
+
+ u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
+ u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
+ u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
+
+ u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
+ u->doublebuffer = GLFW_TRUE;
+
+ u->handle = (uintptr_t) n;
+ usableCount++;
+ }
+
+ closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
+ if (closest)
+ *result = (EGLConfig) closest->handle;
+
+ free(nativeConfigs);
+ free(usableConfigs);
+
+ return closest != NULL;
+}
+
+static void makeContextCurrentEGL(_GLFWwindow* window)
+{
+ if (window)
+ {
+ if (!eglMakeCurrent(_glfw.egl.display,
+ window->context.egl.surface,
+ window->context.egl.surface,
+ window->context.egl.handle))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "EGL: Failed to make context current: %s",
+ getEGLErrorString(eglGetError()));
+ return;
+ }
+ }
+ else
+ {
+ if (!eglMakeCurrent(_glfw.egl.display,
+ EGL_NO_SURFACE,
+ EGL_NO_SURFACE,
+ EGL_NO_CONTEXT))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "EGL: Failed to clear current context: %s",
+ getEGLErrorString(eglGetError()));
+ return;
+ }
+ }
+
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
+}
+
+static void swapBuffersEGL(_GLFWwindow* window)
+{
+ if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "EGL: The context must be current on the calling thread when swapping buffers");
+ return;
+ }
+
+ eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
+}
+
+static void swapIntervalEGL(int interval)
+{
+ eglSwapInterval(_glfw.egl.display, interval);
+}
+
+static int extensionSupportedEGL(const char* extension)
+{
+ const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
+ if (extensions)
+ {
+ if (_glfwStringInExtensionString(extension, extensions))
+ return GLFW_TRUE;
+ }
+
+ return GLFW_FALSE;
+}
+
+static GLFWglproc getProcAddressEGL(const char* procname)
+{
+ _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
+
+ if (window->context.egl.client)
+ {
+ GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
+ procname);
+ if (proc)
+ return proc;
+ }
+
+ return eglGetProcAddress(procname);
+}
+
+static void destroyContextEGL(_GLFWwindow* window)
+{
+#if defined(_GLFW_X11)
+ // NOTE: Do not unload libGL.so.1 while the X11 display is still open,
+ // as it will make XCloseDisplay segfault
+ if (window->context.client != GLFW_OPENGL_API)
+#endif // _GLFW_X11
+ {
+ if (window->context.egl.client)
+ {
+ _glfw_dlclose(window->context.egl.client);
+ window->context.egl.client = NULL;
+ }
+ }
+
+ if (window->context.egl.surface)
+ {
+ eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
+ window->context.egl.surface = EGL_NO_SURFACE;
+ }
+
+ if (window->context.egl.handle)
+ {
+ eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
+ window->context.egl.handle = EGL_NO_CONTEXT;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize EGL
+//
+GLFWbool _glfwInitEGL(void)
+{
+ int i;
+ const char* sonames[] =
+ {
+#if defined(_GLFW_EGL_LIBRARY)
+ _GLFW_EGL_LIBRARY,
+#elif defined(_GLFW_WIN32)
+ "libEGL.dll",
+ "EGL.dll",
+#elif defined(_GLFW_COCOA)
+ "libEGL.dylib",
+#elif defined(__CYGWIN__)
+ "libEGL-1.so",
+#else
+ "libEGL.so.1",
+#endif
+ NULL
+ };
+
+ if (_glfw.egl.handle)
+ return GLFW_TRUE;
+
+ for (i = 0; sonames[i]; i++)
+ {
+ _glfw.egl.handle = _glfw_dlopen(sonames[i]);
+ if (_glfw.egl.handle)
+ break;
+ }
+
+ if (!_glfw.egl.handle)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
+ return GLFW_FALSE;
+ }
+
+ _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
+
+ _glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
+ _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
+ _glfw.egl.GetConfigs = (PFN_eglGetConfigs)
+ _glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
+ _glfw.egl.GetDisplay = (PFN_eglGetDisplay)
+ _glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
+ _glfw.egl.GetError = (PFN_eglGetError)
+ _glfw_dlsym(_glfw.egl.handle, "eglGetError");
+ _glfw.egl.Initialize = (PFN_eglInitialize)
+ _glfw_dlsym(_glfw.egl.handle, "eglInitialize");
+ _glfw.egl.Terminate = (PFN_eglTerminate)
+ _glfw_dlsym(_glfw.egl.handle, "eglTerminate");
+ _glfw.egl.BindAPI = (PFN_eglBindAPI)
+ _glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
+ _glfw.egl.CreateContext = (PFN_eglCreateContext)
+ _glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
+ _glfw.egl.DestroySurface = (PFN_eglDestroySurface)
+ _glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
+ _glfw.egl.DestroyContext = (PFN_eglDestroyContext)
+ _glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
+ _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
+ _glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
+ _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
+ _glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
+ _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
+ _glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
+ _glfw.egl.SwapInterval = (PFN_eglSwapInterval)
+ _glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
+ _glfw.egl.QueryString = (PFN_eglQueryString)
+ _glfw_dlsym(_glfw.egl.handle, "eglQueryString");
+ _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
+ _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
+
+ if (!_glfw.egl.GetConfigAttrib ||
+ !_glfw.egl.GetConfigs ||
+ !_glfw.egl.GetDisplay ||
+ !_glfw.egl.GetError ||
+ !_glfw.egl.Initialize ||
+ !_glfw.egl.Terminate ||
+ !_glfw.egl.BindAPI ||
+ !_glfw.egl.CreateContext ||
+ !_glfw.egl.DestroySurface ||
+ !_glfw.egl.DestroyContext ||
+ !_glfw.egl.CreateWindowSurface ||
+ !_glfw.egl.MakeCurrent ||
+ !_glfw.egl.SwapBuffers ||
+ !_glfw.egl.SwapInterval ||
+ !_glfw.egl.QueryString ||
+ !_glfw.egl.GetProcAddress)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "EGL: Failed to load required entry points");
+
+ _glfwTerminateEGL();
+ return GLFW_FALSE;
+ }
+
+ _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
+ if (_glfw.egl.display == EGL_NO_DISPLAY)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "EGL: Failed to get EGL display: %s",
+ getEGLErrorString(eglGetError()));
+
+ _glfwTerminateEGL();
+ return GLFW_FALSE;
+ }
+
+ if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "EGL: Failed to initialize EGL: %s",
+ getEGLErrorString(eglGetError()));
+
+ _glfwTerminateEGL();
+ return GLFW_FALSE;
+ }
+
+ _glfw.egl.KHR_create_context =
+ extensionSupportedEGL("EGL_KHR_create_context");
+ _glfw.egl.KHR_create_context_no_error =
+ extensionSupportedEGL("EGL_KHR_create_context_no_error");
+ _glfw.egl.KHR_gl_colorspace =
+ extensionSupportedEGL("EGL_KHR_gl_colorspace");
+ _glfw.egl.KHR_get_all_proc_addresses =
+ extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
+ _glfw.egl.KHR_context_flush_control =
+ extensionSupportedEGL("EGL_KHR_context_flush_control");
+
+ return GLFW_TRUE;
+}
+
+// Terminate EGL
+//
+void _glfwTerminateEGL(void)
+{
+ if (_glfw.egl.display)
+ {
+ eglTerminate(_glfw.egl.display);
+ _glfw.egl.display = EGL_NO_DISPLAY;
+ }
+
+ if (_glfw.egl.handle)
+ {
+ _glfw_dlclose(_glfw.egl.handle);
+ _glfw.egl.handle = NULL;
+ }
+}
+
+#define setAttrib(a, v) \
+{ \
+ assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
+ attribs[index++] = a; \
+ attribs[index++] = v; \
+}
+
+// Create the OpenGL or OpenGL ES context
+//
+GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ EGLint attribs[40];
+ EGLConfig config;
+ EGLContext share = NULL;
+ int index = 0;
+
+ if (!_glfw.egl.display)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->share)
+ share = ctxconfig->share->context.egl.handle;
+
+ if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "EGL: Failed to find a suitable EGLConfig");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "EGL: Failed to bind OpenGL ES: %s",
+ getEGLErrorString(eglGetError()));
+ return GLFW_FALSE;
+ }
+ }
+ else
+ {
+ if (!eglBindAPI(EGL_OPENGL_API))
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "EGL: Failed to bind OpenGL: %s",
+ getEGLErrorString(eglGetError()));
+ return GLFW_FALSE;
+ }
+ }
+
+ if (_glfw.egl.KHR_create_context)
+ {
+ int mask = 0, flags = 0;
+
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if (ctxconfig->forward)
+ flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+
+ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
+ mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
+ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
+ mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
+ }
+
+ if (ctxconfig->debug)
+ flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+
+ if (ctxconfig->robustness)
+ {
+ if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
+ {
+ setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
+ EGL_NO_RESET_NOTIFICATION_KHR);
+ }
+ else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
+ {
+ setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
+ EGL_LOSE_CONTEXT_ON_RESET_KHR);
+ }
+
+ flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+ }
+
+ if (ctxconfig->noerror)
+ {
+ if (_glfw.egl.KHR_create_context_no_error)
+ setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
+ }
+
+ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
+ {
+ setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
+ setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
+ }
+
+ if (mask)
+ setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
+
+ if (flags)
+ setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
+ }
+ else
+ {
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
+ }
+
+ if (_glfw.egl.KHR_context_flush_control)
+ {
+ if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
+ {
+ setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
+ EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
+ }
+ else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
+ {
+ setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
+ EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
+ }
+ }
+
+ setAttrib(EGL_NONE, EGL_NONE);
+
+ window->context.egl.handle = eglCreateContext(_glfw.egl.display,
+ config, share, attribs);
+
+ if (window->context.egl.handle == EGL_NO_CONTEXT)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "EGL: Failed to create context: %s",
+ getEGLErrorString(eglGetError()));
+ return GLFW_FALSE;
+ }
+
+ // Set up attributes for surface creation
+ {
+ int index = 0;
+
+ if (fbconfig->sRGB)
+ {
+ if (_glfw.egl.KHR_gl_colorspace)
+ setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
+ }
+
+ setAttrib(EGL_NONE, EGL_NONE);
+ }
+
+ window->context.egl.surface =
+ eglCreateWindowSurface(_glfw.egl.display,
+ config,
+ _GLFW_EGL_NATIVE_WINDOW,
+ attribs);
+ if (window->context.egl.surface == EGL_NO_SURFACE)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "EGL: Failed to create window surface: %s",
+ getEGLErrorString(eglGetError()));
+ return GLFW_FALSE;
+ }
+
+ window->context.egl.config = config;
+
+ // Load the appropriate client library
+ if (!_glfw.egl.KHR_get_all_proc_addresses)
+ {
+ int i;
+ const char** sonames;
+ const char* es1sonames[] =
+ {
+#if defined(_GLFW_GLESV1_LIBRARY)
+ _GLFW_GLESV1_LIBRARY,
+#elif defined(_GLFW_WIN32)
+ "GLESv1_CM.dll",
+ "libGLES_CM.dll",
+#elif defined(_GLFW_COCOA)
+ "libGLESv1_CM.dylib",
+#else
+ "libGLESv1_CM.so.1",
+ "libGLES_CM.so.1",
+#endif
+ NULL
+ };
+ const char* es2sonames[] =
+ {
+#if defined(_GLFW_GLESV2_LIBRARY)
+ _GLFW_GLESV2_LIBRARY,
+#elif defined(_GLFW_WIN32)
+ "GLESv2.dll",
+ "libGLESv2.dll",
+#elif defined(_GLFW_COCOA)
+ "libGLESv2.dylib",
+#elif defined(__CYGWIN__)
+ "libGLESv2-2.so",
+#else
+ "libGLESv2.so.2",
+#endif
+ NULL
+ };
+ const char* glsonames[] =
+ {
+#if defined(_GLFW_OPENGL_LIBRARY)
+ _GLFW_OPENGL_LIBRARY,
+#elif defined(_GLFW_WIN32)
+#elif defined(_GLFW_COCOA)
+#else
+ "libGL.so.1",
+#endif
+ NULL
+ };
+
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ if (ctxconfig->major == 1)
+ sonames = es1sonames;
+ else
+ sonames = es2sonames;
+ }
+ else
+ sonames = glsonames;
+
+ for (i = 0; sonames[i]; i++)
+ {
+ // HACK: Match presence of lib prefix to increase chance of finding
+ // a matching pair in the jungle that is Win32 EGL/GLES
+ if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
+ continue;
+
+ window->context.egl.client = _glfw_dlopen(sonames[i]);
+ if (window->context.egl.client)
+ break;
+ }
+
+ if (!window->context.egl.client)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "EGL: Failed to load client library");
+ return GLFW_FALSE;
+ }
+ }
+
+ window->context.makeCurrent = makeContextCurrentEGL;
+ window->context.swapBuffers = swapBuffersEGL;
+ window->context.swapInterval = swapIntervalEGL;
+ window->context.extensionSupported = extensionSupportedEGL;
+ window->context.getProcAddress = getProcAddressEGL;
+ window->context.destroy = destroyContextEGL;
+
+ return GLFW_TRUE;
+}
+
+#undef setAttrib
+
+// Returns the Visual and depth of the chosen EGLConfig
+//
+#if defined(_GLFW_X11)
+GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig,
+ Visual** visual, int* depth)
+{
+ XVisualInfo* result;
+ XVisualInfo desired;
+ EGLConfig native;
+ EGLint visualID = 0, count = 0;
+ const long vimask = VisualScreenMask | VisualIDMask;
+
+ if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "EGL: Failed to find a suitable EGLConfig");
+ return GLFW_FALSE;
+ }
+
+ eglGetConfigAttrib(_glfw.egl.display, native,
+ EGL_NATIVE_VISUAL_ID, &visualID);
+
+ desired.screen = _glfw.x11.screen;
+ desired.visualid = visualID;
+
+ result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count);
+ if (!result)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "EGL: Failed to retrieve Visual for EGLConfig");
+ return GLFW_FALSE;
+ }
+
+ *visual = result->visual;
+ *depth = result->depth;
+
+ XFree(result);
+ return GLFW_TRUE;
+}
+#endif // _GLFW_X11
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY);
+ return _glfw.egl.display;
+}
+
+GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return EGL_NO_CONTEXT;
+ }
+
+ return window->context.egl.handle;
+}
+
+GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return EGL_NO_SURFACE;
+ }
+
+ return window->context.egl.surface;
+}
+
diff --git a/src/external/glfw/src/egl_context.h b/src/external/glfw/src/egl_context.h
new file mode 100644
index 00000000..aa339baa
--- /dev/null
+++ b/src/external/glfw/src/egl_context.h
@@ -0,0 +1,219 @@
+//========================================================================
+// GLFW 3.3 EGL - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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;
+#elif defined(_GLFW_MIR)
+ #define EGLAPIENTRY
+typedef MirEGLNativeDisplayType EGLNativeDisplayType;
+typedef MirEGLNativeWindowType 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*/
+
diff --git a/src/external/glfw/src/glfw3.pc.in b/src/external/glfw/src/glfw3.pc.in
new file mode 100644
index 00000000..f2e4d976
--- /dev/null
+++ b/src/external/glfw/src/glfw3.pc.in
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib@LIB_SUFFIX@
+
+Name: GLFW
+Description: A multi-platform library for OpenGL, window and input
+Version: @GLFW_VERSION_FULL@
+URL: http://www.glfw.org/
+Requires.private: @GLFW_PKG_DEPS@
+Libs: -L${libdir} -l@GLFW_LIB_NAME@
+Libs.private: @GLFW_PKG_LIBS@
+Cflags: -I${includedir}
diff --git a/src/external/glfw/src/glfw3Config.cmake.in b/src/external/glfw/src/glfw3Config.cmake.in
new file mode 100644
index 00000000..1fa200e2
--- /dev/null
+++ b/src/external/glfw/src/glfw3Config.cmake.in
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
diff --git a/src/external/glfw/src/glfw_config.h.in b/src/external/glfw/src/glfw_config.h.in
new file mode 100644
index 00000000..bc9f5d3e
--- /dev/null
+++ b/src/external/glfw/src/glfw_config.h.in
@@ -0,0 +1,57 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2010-2016 Camilla Löwy <[email protected]>
+//
+// 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 Mir
+#cmakedefine _GLFW_MIR
+// 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
+
diff --git a/src/external/glfw/src/glx_context.c b/src/external/glfw/src/glx_context.c
new file mode 100644
index 00000000..708663a9
--- /dev/null
+++ b/src/external/glfw/src/glx_context.c
@@ -0,0 +1,698 @@
+//========================================================================
+// GLFW 3.3 GLX - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifndef GLXBadProfileARB
+ #define GLXBadProfileARB 13
+#endif
+
+
+// Returns the specified attribute of the specified GLXFBConfig
+//
+static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
+{
+ int value;
+ glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
+ return value;
+}
+
+// Return the GLXFBConfig most closely matching the specified hints
+//
+static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
+ GLXFBConfig* result)
+{
+ GLXFBConfig* nativeConfigs;
+ _GLFWfbconfig* usableConfigs;
+ const _GLFWfbconfig* closest;
+ int i, nativeCount, usableCount;
+ const char* vendor;
+ GLFWbool trustWindowBit = GLFW_TRUE;
+
+ // HACK: This is a (hopefully temporary) workaround for Chromium
+ // (VirtualBox GL) not setting the window bit on any GLXFBConfigs
+ vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
+ if (vendor && strcmp(vendor, "Chromium") == 0)
+ trustWindowBit = GLFW_FALSE;
+
+ nativeConfigs =
+ glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
+ if (!nativeConfigs || !nativeCount)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
+ return GLFW_FALSE;
+ }
+
+ usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
+ usableCount = 0;
+
+ for (i = 0; i < nativeCount; i++)
+ {
+ const GLXFBConfig n = nativeConfigs[i];
+ _GLFWfbconfig* u = usableConfigs + usableCount;
+
+ // Only consider RGBA GLXFBConfigs
+ if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
+ continue;
+
+ // Only consider window GLXFBConfigs
+ if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
+ {
+ if (trustWindowBit)
+ continue;
+ }
+
+ if (desired->transparent)
+ {
+ XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
+ if (vi)
+ {
+ u->transparent = _glfwIsVisualTransparentX11(vi->visual);
+ XFree(vi);
+ }
+ }
+
+ u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
+ u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
+ u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
+
+ u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
+ u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
+ u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
+
+ u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
+ u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
+ u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
+ u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
+
+ u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
+
+ if (getGLXFBConfigAttrib(n, GLX_STEREO))
+ u->stereo = GLFW_TRUE;
+ if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
+ u->doublebuffer = GLFW_TRUE;
+
+ if (_glfw.glx.ARB_multisample)
+ u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
+
+ if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
+ u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
+
+ u->handle = (uintptr_t) n;
+ usableCount++;
+ }
+
+ closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
+ if (closest)
+ *result = (GLXFBConfig) closest->handle;
+
+ XFree(nativeConfigs);
+ free(usableConfigs);
+
+ return closest != NULL;
+}
+
+// Create the OpenGL context using legacy API
+//
+static GLXContext createLegacyContextGLX(_GLFWwindow* window,
+ GLXFBConfig fbconfig,
+ GLXContext share)
+{
+ return glXCreateNewContext(_glfw.x11.display,
+ fbconfig,
+ GLX_RGBA_TYPE,
+ share,
+ True);
+}
+
+static void makeContextCurrentGLX(_GLFWwindow* window)
+{
+ if (window)
+ {
+ if (!glXMakeCurrent(_glfw.x11.display,
+ window->context.glx.window,
+ window->context.glx.handle))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "GLX: Failed to make context current");
+ return;
+ }
+ }
+ else
+ {
+ if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "GLX: Failed to clear current context");
+ return;
+ }
+ }
+
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
+}
+
+static void swapBuffersGLX(_GLFWwindow* window)
+{
+ glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
+}
+
+static void swapIntervalGLX(int interval)
+{
+ _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
+
+ if (_glfw.glx.EXT_swap_control)
+ {
+ _glfw.glx.SwapIntervalEXT(_glfw.x11.display,
+ window->context.glx.window,
+ interval);
+ }
+ else if (_glfw.glx.MESA_swap_control)
+ _glfw.glx.SwapIntervalMESA(interval);
+ else if (_glfw.glx.SGI_swap_control)
+ {
+ if (interval > 0)
+ _glfw.glx.SwapIntervalSGI(interval);
+ }
+}
+
+static int extensionSupportedGLX(const char* extension)
+{
+ const char* extensions =
+ glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
+ if (extensions)
+ {
+ if (_glfwStringInExtensionString(extension, extensions))
+ return GLFW_TRUE;
+ }
+
+ return GLFW_FALSE;
+}
+
+static GLFWglproc getProcAddressGLX(const char* procname)
+{
+ if (_glfw.glx.GetProcAddress)
+ return _glfw.glx.GetProcAddress((const GLubyte*) procname);
+ else if (_glfw.glx.GetProcAddressARB)
+ return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
+ else
+ return dlsym(_glfw.glx.handle, procname);
+}
+
+// Destroy the OpenGL context
+//
+static void destroyContextGLX(_GLFWwindow* window)
+{
+ if (window->context.glx.window)
+ {
+ glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
+ window->context.glx.window = None;
+ }
+
+ if (window->context.glx.handle)
+ {
+ glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
+ window->context.glx.handle = NULL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize GLX
+//
+GLFWbool _glfwInitGLX(void)
+{
+ int i;
+ const char* sonames[] =
+ {
+#if defined(_GLFW_GLX_LIBRARY)
+ _GLFW_GLX_LIBRARY,
+#elif defined(__CYGWIN__)
+ "libGL-1.so",
+#else
+ "libGL.so.1",
+ "libGL.so",
+#endif
+ NULL
+ };
+
+ if (_glfw.glx.handle)
+ return GLFW_TRUE;
+
+ for (i = 0; sonames[i]; i++)
+ {
+ _glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.glx.handle)
+ break;
+ }
+
+ if (!_glfw.glx.handle)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
+ return GLFW_FALSE;
+ }
+
+ _glfw.glx.GetFBConfigs =
+ dlsym(_glfw.glx.handle, "glXGetFBConfigs");
+ _glfw.glx.GetFBConfigAttrib =
+ dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
+ _glfw.glx.GetClientString =
+ dlsym(_glfw.glx.handle, "glXGetClientString");
+ _glfw.glx.QueryExtension =
+ dlsym(_glfw.glx.handle, "glXQueryExtension");
+ _glfw.glx.QueryVersion =
+ dlsym(_glfw.glx.handle, "glXQueryVersion");
+ _glfw.glx.DestroyContext =
+ dlsym(_glfw.glx.handle, "glXDestroyContext");
+ _glfw.glx.MakeCurrent =
+ dlsym(_glfw.glx.handle, "glXMakeCurrent");
+ _glfw.glx.SwapBuffers =
+ dlsym(_glfw.glx.handle, "glXSwapBuffers");
+ _glfw.glx.QueryExtensionsString =
+ dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
+ _glfw.glx.CreateNewContext =
+ dlsym(_glfw.glx.handle, "glXCreateNewContext");
+ _glfw.glx.CreateWindow =
+ dlsym(_glfw.glx.handle, "glXCreateWindow");
+ _glfw.glx.DestroyWindow =
+ dlsym(_glfw.glx.handle, "glXDestroyWindow");
+ _glfw.glx.GetProcAddress =
+ dlsym(_glfw.glx.handle, "glXGetProcAddress");
+ _glfw.glx.GetProcAddressARB =
+ dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
+ _glfw.glx.GetVisualFromFBConfig =
+ dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
+
+ if (!_glfw.glx.GetFBConfigs ||
+ !_glfw.glx.GetFBConfigAttrib ||
+ !_glfw.glx.GetClientString ||
+ !_glfw.glx.QueryExtension ||
+ !_glfw.glx.QueryVersion ||
+ !_glfw.glx.DestroyContext ||
+ !_glfw.glx.MakeCurrent ||
+ !_glfw.glx.SwapBuffers ||
+ !_glfw.glx.QueryExtensionsString ||
+ !_glfw.glx.CreateNewContext ||
+ !_glfw.glx.CreateWindow ||
+ !_glfw.glx.DestroyWindow ||
+ !_glfw.glx.GetProcAddress ||
+ !_glfw.glx.GetProcAddressARB ||
+ !_glfw.glx.GetVisualFromFBConfig)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "GLX: Failed to load required entry points");
+ return GLFW_FALSE;
+ }
+
+ if (!glXQueryExtension(_glfw.x11.display,
+ &_glfw.glx.errorBase,
+ &_glfw.glx.eventBase))
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
+ return GLFW_FALSE;
+ }
+
+ if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "GLX: Failed to query GLX version");
+ return GLFW_FALSE;
+ }
+
+ if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "GLX: GLX version 1.3 is required");
+ return GLFW_FALSE;
+ }
+
+ if (extensionSupportedGLX("GLX_EXT_swap_control"))
+ {
+ _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
+ getProcAddressGLX("glXSwapIntervalEXT");
+
+ if (_glfw.glx.SwapIntervalEXT)
+ _glfw.glx.EXT_swap_control = GLFW_TRUE;
+ }
+
+ if (extensionSupportedGLX("GLX_SGI_swap_control"))
+ {
+ _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
+ getProcAddressGLX("glXSwapIntervalSGI");
+
+ if (_glfw.glx.SwapIntervalSGI)
+ _glfw.glx.SGI_swap_control = GLFW_TRUE;
+ }
+
+ if (extensionSupportedGLX("GLX_MESA_swap_control"))
+ {
+ _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
+ getProcAddressGLX("glXSwapIntervalMESA");
+
+ if (_glfw.glx.SwapIntervalMESA)
+ _glfw.glx.MESA_swap_control = GLFW_TRUE;
+ }
+
+ if (extensionSupportedGLX("GLX_ARB_multisample"))
+ _glfw.glx.ARB_multisample = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
+ _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
+ _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_ARB_create_context"))
+ {
+ _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+ getProcAddressGLX("glXCreateContextAttribsARB");
+
+ if (_glfw.glx.CreateContextAttribsARB)
+ _glfw.glx.ARB_create_context = GLFW_TRUE;
+ }
+
+ if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
+ _glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
+ _glfw.glx.ARB_create_context_profile = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
+ _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
+ _glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
+
+ if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
+ _glfw.glx.ARB_context_flush_control = GLFW_TRUE;
+
+ return GLFW_TRUE;
+}
+
+// Terminate GLX
+//
+void _glfwTerminateGLX(void)
+{
+ // NOTE: This function must not call any X11 functions, as it is called
+ // after XCloseDisplay (see _glfwPlatformTerminate for details)
+
+ if (_glfw.glx.handle)
+ {
+ dlclose(_glfw.glx.handle);
+ _glfw.glx.handle = NULL;
+ }
+}
+
+#define setAttrib(a, v) \
+{ \
+ assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
+ attribs[index++] = a; \
+ attribs[index++] = v; \
+}
+
+// Create the OpenGL or OpenGL ES context
+//
+GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ int attribs[40];
+ GLXFBConfig native = NULL;
+ GLXContext share = NULL;
+
+ if (ctxconfig->share)
+ share = ctxconfig->share->context.glx.handle;
+
+ if (!chooseGLXFBConfig(fbconfig, &native))
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "GLX: Failed to find a suitable GLXFBConfig");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ if (!_glfw.glx.ARB_create_context ||
+ !_glfw.glx.ARB_create_context_profile ||
+ !_glfw.glx.EXT_create_context_es2_profile)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->forward)
+ {
+ if (!_glfw.glx.ARB_create_context)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->profile)
+ {
+ if (!_glfw.glx.ARB_create_context ||
+ !_glfw.glx.ARB_create_context_profile)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
+ return GLFW_FALSE;
+ }
+ }
+
+ _glfwGrabErrorHandlerX11();
+
+ if (_glfw.glx.ARB_create_context)
+ {
+ int index = 0, mask = 0, flags = 0;
+
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if (ctxconfig->forward)
+ flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+
+ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
+ mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
+ mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ }
+ else
+ mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
+
+ if (ctxconfig->debug)
+ flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
+
+ if (ctxconfig->robustness)
+ {
+ if (_glfw.glx.ARB_create_context_robustness)
+ {
+ if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
+ {
+ setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+ GLX_NO_RESET_NOTIFICATION_ARB);
+ }
+ else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
+ {
+ setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+ GLX_LOSE_CONTEXT_ON_RESET_ARB);
+ }
+
+ flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
+ }
+ }
+
+ if (ctxconfig->release)
+ {
+ if (_glfw.glx.ARB_context_flush_control)
+ {
+ if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
+ {
+ setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
+ GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
+ }
+ else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
+ {
+ setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
+ GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
+ }
+ }
+ }
+
+ if (ctxconfig->noerror)
+ {
+ if (_glfw.glx.ARB_create_context_no_error)
+ setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
+ }
+
+ // NOTE: Only request an explicitly versioned context when necessary, as
+ // explicitly requesting version 1.0 does not always return the
+ // highest version supported by the driver
+ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
+ {
+ setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
+ setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
+ }
+
+ if (mask)
+ setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
+
+ if (flags)
+ setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
+
+ setAttrib(None, None);
+
+ window->context.glx.handle =
+ _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
+ native,
+ share,
+ True,
+ attribs);
+
+ // HACK: This is a fallback for broken versions of the Mesa
+ // implementation of GLX_ARB_create_context_profile that fail
+ // default 1.0 context creation with a GLXBadProfileARB error in
+ // violation of the extension spec
+ if (!window->context.glx.handle)
+ {
+ if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
+ ctxconfig->client == GLFW_OPENGL_API &&
+ ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
+ ctxconfig->forward == GLFW_FALSE)
+ {
+ window->context.glx.handle =
+ createLegacyContextGLX(window, native, share);
+ }
+ }
+ }
+ else
+ {
+ window->context.glx.handle =
+ createLegacyContextGLX(window, native, share);
+ }
+
+ _glfwReleaseErrorHandlerX11();
+
+ if (!window->context.glx.handle)
+ {
+ _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
+ return GLFW_FALSE;
+ }
+
+ window->context.glx.window =
+ glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
+ if (!window->context.glx.window)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
+ return GLFW_FALSE;
+ }
+
+ window->context.makeCurrent = makeContextCurrentGLX;
+ window->context.swapBuffers = swapBuffersGLX;
+ window->context.swapInterval = swapIntervalGLX;
+ window->context.extensionSupported = extensionSupportedGLX;
+ window->context.getProcAddress = getProcAddressGLX;
+ window->context.destroy = destroyContextGLX;
+
+ return GLFW_TRUE;
+}
+
+#undef setAttrib
+
+// Returns the Visual and depth of the chosen GLXFBConfig
+//
+GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig,
+ Visual** visual, int* depth)
+{
+ GLXFBConfig native;
+ XVisualInfo* result;
+
+ if (!chooseGLXFBConfig(fbconfig, &native))
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "GLX: Failed to find a suitable GLXFBConfig");
+ return GLFW_FALSE;
+ }
+
+ result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
+ if (!result)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "GLX: Failed to retrieve Visual for GLXFBConfig");
+ return GLFW_FALSE;
+ }
+
+ *visual = result->visual;
+ *depth = result->depth;
+
+ XFree(result);
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return NULL;
+ }
+
+ return window->context.glx.handle;
+}
+
+GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(None);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return None;
+ }
+
+ return window->context.glx.window;
+}
+
diff --git a/src/external/glfw/src/glx_context.h b/src/external/glfw/src/glx_context.h
new file mode 100644
index 00000000..f767cb14
--- /dev/null
+++ b/src/external/glfw/src/glx_context.h
@@ -0,0 +1,181 @@
+//========================================================================
+// GLFW 3.3 GLX - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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);
+
diff --git a/src/external/glfw/src/init.c b/src/external/glfw/src/init.c
new file mode 100644
index 00000000..19a13e0d
--- /dev/null
+++ b/src/external/glfw/src/init.c
@@ -0,0 +1,317 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+#include "mappings.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+
+// The global variables below comprise all global data in GLFW.
+// Any other global variable is a bug.
+
+// Global state shared between compilation units of GLFW
+//
+_GLFWlibrary _glfw = { GLFW_FALSE };
+
+// These are outside of _glfw so they can be used before initialization and
+// after termination
+//
+static _GLFWerror _glfwMainThreadError;
+static GLFWerrorfun _glfwErrorCallback;
+static _GLFWinitconfig _glfwInitHints =
+{
+ GLFW_TRUE, // hat buttons
+ {
+ GLFW_TRUE, // macOS menu bar
+ GLFW_TRUE // macOS bundle chdir
+ },
+ {
+ "", // X11 WM_CLASS name
+ "" // X11 WM_CLASS class
+ }
+};
+
+// Returns a generic string representation of the specified error
+//
+static const char* getErrorString(int code)
+{
+ switch (code)
+ {
+ case GLFW_NOT_INITIALIZED:
+ return "The GLFW library is not initialized";
+ case GLFW_NO_CURRENT_CONTEXT:
+ return "There is no current context";
+ case GLFW_INVALID_ENUM:
+ return "Invalid argument for enum parameter";
+ case GLFW_INVALID_VALUE:
+ return "Invalid value for parameter";
+ case GLFW_OUT_OF_MEMORY:
+ return "Out of memory";
+ case GLFW_API_UNAVAILABLE:
+ return "The requested API is unavailable";
+ case GLFW_VERSION_UNAVAILABLE:
+ return "The requested API version is unavailable";
+ case GLFW_PLATFORM_ERROR:
+ return "An undocumented platform-specific error occurred";
+ case GLFW_FORMAT_UNAVAILABLE:
+ return "The requested format is unavailable";
+ case GLFW_NO_WINDOW_CONTEXT:
+ return "The specified window has no context";
+ default:
+ return "ERROR: UNKNOWN GLFW ERROR";
+ }
+}
+
+// Terminate the library
+//
+static void terminate(void)
+{
+ int i;
+
+ memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
+
+ while (_glfw.windowListHead)
+ glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
+
+ while (_glfw.cursorListHead)
+ glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead);
+
+ for (i = 0; i < _glfw.monitorCount; i++)
+ {
+ _GLFWmonitor* monitor = _glfw.monitors[i];
+ if (monitor->originalRamp.size)
+ _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
+ _glfwFreeMonitor(monitor);
+ }
+
+ free(_glfw.monitors);
+ _glfw.monitors = NULL;
+ _glfw.monitorCount = 0;
+
+ free(_glfw.mappings);
+ _glfw.mappings = NULL;
+ _glfw.mappingCount = 0;
+
+ _glfwTerminateVulkan();
+ _glfwPlatformTerminate();
+
+ _glfw.initialized = GLFW_FALSE;
+
+ while (_glfw.errorListHead)
+ {
+ _GLFWerror* error = _glfw.errorListHead;
+ _glfw.errorListHead = error->next;
+ free(error);
+ }
+
+ _glfwPlatformDestroyTls(&_glfw.contextSlot);
+ _glfwPlatformDestroyTls(&_glfw.errorSlot);
+ _glfwPlatformDestroyMutex(&_glfw.errorLock);
+
+ memset(&_glfw, 0, sizeof(_glfw));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW event API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwInputError(int code, const char* format, ...)
+{
+ _GLFWerror* error;
+ char description[_GLFW_MESSAGE_SIZE];
+
+ if (format)
+ {
+ va_list vl;
+
+ va_start(vl, format);
+ vsnprintf(description, sizeof(description), format, vl);
+ va_end(vl);
+
+ description[sizeof(description) - 1] = '\0';
+ }
+ else
+ strcpy(description, getErrorString(code));
+
+ if (_glfw.initialized)
+ {
+ error = _glfwPlatformGetTls(&_glfw.errorSlot);
+ if (!error)
+ {
+ error = calloc(1, sizeof(_GLFWerror));
+ _glfwPlatformSetTls(&_glfw.errorSlot, error);
+ _glfwPlatformLockMutex(&_glfw.errorLock);
+ error->next = _glfw.errorListHead;
+ _glfw.errorListHead = error;
+ _glfwPlatformUnlockMutex(&_glfw.errorLock);
+ }
+ }
+ else
+ error = &_glfwMainThreadError;
+
+ error->code = code;
+ strcpy(error->description, description);
+
+ if (_glfwErrorCallback)
+ _glfwErrorCallback(code, description);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI int glfwInit(void)
+{
+ if (_glfw.initialized)
+ return GLFW_TRUE;
+
+ memset(&_glfw, 0, sizeof(_glfw));
+ _glfw.hints.init = _glfwInitHints;
+
+ if (!_glfwPlatformInit())
+ {
+ terminate();
+ return GLFW_FALSE;
+ }
+
+ if (!_glfwPlatformCreateMutex(&_glfw.errorLock))
+ return GLFW_FALSE;
+ if (!_glfwPlatformCreateTls(&_glfw.errorSlot))
+ return GLFW_FALSE;
+ if (!_glfwPlatformCreateTls(&_glfw.contextSlot))
+ return GLFW_FALSE;
+
+ _glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
+
+ _glfw.initialized = GLFW_TRUE;
+ _glfw.timer.offset = _glfwPlatformGetTimerValue();
+
+ glfwDefaultWindowHints();
+ glfwUpdateGamepadMappings(_glfwDefaultMappings);
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI void glfwTerminate(void)
+{
+ if (!_glfw.initialized)
+ return;
+
+ terminate();
+}
+
+GLFWAPI void glfwInitHint(int hint, int value)
+{
+ switch (hint)
+ {
+ case GLFW_JOYSTICK_HAT_BUTTONS:
+ _glfwInitHints.hatButtons = value;
+ return;
+ case GLFW_COCOA_CHDIR_RESOURCES:
+ _glfwInitHints.ns.chdir = value;
+ return;
+ case GLFW_COCOA_MENUBAR:
+ _glfwInitHints.ns.menubar = value;
+ return;
+ }
+
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid integer type init hint 0x%08X", hint);
+}
+
+GLFWAPI void glfwInitHintString(int hint, const char* value)
+{
+ assert(value != NULL);
+
+ switch (hint)
+ {
+ case GLFW_X11_WM_CLASS_NAME:
+ strncpy(_glfwInitHints.x11.className, value,
+ sizeof(_glfwInitHints.x11.className) - 1);
+ break;
+ case GLFW_X11_WM_CLASS_CLASS:
+ strncpy(_glfwInitHints.x11.classClass, value,
+ sizeof(_glfwInitHints.x11.classClass) - 1);
+ break;
+ }
+
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid string type init hint 0x%08X", hint);
+}
+
+GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
+{
+ if (major != NULL)
+ *major = GLFW_VERSION_MAJOR;
+ if (minor != NULL)
+ *minor = GLFW_VERSION_MINOR;
+ if (rev != NULL)
+ *rev = GLFW_VERSION_REVISION;
+}
+
+GLFWAPI const char* glfwGetVersionString(void)
+{
+ return _glfwPlatformGetVersionString();
+}
+
+GLFWAPI int glfwGetError(const char** description)
+{
+ _GLFWerror* error;
+ int code = GLFW_NO_ERROR;
+
+ if (description)
+ *description = NULL;
+
+ if (_glfw.initialized)
+ error = _glfwPlatformGetTls(&_glfw.errorSlot);
+ else
+ error = &_glfwMainThreadError;
+
+ if (error)
+ {
+ code = error->code;
+ error->code = GLFW_NO_ERROR;
+ if (description && code)
+ *description = error->description;
+ }
+
+ return code;
+}
+
+GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
+{
+ _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
+ return cbfun;
+}
+
diff --git a/src/external/glfw/src/input.c b/src/external/glfw/src/input.c
new file mode 100644
index 00000000..7d9ff774
--- /dev/null
+++ b/src/external/glfw/src/input.c
@@ -0,0 +1,1151 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+// Internal key state used for sticky keys
+#define _GLFW_STICK 3
+
+// Internal constants for gamepad mapping source types
+#define _GLFW_JOYSTICK_AXIS 1
+#define _GLFW_JOYSTICK_BUTTON 2
+#define _GLFW_JOYSTICK_HATBIT 3
+
+// Finds a mapping based on joystick GUID
+//
+static _GLFWmapping* findMapping(const char* guid)
+{
+ int i;
+
+ for (i = 0; i < _glfw.mappingCount; i++)
+ {
+ if (strcmp(_glfw.mappings[i].guid, guid) == 0)
+ return _glfw.mappings + i;
+ }
+
+ return NULL;
+}
+
+// Parses an SDL_GameControllerDB line and adds it to the mapping list
+//
+static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
+{
+ const char* c = string;
+ size_t i, length;
+ struct
+ {
+ const char* name;
+ _GLFWmapelement* element;
+ } fields[] =
+ {
+ { "platform", NULL },
+ { "a", mapping->buttons + GLFW_GAMEPAD_BUTTON_A },
+ { "b", mapping->buttons + GLFW_GAMEPAD_BUTTON_B },
+ { "x", mapping->buttons + GLFW_GAMEPAD_BUTTON_X },
+ { "y", mapping->buttons + GLFW_GAMEPAD_BUTTON_Y },
+ { "back", mapping->buttons + GLFW_GAMEPAD_BUTTON_BACK },
+ { "start", mapping->buttons + GLFW_GAMEPAD_BUTTON_START },
+ { "guide", mapping->buttons + GLFW_GAMEPAD_BUTTON_GUIDE },
+ { "leftshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_BUMPER },
+ { "rightshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER },
+ { "leftstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_THUMB },
+ { "rightstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB },
+ { "dpup", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_UP },
+ { "dpright", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_RIGHT },
+ { "dpdown", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_DOWN },
+ { "dpleft", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_LEFT },
+ { "lefttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER },
+ { "righttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER },
+ { "leftx", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_X },
+ { "lefty", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_Y },
+ { "rightx", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_X },
+ { "righty", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_Y }
+ };
+
+ length = strcspn(c, ",");
+ if (length != 32 || c[length] != ',')
+ {
+ _glfwInputError(GLFW_INVALID_VALUE, NULL);
+ return GLFW_FALSE;
+ }
+
+ memcpy(mapping->guid, c, length);
+ c += length + 1;
+
+ length = strcspn(c, ",");
+ if (length >= sizeof(mapping->name) || c[length] != ',')
+ {
+ _glfwInputError(GLFW_INVALID_VALUE, NULL);
+ return GLFW_FALSE;
+ }
+
+ memcpy(mapping->name, c, length);
+ c += length + 1;
+
+ while (*c)
+ {
+ for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
+ {
+ length = strlen(fields[i].name);
+ if (strncmp(c, fields[i].name, length) != 0 || c[length] != ':')
+ continue;
+
+ c += length + 1;
+
+ if (fields[i].element)
+ {
+ if (*c == 'a')
+ fields[i].element->type = _GLFW_JOYSTICK_AXIS;
+ else if (*c == 'b')
+ fields[i].element->type = _GLFW_JOYSTICK_BUTTON;
+ else if (*c == 'h')
+ fields[i].element->type = _GLFW_JOYSTICK_HATBIT;
+ else
+ break;
+
+ if (fields[i].element->type == _GLFW_JOYSTICK_HATBIT)
+ {
+ const unsigned int hat = strtoul(c + 1, (char**) &c, 10);
+ const unsigned int bit = strtoul(c + 1, (char**) &c, 10);
+ fields[i].element->value = (hat << 4) | bit;
+ }
+ else
+ fields[i].element->value = (uint8_t) strtoul(c + 1, (char**) &c, 10);
+ }
+ else
+ {
+ length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
+ if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
+ return GLFW_FALSE;
+ }
+
+ break;
+ }
+
+ c += strcspn(c, ",");
+ c += strspn(c, ",");
+ }
+
+ for (i = 0; i < 32; i++)
+ {
+ if (mapping->guid[i] >= 'A' && mapping->guid[i] <= 'F')
+ mapping->guid[i] += 'a' - 'A';
+ }
+
+ _glfwPlatformUpdateGamepadGUID(mapping->guid);
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW event API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods)
+{
+ if (key >= 0 && key <= GLFW_KEY_LAST)
+ {
+ GLFWbool repeated = GLFW_FALSE;
+
+ if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
+ return;
+
+ if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
+ repeated = GLFW_TRUE;
+
+ if (action == GLFW_RELEASE && window->stickyKeys)
+ window->keys[key] = _GLFW_STICK;
+ else
+ window->keys[key] = (char) action;
+
+ if (repeated)
+ action = GLFW_REPEAT;
+ }
+
+ if (window->callbacks.key)
+ window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods);
+}
+
+void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain)
+{
+ if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
+ return;
+
+ if (window->callbacks.charmods)
+ window->callbacks.charmods((GLFWwindow*) window, codepoint, mods);
+
+ if (plain)
+ {
+ if (window->callbacks.character)
+ window->callbacks.character((GLFWwindow*) window, codepoint);
+ }
+}
+
+void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
+{
+ if (window->callbacks.scroll)
+ window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
+}
+
+void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
+{
+ if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
+ return;
+
+ if (action == GLFW_RELEASE && window->stickyMouseButtons)
+ window->mouseButtons[button] = _GLFW_STICK;
+ else
+ window->mouseButtons[button] = (char) action;
+
+ if (window->callbacks.mouseButton)
+ window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
+}
+
+void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
+{
+ if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
+ return;
+
+ window->virtualCursorPosX = xpos;
+ window->virtualCursorPosY = ypos;
+
+ if (window->callbacks.cursorPos)
+ window->callbacks.cursorPos((GLFWwindow*) window, xpos, ypos);
+}
+
+void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
+{
+ if (window->callbacks.cursorEnter)
+ window->callbacks.cursorEnter((GLFWwindow*) window, entered);
+}
+
+void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
+{
+ if (window->callbacks.drop)
+ window->callbacks.drop((GLFWwindow*) window, count, paths);
+}
+
+void _glfwInputJoystick(_GLFWjoystick* js, int event)
+{
+ const int jid = (int) (js - _glfw.joysticks);
+
+ if (_glfw.callbacks.joystick)
+ _glfw.callbacks.joystick(jid, event);
+}
+
+void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
+{
+ js->axes[axis] = value;
+}
+
+void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
+{
+ js->buttons[button] = value;
+}
+
+void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
+{
+ const int base = js->buttonCount + hat * 4;
+
+ js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE;
+ js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE;
+ js->buttons[base + 2] = (value & 0x04) ? GLFW_PRESS : GLFW_RELEASE;
+ js->buttons[base + 3] = (value & 0x08) ? GLFW_PRESS : GLFW_RELEASE;
+
+ js->hats[hat] = value;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+_GLFWjoystick* _glfwAllocJoystick(const char* name,
+ const char* guid,
+ int axisCount,
+ int buttonCount,
+ int hatCount)
+{
+ int jid;
+ _GLFWjoystick* js;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ if (!_glfw.joysticks[jid].present)
+ break;
+ }
+
+ if (jid > GLFW_JOYSTICK_LAST)
+ return NULL;
+
+ js = _glfw.joysticks + jid;
+ js->present = GLFW_TRUE;
+ js->name = strdup(name);
+ js->axes = calloc(axisCount, sizeof(float));
+ js->buttons = calloc(buttonCount + hatCount * 4, 1);
+ js->hats = calloc(hatCount, 1);
+ js->axisCount = axisCount;
+ js->buttonCount = buttonCount;
+ js->hatCount = hatCount;
+ js->mapping = findMapping(guid);
+
+ strcpy(js->guid, guid);
+
+ return js;
+}
+
+void _glfwFreeJoystick(_GLFWjoystick* js)
+{
+ free(js->name);
+ free(js->axes);
+ free(js->buttons);
+ free(js->hats);
+ memset(js, 0, sizeof(_GLFWjoystick));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(0);
+
+ switch (mode)
+ {
+ case GLFW_CURSOR:
+ return window->cursorMode;
+ case GLFW_STICKY_KEYS:
+ return window->stickyKeys;
+ case GLFW_STICKY_MOUSE_BUTTONS:
+ return window->stickyMouseButtons;
+ }
+
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
+ return 0;
+}
+
+GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (mode == GLFW_CURSOR)
+ {
+ if (value != GLFW_CURSOR_NORMAL &&
+ value != GLFW_CURSOR_HIDDEN &&
+ value != GLFW_CURSOR_DISABLED)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM,
+ "Invalid cursor mode 0x%08X",
+ value);
+ return;
+ }
+
+ if (window->cursorMode == value)
+ return;
+
+ window->cursorMode = value;
+
+ _glfwPlatformGetCursorPos(window,
+ &window->virtualCursorPosX,
+ &window->virtualCursorPosY);
+
+ if (_glfwPlatformWindowFocused(window))
+ _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)
+ window->keys[i] = GLFW_RELEASE;
+ }
+ }
+
+ window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
+ }
+ else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
+ {
+ value = value ? GLFW_TRUE : GLFW_FALSE;
+ 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 ? GLFW_TRUE : GLFW_FALSE;
+ }
+ else
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
+}
+
+GLFWAPI const char* glfwGetKeyName(int key, int scancode)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (key != GLFW_KEY_UNKNOWN)
+ {
+ if (key != GLFW_KEY_KP_EQUAL &&
+ (key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
+ (key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))
+ {
+ return NULL;
+ }
+
+ scancode = _glfwPlatformGetKeyScancode(key);
+ }
+
+ return _glfwPlatformGetScancodeName(scancode);
+}
+
+GLFWAPI int glfwGetKeyScancode(int key)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(-1);
+
+ if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
+ return GLFW_RELEASE;
+ }
+
+ return _glfwPlatformGetKeyScancode(key);
+}
+
+GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
+
+ if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
+ return GLFW_RELEASE;
+ }
+
+ if (window->keys[key] == _GLFW_STICK)
+ {
+ // Sticky mode: release key now
+ window->keys[key] = GLFW_RELEASE;
+ return GLFW_PRESS;
+ }
+
+ return (int) window->keys[key];
+}
+
+GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
+
+ if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);
+ return GLFW_RELEASE;
+ }
+
+ if (window->mouseButtons[button] == _GLFW_STICK)
+ {
+ // Sticky mode: release mouse button now
+ window->mouseButtons[button] = GLFW_RELEASE;
+ return GLFW_PRESS;
+ }
+
+ return (int) window->mouseButtons[button];
+}
+
+GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ if (xpos)
+ *xpos = 0;
+ if (ypos)
+ *ypos = 0;
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ {
+ if (xpos)
+ *xpos = window->virtualCursorPosX;
+ if (ypos)
+ *ypos = window->virtualCursorPosY;
+ }
+ else
+ _glfwPlatformGetCursorPos(window, xpos, ypos);
+}
+
+GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
+ ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid cursor position %f %f",
+ xpos, ypos);
+ return;
+ }
+
+ if (!_glfwPlatformWindowFocused(window))
+ return;
+
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ {
+ // Only update the accumulated position if the cursor is disabled
+ window->virtualCursorPosX = xpos;
+ window->virtualCursorPosY = ypos;
+ }
+ else
+ {
+ // Update system cursor position
+ _glfwPlatformSetCursorPos(window, xpos, ypos);
+ }
+}
+
+GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
+{
+ _GLFWcursor* cursor;
+
+ assert(image != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ cursor = calloc(1, sizeof(_GLFWcursor));
+ cursor->next = _glfw.cursorListHead;
+ _glfw.cursorListHead = cursor;
+
+ if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot))
+ {
+ glfwDestroyCursor((GLFWcursor*) cursor);
+ return NULL;
+ }
+
+ return (GLFWcursor*) cursor;
+}
+
+GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
+{
+ _GLFWcursor* cursor;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (shape != GLFW_ARROW_CURSOR &&
+ shape != GLFW_IBEAM_CURSOR &&
+ shape != GLFW_CROSSHAIR_CURSOR &&
+ shape != GLFW_HAND_CURSOR &&
+ shape != GLFW_HRESIZE_CURSOR &&
+ shape != GLFW_VRESIZE_CURSOR)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
+ return NULL;
+ }
+
+ cursor = calloc(1, sizeof(_GLFWcursor));
+ cursor->next = _glfw.cursorListHead;
+ _glfw.cursorListHead = cursor;
+
+ if (!_glfwPlatformCreateStandardCursor(cursor, shape))
+ {
+ glfwDestroyCursor((GLFWcursor*) cursor);
+ return NULL;
+ }
+
+ return (GLFWcursor*) cursor;
+}
+
+GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
+{
+ _GLFWcursor* cursor = (_GLFWcursor*) handle;
+
+ _GLFW_REQUIRE_INIT();
+
+ if (cursor == NULL)
+ return;
+
+ // Make sure the cursor is not being used by any window
+ {
+ _GLFWwindow* window;
+
+ for (window = _glfw.windowListHead; window; window = window->next)
+ {
+ if (window->cursor == cursor)
+ glfwSetCursor((GLFWwindow*) window, NULL);
+ }
+ }
+
+ _glfwPlatformDestroyCursor(cursor);
+
+ // Unlink cursor from global linked list
+ {
+ _GLFWcursor** prev = &_glfw.cursorListHead;
+
+ while (*prev != cursor)
+ prev = &((*prev)->next);
+
+ *prev = cursor->next;
+ }
+
+ free(cursor);
+}
+
+GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) windowHandle;
+ _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ window->cursor = cursor;
+
+ _glfwPlatformSetCursor(window, cursor);
+}
+
+GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
+ GLFWmousebuttonfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
+ GLFWcursorposfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
+ GLFWcursorenterfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
+ GLFWscrollfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
+ return cbfun;
+}
+
+GLFWAPI int glfwJoystickPresent(int jid)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return GLFW_FALSE;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return GLFW_FALSE;
+
+ return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
+}
+
+GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+ assert(count != NULL);
+
+ *count = 0;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return NULL;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return NULL;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
+ return NULL;
+
+ *count = js->axisCount;
+ return js->axes;
+}
+
+GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+ assert(count != NULL);
+
+ *count = 0;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return NULL;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return NULL;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
+ return NULL;
+
+ if (_glfw.hints.init.hatButtons)
+ *count = js->buttonCount + js->hatCount * 4;
+ else
+ *count = js->buttonCount;
+
+ return js->buttons;
+}
+
+GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+ assert(count != NULL);
+
+ *count = 0;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return NULL;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return NULL;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
+ return NULL;
+
+ *count = js->hatCount;
+ return js->hats;
+}
+
+GLFWAPI const char* glfwGetJoystickName(int jid)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return NULL;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return NULL;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
+ return NULL;
+
+ return js->name;
+}
+
+GLFWAPI const char* glfwGetJoystickGUID(int jid)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return NULL;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return NULL;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
+ return NULL;
+
+ return js->guid;
+}
+
+GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
+ return cbfun;
+}
+
+GLFWAPI int glfwUpdateGamepadMappings(const char* string)
+{
+ int jid;
+ const char* c = string;
+
+ assert(string != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ while (*c)
+ {
+ if (isxdigit(*c))
+ {
+ char line[1024];
+
+ const size_t length = strcspn(c, "\r\n");
+ if (length < sizeof(line))
+ {
+ _GLFWmapping mapping = {{0}};
+
+ memcpy(line, c, length);
+ line[length] = '\0';
+
+ if (parseMapping(&mapping, line))
+ {
+ _GLFWmapping* previous = findMapping(mapping.guid);
+ if (previous)
+ *previous = mapping;
+ else
+ {
+ _glfw.mappingCount++;
+ _glfw.mappings =
+ realloc(_glfw.mappings,
+ sizeof(_GLFWmapping) * _glfw.mappingCount);
+ _glfw.mappings[_glfw.mappingCount - 1] = mapping;
+ }
+ }
+ }
+
+ c += length;
+ }
+ else
+ {
+ c += strcspn(c, "\r\n");
+ c += strspn(c, "\r\n");
+ }
+ }
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ _GLFWjoystick* js = _glfw.joysticks + jid;
+ if (js->present)
+ js->mapping = findMapping(js->guid);
+ }
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI int glfwJoystickIsGamepad(int jid)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return GLFW_FALSE;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return GLFW_FALSE;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
+ return GLFW_FALSE;
+
+ return js->mapping != NULL;
+}
+
+GLFWAPI const char* glfwGetGamepadName(int jid)
+{
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return NULL;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return NULL;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
+ return NULL;
+
+ if (!js->mapping)
+ return NULL;
+
+ return js->mapping->name;
+}
+
+GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
+{
+ int i;
+ _GLFWjoystick* js;
+
+ assert(jid >= GLFW_JOYSTICK_1);
+ assert(jid <= GLFW_JOYSTICK_LAST);
+ assert(state != NULL);
+
+ memset(state, 0, sizeof(GLFWgamepadstate));
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
+ {
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
+ return GLFW_FALSE;
+ }
+
+ js = _glfw.joysticks + jid;
+ if (!js->present)
+ return GLFW_FALSE;
+
+ if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
+ return GLFW_FALSE;
+
+ if (!js->mapping)
+ return GLFW_FALSE;
+
+ for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
+ {
+ if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_AXIS)
+ {
+ if (fabs(js->axes[js->mapping->buttons[i].value]) > 0.5)
+ state->buttons[i] = GLFW_PRESS;
+ }
+ else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_HATBIT)
+ {
+ const unsigned int hat = js->mapping->buttons[i].value >> 4;
+ const unsigned int bit = js->mapping->buttons[i].value & 0xf;
+ if (js->hats[hat] & bit)
+ state->buttons[i] = GLFW_PRESS;
+ }
+ else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_BUTTON)
+ state->buttons[i] = js->buttons[js->mapping->buttons[i].value];
+ }
+
+ for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
+ {
+ if (js->mapping->axes[i].type == _GLFW_JOYSTICK_AXIS)
+ state->axes[i] = js->axes[js->mapping->axes[i].value];
+ else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_HATBIT)
+ {
+ const unsigned int hat = js->mapping->buttons[i].value >> 4;
+ const unsigned int bit = js->mapping->buttons[i].value & 0xf;
+ if (js->hats[hat] & bit)
+ state->axes[i] = 1.f;
+ }
+ else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_BUTTON)
+ state->axes[i] = (float) js->buttons[js->mapping->axes[i].value];
+ }
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+ assert(string != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformSetClipboardString(window, string);
+}
+
+GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return _glfwPlatformGetClipboardString(window);
+}
+
+GLFWAPI double glfwGetTime(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(0.0);
+ return (double) (_glfwPlatformGetTimerValue() - _glfw.timer.offset) /
+ _glfwPlatformGetTimerFrequency();
+}
+
+GLFWAPI void glfwSetTime(double time)
+{
+ _GLFW_REQUIRE_INIT();
+
+ if (time != time || time < 0.0 || time > 18446744073.0)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time);
+ return;
+ }
+
+ _glfw.timer.offset = _glfwPlatformGetTimerValue() -
+ (uint64_t) (time * _glfwPlatformGetTimerFrequency());
+}
+
+GLFWAPI uint64_t glfwGetTimerValue(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(0);
+ return _glfwPlatformGetTimerValue();
+}
+
+GLFWAPI uint64_t glfwGetTimerFrequency(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(0);
+ return _glfwPlatformGetTimerFrequency();
+}
+
diff --git a/src/external/glfw/src/internal.h b/src/external/glfw/src/internal.h
new file mode 100644
index 00000000..485d9434
--- /dev/null
+++ b/src/external/glfw/src/internal.h
@@ -0,0 +1,1016 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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.
+//
+//========================================================================
+
+#pragma once
+
+#if defined(_GLFW_USE_CONFIG_H)
+ #include "glfw_config.h"
+#endif
+
+#if defined(GLFW_INCLUDE_GLCOREARB) || \
+ defined(GLFW_INCLUDE_ES1) || \
+ defined(GLFW_INCLUDE_ES2) || \
+ defined(GLFW_INCLUDE_ES3) || \
+ defined(GLFW_INCLUDE_ES31) || \
+ defined(GLFW_INCLUDE_ES32) || \
+ defined(GLFW_INCLUDE_NONE) || \
+ defined(GLFW_INCLUDE_GLEXT) || \
+ defined(GLFW_INCLUDE_GLU) || \
+ defined(GLFW_INCLUDE_VULKAN) || \
+ defined(GLFW_DLL)
+ #error "You must not define any header option macros when compiling GLFW"
+#endif
+
+#define GLFW_INCLUDE_NONE
+#include "../include/GLFW/glfw3.h"
+
+#define _GLFW_INSERT_FIRST 0
+#define _GLFW_INSERT_LAST 1
+
+#define _GLFW_POLL_PRESENCE 0
+#define _GLFW_POLL_AXES 1
+#define _GLFW_POLL_BUTTONS 2
+#define _GLFW_POLL_ALL (_GLFW_POLL_AXES | _GLFW_POLL_BUTTONS)
+
+#define _GLFW_MESSAGE_SIZE 1024
+
+typedef int GLFWbool;
+
+typedef struct _GLFWerror _GLFWerror;
+typedef struct _GLFWinitconfig _GLFWinitconfig;
+typedef struct _GLFWwndconfig _GLFWwndconfig;
+typedef struct _GLFWctxconfig _GLFWctxconfig;
+typedef struct _GLFWfbconfig _GLFWfbconfig;
+typedef struct _GLFWcontext _GLFWcontext;
+typedef struct _GLFWwindow _GLFWwindow;
+typedef struct _GLFWlibrary _GLFWlibrary;
+typedef struct _GLFWmonitor _GLFWmonitor;
+typedef struct _GLFWcursor _GLFWcursor;
+typedef struct _GLFWmapelement _GLFWmapelement;
+typedef struct _GLFWmapping _GLFWmapping;
+typedef struct _GLFWjoystick _GLFWjoystick;
+typedef struct _GLFWtls _GLFWtls;
+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_NONE 0
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_EXTENSIONS 0x1f03
+#define GL_NUM_EXTENSIONS 0x821d
+#define GL_CONTEXT_FLAGS 0x821e
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
+
+typedef int GLint;
+typedef unsigned int GLuint;
+typedef unsigned int GLenum;
+typedef unsigned int GLbitfield;
+typedef unsigned char GLubyte;
+
+typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield);
+typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
+typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
+typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
+
+#define VK_NULL_HANDLE 0
+
+typedef void* VkInstance;
+typedef void* VkPhysicalDevice;
+typedef uint64_t VkSurfaceKHR;
+typedef uint32_t VkFlags;
+typedef uint32_t VkBool32;
+
+typedef enum VkStructureType
+{
+ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
+ VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
+ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
+ VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
+ VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000053000,
+ VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkStructureType;
+
+typedef enum VkResult
+{
+ VK_SUCCESS = 0,
+ VK_NOT_READY = 1,
+ VK_TIMEOUT = 2,
+ VK_EVENT_SET = 3,
+ VK_EVENT_RESET = 4,
+ VK_INCOMPLETE = 5,
+ VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+ VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+ VK_ERROR_INITIALIZATION_FAILED = -3,
+ VK_ERROR_DEVICE_LOST = -4,
+ VK_ERROR_MEMORY_MAP_FAILED = -5,
+ VK_ERROR_LAYER_NOT_PRESENT = -6,
+ VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+ VK_ERROR_FEATURE_NOT_PRESENT = -8,
+ VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+ VK_ERROR_TOO_MANY_OBJECTS = -10,
+ VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+ VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+ VK_SUBOPTIMAL_KHR = 1000001003,
+ VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+ VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
+ VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+ VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+} VkResult;
+
+typedef struct VkAllocationCallbacks VkAllocationCallbacks;
+
+typedef struct VkExtensionProperties
+{
+ char extensionName[256];
+ uint32_t specVersion;
+} VkExtensionProperties;
+
+typedef void (APIENTRY * PFN_vkVoidFunction)(void);
+
+#if defined(_GLFW_VULKAN_STATIC)
+ PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);
+ VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);
+#else
+ typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
+ typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
+ #define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
+ #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
+#endif
+
+#if defined(_GLFW_COCOA)
+ #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_MIR)
+ #include "mir_platform.h"
+#elif defined(_GLFW_OSMESA)
+ #include "null_platform.h"
+#else
+ #error "No supported window creation API selected"
+#endif
+
+
+//========================================================================
+// Doxygen group definitions
+//========================================================================
+
+/*! @defgroup platform Platform interface
+ * @brief The interface implemented by the platform-specific code.
+ *
+ * The platform API is the interface exposed by the platform-specific code for
+ * each platform and is called by the shared code of the public API It mirrors
+ * the public API except it uses objects instead of handles.
+ */
+/*! @defgroup event Event interface
+ * @brief The interface used by the platform-specific code to report events.
+ *
+ * The event API is used by the platform-specific code to notify the shared
+ * code of events that can be translated into state changes and/or callback
+ * calls.
+ */
+/*! @defgroup utility Utility functions
+ * @brief Various utility functions for internal use.
+ *
+ * These functions are shared code and may be used by any part of GLFW
+ * Each platform may add its own utility functions, but those must only be
+ * called by the platform-specific code
+ */
+
+
+//========================================================================
+// Helper macros
+//========================================================================
+
+// 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
+#define _GLFW_REQUIRE_INIT() \
+ if (!_glfw.initialized) \
+ { \
+ _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
+ return; \
+ }
+#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \
+ if (!_glfw.initialized) \
+ { \
+ _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
+ return x; \
+ }
+
+// Swaps the provided pointers
+#define _GLFW_SWAP_POINTERS(x, y) \
+ { \
+ void* t; \
+ t = x; \
+ x = y; \
+ y = t; \
+ }
+
+
+//========================================================================
+// Platform-independent structures
+//========================================================================
+
+struct _GLFWerror
+{
+ _GLFWerror* next;
+ int code;
+ char description[_GLFW_MESSAGE_SIZE];
+};
+
+/*! @brief Initialization configuration.
+ *
+ * Parameters relating to the initialization of the library.
+ */
+struct _GLFWinitconfig
+{
+ GLFWbool hatButtons;
+ struct {
+ GLFWbool menubar;
+ GLFWbool chdir;
+ } ns;
+ struct {
+ char className[256];
+ char classClass[256];
+ } x11;
+};
+
+/*! @brief Window configuration.
+ *
+ * Parameters relating to the creation of the window but not directly related
+ * to the framebuffer. This is used to pass window creation parameters from
+ * shared code to the platform API.
+ */
+struct _GLFWwndconfig
+{
+ int width;
+ int height;
+ const char* title;
+ GLFWbool resizable;
+ GLFWbool visible;
+ GLFWbool decorated;
+ GLFWbool focused;
+ GLFWbool autoIconify;
+ GLFWbool floating;
+ GLFWbool maximized;
+ GLFWbool centerCursor;
+ struct {
+ GLFWbool retina;
+ GLFWbool frame;
+ } ns;
+};
+
+/*! @brief Context configuration.
+ *
+ * Parameters relating to the creation of the context but not directly related
+ * to the framebuffer. This is used to pass context creation parameters from
+ * shared code to the platform API.
+ */
+struct _GLFWctxconfig
+{
+ int client;
+ int source;
+ int major;
+ int minor;
+ GLFWbool forward;
+ GLFWbool debug;
+ GLFWbool noerror;
+ int profile;
+ int robustness;
+ int release;
+ _GLFWwindow* share;
+ struct {
+ GLFWbool offline;
+ } nsgl;
+};
+
+/*! @brief Framebuffer configuration.
+ *
+ * This describes buffers and their sizes. It also contains
+ * a platform-specific ID used to map back to the backend API object.
+ *
+ * It is used to pass framebuffer parameters from shared code to the platform
+ * API and also to enumerate and select available framebuffer configs.
+ */
+struct _GLFWfbconfig
+{
+ int redBits;
+ int greenBits;
+ int blueBits;
+ int alphaBits;
+ int depthBits;
+ int stencilBits;
+ int accumRedBits;
+ int accumGreenBits;
+ int accumBlueBits;
+ int accumAlphaBits;
+ int auxBuffers;
+ GLFWbool stereo;
+ int samples;
+ GLFWbool sRGB;
+ GLFWbool doublebuffer;
+ GLFWbool transparent;
+ uintptr_t handle;
+};
+
+/*! @brief Context structure.
+ */
+struct _GLFWcontext
+{
+ int client;
+ int source;
+ int major, minor, revision;
+ GLFWbool forward, debug, noerror;
+ int profile;
+ int robustness;
+ int release;
+
+ PFNGLGETSTRINGIPROC GetStringi;
+ PFNGLGETINTEGERVPROC GetIntegerv;
+ PFNGLGETSTRINGPROC GetString;
+
+ _GLFWmakecontextcurrentfun makeCurrent;
+ _GLFWswapbuffersfun swapBuffers;
+ _GLFWswapintervalfun swapInterval;
+ _GLFWextensionsupportedfun extensionSupported;
+ _GLFWgetprocaddressfun getProcAddress;
+ _GLFWdestroycontextfun destroy;
+
+ // This is defined in the context API's context.h
+ _GLFW_PLATFORM_CONTEXT_STATE;
+ // This is defined in egl_context.h
+ _GLFW_EGL_CONTEXT_STATE;
+ // This is defined in osmesa_context.h
+ _GLFW_OSMESA_CONTEXT_STATE;
+};
+
+/*! @brief Window and context structure.
+ */
+struct _GLFWwindow
+{
+ struct _GLFWwindow* next;
+
+ // Window settings and state
+ GLFWbool resizable;
+ GLFWbool decorated;
+ GLFWbool autoIconify;
+ GLFWbool floating;
+ GLFWbool shouldClose;
+ void* userPointer;
+ GLFWvidmode videoMode;
+ _GLFWmonitor* monitor;
+ _GLFWcursor* cursor;
+
+ int minwidth, minheight;
+ int maxwidth, maxheight;
+ int numer, denom;
+
+ GLFWbool stickyKeys;
+ GLFWbool stickyMouseButtons;
+ int cursorMode;
+ char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
+ char keys[GLFW_KEY_LAST + 1];
+ // Virtual cursor position when cursor is disabled
+ double virtualCursorPosX, virtualCursorPosY;
+
+ _GLFWcontext context;
+
+ struct {
+ GLFWwindowposfun pos;
+ GLFWwindowsizefun size;
+ GLFWwindowclosefun close;
+ GLFWwindowrefreshfun refresh;
+ GLFWwindowfocusfun focus;
+ GLFWwindowiconifyfun iconify;
+ GLFWwindowmaximizefun maximize;
+ GLFWframebuffersizefun fbsize;
+ GLFWmousebuttonfun mouseButton;
+ GLFWcursorposfun cursorPos;
+ GLFWcursorenterfun cursorEnter;
+ GLFWscrollfun scroll;
+ GLFWkeyfun key;
+ GLFWcharfun character;
+ GLFWcharmodsfun charmods;
+ GLFWdropfun drop;
+ } callbacks;
+
+ // This is defined in the window API's platform.h
+ _GLFW_PLATFORM_WINDOW_STATE;
+};
+
+/*! @brief Monitor structure.
+ */
+struct _GLFWmonitor
+{
+ char* name;
+
+ // Physical dimensions in millimeters.
+ int widthMM, heightMM;
+
+ // The window whose video mode is current on this monitor
+ _GLFWwindow* window;
+
+ GLFWvidmode* modes;
+ int modeCount;
+ GLFWvidmode currentMode;
+
+ GLFWgammaramp originalRamp;
+ GLFWgammaramp currentRamp;
+
+ // This is defined in the window API's platform.h
+ _GLFW_PLATFORM_MONITOR_STATE;
+};
+
+/*! @brief Cursor structure
+ */
+struct _GLFWcursor
+{
+ _GLFWcursor* next;
+
+ // This is defined in the window API's platform.h
+ _GLFW_PLATFORM_CURSOR_STATE;
+};
+
+/*! @brief Gamepad mapping element structure
+ */
+struct _GLFWmapelement
+{
+ uint8_t type;
+ uint8_t value;
+};
+
+/*! @brief Gamepad mapping structure
+ */
+struct _GLFWmapping
+{
+ char name[128];
+ char guid[33];
+ _GLFWmapelement buttons[15];
+ _GLFWmapelement axes[6];
+};
+
+/*! @brief Joystick structure
+ */
+struct _GLFWjoystick
+{
+ GLFWbool present;
+ float* axes;
+ int axisCount;
+ unsigned char* buttons;
+ int buttonCount;
+ unsigned char* hats;
+ int hatCount;
+ char* name;
+ char guid[33];
+ _GLFWmapping* mapping;
+
+ // This is defined in the joystick API's joystick.h
+ _GLFW_PLATFORM_JOYSTICK_STATE;
+};
+
+/*! @brief Thread local storage structure.
+ */
+struct _GLFWtls
+{
+ // This is defined in the platform's thread.h
+ _GLFW_PLATFORM_TLS_STATE;
+};
+
+/*! @brief Mutex structure.
+ */
+struct _GLFWmutex
+{
+ // This is defined in the platform's thread.h
+ _GLFW_PLATFORM_MUTEX_STATE;
+};
+
+/*! @brief Library global data.
+ */
+struct _GLFWlibrary
+{
+ GLFWbool initialized;
+
+ struct {
+ _GLFWinitconfig init;
+ _GLFWfbconfig framebuffer;
+ _GLFWwndconfig window;
+ _GLFWctxconfig context;
+ int refreshRate;
+ } hints;
+
+ _GLFWerror* errorListHead;
+ _GLFWcursor* cursorListHead;
+ _GLFWwindow* windowListHead;
+
+ _GLFWmonitor** monitors;
+ int monitorCount;
+
+ _GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
+ _GLFWmapping* mappings;
+ int mappingCount;
+
+ _GLFWtls errorSlot;
+ _GLFWtls contextSlot;
+ _GLFWmutex errorLock;
+
+ struct {
+ uint64_t offset;
+ // This is defined in the platform's time.h
+ _GLFW_PLATFORM_LIBRARY_TIMER_STATE;
+ } timer;
+
+ struct {
+ GLFWbool available;
+ void* handle;
+ char* extensions[2];
+#if !defined(_GLFW_VULKAN_STATIC)
+ PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
+ PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+#endif
+ GLFWbool KHR_surface;
+#if defined(_GLFW_WIN32)
+ GLFWbool KHR_win32_surface;
+#elif defined(_GLFW_COCOA)
+ GLFWbool MVK_macos_surface;
+#elif defined(_GLFW_X11)
+ GLFWbool KHR_xlib_surface;
+ GLFWbool KHR_xcb_surface;
+#elif defined(_GLFW_WAYLAND)
+ GLFWbool KHR_wayland_surface;
+#elif defined(_GLFW_MIR)
+ GLFWbool KHR_mir_surface;
+#endif
+ } vk;
+
+ struct {
+ GLFWmonitorfun monitor;
+ GLFWjoystickfun joystick;
+ } callbacks;
+
+ // This is defined in the window API's platform.h
+ _GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
+ // This is defined in the context API's context.h
+ _GLFW_PLATFORM_LIBRARY_CONTEXT_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
+//========================================================================
+
+/*! @brief All global data shared between compilation units.
+ */
+extern _GLFWlibrary _glfw;
+
+
+//========================================================================
+// Platform API functions
+//========================================================================
+
+/*! @addtogroup platform @{ */
+
+int _glfwPlatformInit(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);
+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 _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, float* xscale, float* yscale);
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window);
+
+int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
+void _glfwPlatformUpdateGamepadGUID(char* guid);
+
+uint64_t _glfwPlatformGetTimerValue(void);
+uint64_t _glfwPlatformGetTimerFrequency(void);
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig);
+void _glfwPlatformDestroyWindow(_GLFWwindow* window);
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, const GLFWimage* images);
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, float* xscale, float* yscale);
+void _glfwPlatformIconifyWindow(_GLFWwindow* window);
+void _glfwPlatformRestoreWindow(_GLFWwindow* window);
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
+void _glfwPlatformShowWindow(_GLFWwindow* window);
+void _glfwPlatformHideWindow(_GLFWwindow* window);
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
+void _glfwPlatformFocusWindow(_GLFWwindow* window);
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
+int _glfwPlatformWindowFocused(_GLFWwindow* window);
+int _glfwPlatformWindowIconified(_GLFWwindow* window);
+int _glfwPlatformWindowVisible(_GLFWwindow* window);
+int _glfwPlatformWindowMaximized(_GLFWwindow* window);
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
+
+void _glfwPlatformPollEvents(void);
+void _glfwPlatformWaitEvents(void);
+void _glfwPlatformWaitEventsTimeout(double timeout);
+void _glfwPlatformPostEmptyEvent(void);
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
+
+GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
+void _glfwPlatformDestroyTls(_GLFWtls* tls);
+void* _glfwPlatformGetTls(_GLFWtls* tls);
+void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
+
+GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
+void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
+void _glfwPlatformLockMutex(_GLFWmutex* mutex);
+void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
+
+/*! @} */
+
+
+//========================================================================
+// Event API functions
+//========================================================================
+
+/*! @brief Notifies shared code that a window has lost or received input focus.
+ * @param[in] window The window that received the event.
+ * @param[in] focused `GLFW_TRUE` if the window received focus, or `GLFW_FALSE`
+ * if it lost focus.
+ * @ingroup event
+ */
+void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
+
+/*! @brief Notifies shared code that a window has moved.
+ * @param[in] window The window that received the event.
+ * @param[in] xpos The new x-coordinate of the client area of the window.
+ * @param[in] ypos The new y-coordinate of the client area of the window.
+ * @ingroup event
+ */
+void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
+
+/*! @brief Notifies shared code that a window has been resized.
+ * @param[in] window The window that received the event.
+ * @param[in] width The new width of the client area of the window.
+ * @param[in] height The new height of the client area of the window.
+ * @ingroup event
+ */
+void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
+
+/*! @brief Notifies shared code that a window framebuffer has been resized.
+ * @param[in] window The window that received the event.
+ * @param[in] width The new width, in pixels, of the framebuffer.
+ * @param[in] height The new height, in pixels, of the framebuffer.
+ * @ingroup event
+ */
+void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
+
+/*! @brief Notifies shared code that a window has been iconified or restored.
+ * @param[in] window The window that received the event.
+ * @param[in] iconified `GLFW_TRUE` if the window was iconified, or
+ * `GLFW_FALSE` if it was restored.
+ * @ingroup event
+ */
+void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
+
+/*! @brief Notifies shared code that a window has been maximized or restored.
+ * @param[in] window The window that received the event.
+ * @param[in] maximized `GLFW_TRUE` if the window was maximized, or
+ * `GLFW_FALSE` if it was restored.
+ * @ingroup event
+ */
+void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
+
+/*! @brief Notifies shared code that a window's contents needs updating.
+ * @param[in] window The window that received the event.
+ */
+void _glfwInputWindowDamage(_GLFWwindow* window);
+
+/*! @brief Notifies shared code that the user wishes to close a window.
+ * @param[in] window The window that received the event.
+ * @ingroup event
+ */
+void _glfwInputWindowCloseRequest(_GLFWwindow* window);
+
+/*! @brief Notifies shared code that a window has changed its desired monitor.
+ * @param[in] window The window that received the event.
+ * @param[in] monitor The new desired monitor, or `NULL`.
+ * @ingroup event
+ */
+void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
+
+/*! @brief Notifies shared code of a physical key event.
+ * @param[in] window The window that received the event.
+ * @param[in] key The key that was pressed or released.
+ * @param[in] scancode The system-specific scan code of the key.
+ * @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
+ * @param[in] mods The modifiers pressed when the event was generated.
+ * @ingroup event
+ */
+void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods);
+
+/*! @brief Notifies shared code of a Unicode character input event.
+ * @param[in] window The window that received the event.
+ * @param[in] codepoint The Unicode code point of the input character.
+ * @param[in] mods Bit field describing which modifier keys were held down.
+ * @param[in] plain `GLFW_TRUE` if the character is regular text input, or
+ * `GLFW_FALSE` otherwise.
+ * @ingroup event
+ */
+void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain);
+
+/*! @brief Notifies shared code of a scroll event.
+ * @param[in] window The window that received the event.
+ * @param[in] xoffset The scroll offset along the x-axis.
+ * @param[in] yoffset The scroll offset along the y-axis.
+ * @ingroup event
+ */
+void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
+
+/*! @brief Notifies shared code of a mouse button click event.
+ * @param[in] window The window that received the event.
+ * @param[in] button The button that was pressed or released.
+ * @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
+ * @param[in] mods The modifiers pressed when the event was generated.
+ * @ingroup event
+ */
+void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
+
+/*! @brief Notifies shared code of a cursor motion event.
+ * @param[in] window The window that received the event.
+ * @param[in] xpos The new x-coordinate of the cursor, relative to the left
+ * edge of the client area of the window.
+ * @param[in] ypos The new y-coordinate of the cursor, relative to the top edge
+ * of the client area of the window.
+ * @ingroup event
+ */
+void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
+
+/*! @brief Notifies shared code of a cursor enter/leave event.
+ * @param[in] window The window that received the event.
+ * @param[in] entered `GLFW_TRUE` if the cursor entered the client area of the
+ * window, or `GLFW_FALSE` if it left it.
+ * @ingroup event
+ */
+void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
+
+/*! @brief Notifies shared code of a monitor connection or disconnection.
+ * @param[in] monitor The monitor that was connected or disconnected.
+ * @param[in] action One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
+ * @param[in] placement `_GLFW_INSERT_FIRST` or `_GLFW_INSERT_LAST`.
+ * @ingroup event
+ */
+void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
+
+/*! @brief Notifies shared code that a full screen window has acquired or
+ * released a monitor.
+ * @param[in] monitor The monitor that was acquired or released.
+ * @param[in] window The window that acquired the monitor, or `NULL`.
+ * @ingroup event
+ */
+void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
+
+/*! @brief Notifies shared code of an error.
+ * @param[in] code The error code most suitable for the error.
+ * @param[in] format The `printf` style format string of the error
+ * description.
+ * @ingroup event
+ */
+#if defined(__GNUC__)
+void _glfwInputError(int code, const char* format, ...) __attribute__((format(printf, 2, 3)));
+#else
+void _glfwInputError(int code, const char* format, ...);
+#endif
+
+/*! @brief Notifies shared code of files or directories dropped on a window.
+ * @param[in] window The window that received the event.
+ * @param[in] count The number of dropped objects.
+ * @param[in] names The names of the dropped objects.
+ * @ingroup event
+ */
+void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
+
+/*! @brief Notifies shared code of a joystick connection or disconnection.
+ * @param[in] js The joystick that was connected or disconnected.
+ * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
+ * @ingroup event
+ */
+void _glfwInputJoystick(_GLFWjoystick* js, int event);
+
+/*! @brief Notifies shared code of the new value of a joystick axis.
+ * @param[in] js The joystick whose axis to update.
+ * @param[in] axis The index of the axis to update.
+ * @param[in] value The new value of the axis.
+ */
+void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
+
+/*! @brief Notifies shared code of the new value of a joystick button.
+ * @param[in] js The joystick whose button to update.
+ * @param[in] button The index of the button to update.
+ * @param[in] value The new value of the button.
+ */
+void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
+
+/*! @brief Notifies shared code of the new value of a joystick hat.
+ * @param[in] js The joystick whose hat to update.
+ * @param[in] button The index of the hat to update.
+ * @param[in] value The new value of the hat.
+ */
+void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
+
+
+//========================================================================
+// Utility functions
+//========================================================================
+
+/*! @brief Chooses the video mode most closely matching the desired one.
+ * @ingroup utility
+ */
+const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
+ const GLFWvidmode* desired);
+
+/*! @brief Performs lexical comparison between two @ref GLFWvidmode structures.
+ * @ingroup utility
+ */
+int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second);
+
+/*! @brief Splits a color depth into red, green and blue bit depths.
+ * @ingroup utility
+ */
+void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
+
+/*! @brief Searches an extension string for the specified extension.
+ * @param[in] string The extension string to search.
+ * @param[in] extensions The extension to search for.
+ * @return `GLFW_TRUE` if the extension was found, or `GLFW_FALSE` otherwise.
+ * @ingroup utility
+ */
+GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
+
+/*! @brief Chooses the framebuffer config that best matches the desired one.
+ * @param[in] desired The desired framebuffer config.
+ * @param[in] alternatives The framebuffer configs supported by the system.
+ * @param[in] count The number of entries in the alternatives array.
+ * @return The framebuffer config most closely matching the desired one, or @c
+ * NULL if none fulfilled the hard constraints of the desired values.
+ * @ingroup utility
+ */
+const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
+ const _GLFWfbconfig* alternatives,
+ unsigned int count);
+
+/*! @brief Retrieves the attributes of the current context.
+ * @param[in] ctxconfig The desired context attributes.
+ * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if the context is
+ * unusable.
+ * @ingroup utility
+ */
+GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig);
+
+/*! @brief Checks whether the desired context attributes are valid.
+ * @param[in] ctxconfig The context attributes to check.
+ * @return `GLFW_TRUE` if the context attributes are valid, or `GLFW_FALSE`
+ * otherwise.
+ * @ingroup utility
+ *
+ * This function checks things like whether the specified client API version
+ * exists and whether all relevant options have supported and non-conflicting
+ * values.
+ */
+GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
+
+/*! @brief Allocates red, green and blue value arrays of the specified size.
+ * @ingroup utility
+ */
+void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
+
+/*! @brief Frees the red, green and blue value arrays and clears the struct.
+ * @ingroup utility
+ */
+void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
+
+/*! @brief Allocates and returns a monitor object with the specified name
+ * and dimensions.
+ * @param[in] name The name of the monitor.
+ * @param[in] widthMM The width, in mm, of the monitor's display area.
+ * @param[in] heightMM The height, in mm, of the monitor's display area.
+ * @return The newly created object.
+ * @ingroup utility
+ */
+_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM);
+
+/*! @brief Frees a monitor object and any data associated with it.
+ * @ingroup utility
+ */
+void _glfwFreeMonitor(_GLFWmonitor* monitor);
+
+/*! @brief Returns an available joystick object with arrays and name allocated.
+ * @ingroup utility
+ */
+_GLFWjoystick* _glfwAllocJoystick(const char* name,
+ const char* guid,
+ int axisCount,
+ int buttonCount,
+ int hatCount);
+
+/*! @brief Frees arrays and name and flags the joystick object as unused.
+ * @ingroup utility
+ */
+void _glfwFreeJoystick(_GLFWjoystick* js);
+
+/*! @ingroup utility
+ */
+GLFWbool _glfwInitVulkan(int mode);
+
+/*! @ingroup utility
+ */
+void _glfwTerminateVulkan(void);
+
+/*! @ingroup utility
+ */
+const char* _glfwGetVulkanResultString(VkResult result);
+
diff --git a/src/external/glfw/src/linux_joystick.c b/src/external/glfw/src/linux_joystick.c
new file mode 100644
index 00000000..d73961fb
--- /dev/null
+++ b/src/external/glfw/src/linux_joystick.c
@@ -0,0 +1,429 @@
+//========================================================================
+// GLFW 3.3 Linux - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/inotify.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// Apply an EV_KEY event to the specified joystick
+//
+static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
+{
+ _glfwInputJoystickButton(js,
+ js->linjs.keyMap[code - BTN_MISC],
+ value ? GLFW_PRESS : GLFW_RELEASE);
+}
+
+// Apply an EV_ABS event to the specified joystick
+//
+static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
+{
+ const int index = js->linjs.absMap[code];
+
+ if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
+ {
+ static const char stateMap[3][3] =
+ {
+ { GLFW_HAT_CENTERED, GLFW_HAT_UP, GLFW_HAT_DOWN },
+ { GLFW_HAT_LEFT, GLFW_HAT_LEFT_UP, GLFW_HAT_LEFT_DOWN },
+ { GLFW_HAT_RIGHT, GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN },
+ };
+
+ const int hat = (code - ABS_HAT0X) / 2;
+ const int axis = (code - ABS_HAT0X) % 2;
+ int* state = js->linjs.hats[hat];
+
+ // NOTE: Looking at several input drivers, it seems all hat events use
+ // -1 for left / up, 0 for centered and 1 for right / down
+ if (value == 0)
+ state[axis] = 0;
+ else if (value < 0)
+ state[axis] = 1;
+ else if (value > 0)
+ state[axis] = 2;
+
+ _glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
+ }
+ else
+ {
+ const struct input_absinfo* info = &js->linjs.absInfo[code];
+ float normalized = value;
+
+ const int range = info->maximum - info->minimum;
+ if (range)
+ {
+ // Normalize to 0.0 -> 1.0
+ normalized = (normalized - info->minimum) / range;
+ // Normalize to -1.0 -> 1.0
+ normalized = normalized * 2.0f - 1.0f;
+ }
+
+ _glfwInputJoystickAxis(js, index, normalized);
+ }
+}
+
+// Poll state of absolute axes
+//
+static void pollAbsState(_GLFWjoystick* js)
+{
+ int code;
+
+ for (code = 0; code < ABS_CNT; code++)
+ {
+ if (js->linjs.absMap[code] < 0)
+ continue;
+
+ struct input_absinfo* info = &js->linjs.absInfo[code];
+
+ if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
+ continue;
+
+ handleAbsEvent(js, code, info->value);
+ }
+}
+
+#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
+
+// Attempt to open the specified joystick device
+//
+static GLFWbool openJoystickDevice(const char* path)
+{
+ int jid, code;
+ 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)
+ continue;
+ if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
+ return GLFW_FALSE;
+ }
+
+ linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (linjs.fd == -1)
+ return GLFW_FALSE;
+
+ 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_ABS, sizeof(absBits)), absBits) < 0 ||
+ ioctl(linjs.fd, EVIOCGID, &id) < 0)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Linux: Failed to query input device: %s",
+ strerror(errno));
+ close(linjs.fd);
+ return GLFW_FALSE;
+ }
+
+ // Ensure this device supports the events expected of a joystick
+ if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
+ {
+ close(linjs.fd);
+ return GLFW_FALSE;
+ }
+
+ if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
+ strncpy(name, "Unknown", sizeof(name));
+
+ // Generate a joystick GUID that matches the SDL 2.0.5+ one
+ if (id.vendor && id.product && id.version)
+ {
+ sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
+ id.bustype & 0xff, id.bustype >> 8,
+ id.vendor & 0xff, id.vendor >> 8,
+ id.product & 0xff, id.product >> 8,
+ id.version & 0xff, id.version >> 8);
+ }
+ else
+ {
+ sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
+ id.bustype & 0xff, id.bustype >> 8,
+ name[0], name[1], name[2], name[3],
+ name[4], name[5], name[6], name[7],
+ name[8], name[9], name[10]);
+ }
+
+ for (code = BTN_MISC; code < KEY_CNT; code++)
+ {
+ if (!isBitSet(code, keyBits))
+ continue;
+
+ linjs.keyMap[code - BTN_MISC] = buttonCount;
+ buttonCount++;
+ }
+
+ for (code = 0; code < ABS_CNT; code++)
+ {
+ linjs.absMap[code] = -1;
+ if (!isBitSet(code, absBits))
+ continue;
+
+ if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
+ {
+ linjs.absMap[code] = hatCount;
+ hatCount++;
+ // Skip the Y axis
+ code++;
+ }
+ else
+ {
+ if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
+ continue;
+
+ linjs.absMap[code] = axisCount;
+ axisCount++;
+ }
+ }
+
+ js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
+ if (!js)
+ {
+ close(linjs.fd);
+ return GLFW_FALSE;
+ }
+
+ strncpy(linjs.path, path, sizeof(linjs.path));
+ memcpy(&js->linjs, &linjs, sizeof(linjs));
+
+ pollAbsState(js);
+
+ _glfwInputJoystick(js, GLFW_CONNECTED);
+ return GLFW_TRUE;
+}
+
+#undef isBitSet
+
+// Frees all resources associated with the specified joystick
+//
+static void closeJoystick(_GLFWjoystick* js)
+{
+ close(js->linjs.fd);
+ _glfwFreeJoystick(js);
+ _glfwInputJoystick(js, GLFW_DISCONNECTED);
+}
+
+// Lexically compare joysticks by name; used by qsort
+//
+static int compareJoysticks(const void* fp, const void* sp)
+{
+ const _GLFWjoystick* fj = fp;
+ const _GLFWjoystick* sj = sp;
+ return strcmp(fj->linjs.path, sj->linjs.path);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize joystick interface
+//
+GLFWbool _glfwInitJoysticksLinux(void)
+{
+ DIR* dir;
+ int count = 0;
+ const char* dirname = "/dev/input";
+
+ _glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+ if (_glfw.linjs.inotify > 0)
+ {
+ // HACK: Register for IN_ATTRIB to get notified when udev is done
+ // This works well in practice but the true way is libudev
+
+ _glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
+ dirname,
+ IN_CREATE | IN_ATTRIB | IN_DELETE);
+ }
+
+ // Continue without device connection notifications if inotify fails
+
+ if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
+ return GLFW_FALSE;
+ }
+
+ dir = opendir(dirname);
+ if (dir)
+ {
+ struct dirent* entry;
+
+ while ((entry = readdir(dir)))
+ {
+ regmatch_t match;
+
+ if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0)
+ continue;
+
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
+
+ if (openJoystickDevice(path))
+ count++;
+ }
+
+ closedir(dir);
+ }
+
+ // Continue with no joysticks if enumeration fails
+
+ qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
+ return GLFW_TRUE;
+}
+
+// Close all opened joystick handles
+//
+void _glfwTerminateJoysticksLinux(void)
+{
+ int jid;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ _GLFWjoystick* js = _glfw.joysticks + jid;
+ if (js->present)
+ closeJoystick(js);
+ }
+
+ regfree(&_glfw.linjs.regex);
+
+ if (_glfw.linjs.inotify > 0)
+ {
+ if (_glfw.linjs.watch > 0)
+ inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
+
+ close(_glfw.linjs.inotify);
+ }
+}
+
+void _glfwDetectJoystickConnectionLinux(void)
+{
+ 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)
+ for (;;)
+ {
+ struct input_event e;
+
+ errno = 0;
+ if (read(js->linjs.fd, &e, sizeof(e)) < 0)
+ {
+ // Reset the joystick slot if the device was disconnected
+ if (errno == ENODEV)
+ closeJoystick(js);
+
+ break;
+ }
+
+ if (e.type == EV_SYN)
+ {
+ if (e.code == SYN_DROPPED)
+ _glfw.linjs.dropped = GLFW_TRUE;
+ else if (e.code == SYN_REPORT)
+ {
+ _glfw.linjs.dropped = GLFW_FALSE;
+ pollAbsState(js);
+ }
+ }
+
+ if (_glfw.linjs.dropped)
+ continue;
+
+ if (e.type == EV_KEY)
+ handleKeyEvent(js, e.code, e.value);
+ else if (e.type == EV_ABS)
+ handleAbsEvent(js, e.code, e.value);
+ }
+
+ return js->present;
+}
+
+void _glfwPlatformUpdateGamepadGUID(char* guid)
+{
+}
+
diff --git a/src/external/glfw/src/linux_joystick.h b/src/external/glfw/src/linux_joystick.h
new file mode 100644
index 00000000..2eabfa13
--- /dev/null
+++ b/src/external/glfw/src/linux_joystick.h
@@ -0,0 +1,62 @@
+//========================================================================
+// GLFW 3.3 Linux - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014 Jonas Ã…dahl <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <linux/input.h>
+#include <linux/limits.h>
+#include <regex.h>
+
+#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
+#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
+
+#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
+
+// Linux-specific joystick data
+//
+typedef struct _GLFWjoystickLinux
+{
+ int fd;
+ char path[PATH_MAX];
+ int keyMap[KEY_CNT - BTN_MISC];
+ int absMap[ABS_CNT];
+ struct input_absinfo absInfo[ABS_CNT];
+ int hats[4][2];
+} _GLFWjoystickLinux;
+
+// Linux-specific joystick API data
+//
+typedef struct _GLFWlibraryLinux
+{
+ int inotify;
+ int watch;
+ regex_t regex;
+ GLFWbool dropped;
+} _GLFWlibraryLinux;
+
+
+GLFWbool _glfwInitJoysticksLinux(void);
+void _glfwTerminateJoysticksLinux(void);
+void _glfwDetectJoystickConnectionLinux(void);
+
diff --git a/src/external/glfw/src/mappings.h b/src/external/glfw/src/mappings.h
new file mode 100644
index 00000000..6c1b800d
--- /dev/null
+++ b/src/external/glfw/src/mappings.h
@@ -0,0 +1,241 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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 mappings.h.in, this file is used by CMake to produce the mappings.h
+// header file. If you are adding a GLFW specific gamepad mapping, this is
+// where to put it.
+//========================================================================
+// As mappings.h, this provides all pre-defined gamepad mappings, including
+// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
+// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
+// This file can be re-generated from mappings.h.in and the upstream
+// gamecontrollerdb.txt with the GenerateMappings.cmake script.
+//========================================================================
+
+// All gamepad mappings not labeled GLFW are copied from the
+// SDL_GameControllerDB project under the following license:
+//
+// Simple DirectMedia Layer
+// Copyright (C) 1997-2013 Sam Lantinga <[email protected]>
+//
+// 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.
+
+const char* _glfwDefaultMappings =
+"8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
+"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
+"ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,\n"
+"6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
+"0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
+"88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,\n"
+"4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,\n"
+"25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,\n"
+"4c05c405000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
+"4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
+"4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
+"6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,platform:Windows,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"36280100000000000000504944564944,OUYA Controller,platform:Windows,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,\n"
+"4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Windows,\n"
+"00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,\n"
+"00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,\n"
+"28040140000000000000504944564944,GamePad Pro USB,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,\n"
+"ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,\n"
+"8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
+"8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
+"10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
+"79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,\n"
+"4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
+"83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows,\n"
+"10080100000000000000504944564944,PS1 USB,platform:Windows,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
+"49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows,\n"
+"4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"79004318000000000000504944564944,Mayflash GameCube Controller Adapter,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
+"79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Windows,\n"
+"10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,platform:Windows,\n"
+"63252305000000000000504944564944,USB Vibration Joystick (BM),platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
+"02200090000000000000504944564944,8Bitdo NES30 PRO USB,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
+"ff113133000000000000504944564944,Gembird JPD-DualForce,platform:Windows,a:b2,b:b3,x:b0,y:b1,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,leftstick:b10,rightstick:b11,\n"
+"341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,\n"
+"c0111352000000000000504944564944,Battalife Joystick,platform:Windows,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1,\n"
+"100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Windows,\n"
+"79000600000000000000504944564944,NGS Phantom,a:b2,b:b3,y:b1,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
+"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,\n"
+"6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
+"6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
+"6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
+"6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
+"4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,\n"
+"4c05000000000000c405000000000000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,\n"
+"4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,\n"
+"5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
+"891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X,\n"
+"4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Mac OS X,\n"
+"8f0e0000000000000300000000000000,Piranha xtreme,platform:Mac OS X,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
+"0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
+"79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,\n"
+"4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
+"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,platform:Mac OS X,\n"
+"83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X,\n"
+"bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X,\n"
+"79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,platform:Mac OS X,\n"
+"5e04000000000000dd02000000000000,Xbox One Wired Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"5e04000000000000ea02000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"5e04000000000000e002000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,platform:Mac OS X,\n"
+"79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,platform:Mac OS X,\n"
+"2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,\n"
+"351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
+"b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
+"81170000000000007e05000000000000,Sega Saturn,x:b0,a:b2,b:b4,y:b6,start:b13,dpleft:b15,dpdown:b16,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,lefttrigger:b10,rightshoulder:b9,righttrigger:a4,righttrigger:b11,leftx:a0,lefty:a2,platform:Mac OS X,\n"
+"10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
+"d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7,\n"
+"0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4,\n"
+"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,\n"
+"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,\n"
+"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,\n"
+"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,\n"
+"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,\n"
+"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,\n"
+"030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
+"050000004c050000c405000000010000,Sony DualShock 4 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,\n"
+"030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
+"050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
+"030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
+"030000006f0e00003001000001010000,EA Sports PS3 Controller,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
+"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
+"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,\n"
+"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
+"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,\n"
+"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,\n"
+"030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
+"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
+"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
+"030000006d04000016c2000010010000,Logitech Logitech Dual Action,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux,\n"
+"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,platform:Linux,\n"
+"030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"05000000d6200000ad0d000001000000,Moga Pro,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,\n"
+"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
+"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,\n"
+"0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,\n"
+"0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,\n"
+"030000006f0e00001f01000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"03000000280400000140000000010000,Gravis GamePad Pro USB ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,\n"
+"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
+"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,platform:Linux,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,\n"
+"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
+"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,\n"
+"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
+"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,\n"
+"050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,\n"
+"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a3,rightx:a1,righty:a4,\n"
+"03000000666600000488000000010000,Super Joy Box 5 Pro,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,\n"
+"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,\n"
+"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,\n"
+"030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"030000005e040000d102000001010000,Microsoft X-Box One pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux,\n"
+"03000000790000001100000010010000,RetroLink Saturn Classic Controller,platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
+"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,\n"
+"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
+"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,\n"
+"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7\n"
+"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
+"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"030000006f0e00001304000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
+"03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
+"03000000790000001100000010010000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
+"03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,platform:Linux,\n"
+"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,\n"
+"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,platform:Linux,\n"
+"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,platform:Linux,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,platform:Linux,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux,\n"
+"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,platform:Linux,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,\n"
+"05000000102800000900000000010000,8Bitdo SFC30 GamePad,platform:Linux,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
+"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,\n"
+"030000000d0f00000d00000000010000,hori,platform:Linux,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,\n"
+"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,\n"
+"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,platform:Linux,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,\n"
+"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),platform:Linux,a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,\n"
+"05000000010000000100000003000000,Nintendo Wiimote,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
+"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
+"030000006f0e00000103000000020000,Logic3 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
+"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
+"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5,\n"
+"05000000a00500003232000001000000,8Bitdo Zero GamePad,platform:Linux,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
+"030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Linux,\n"
+"03000000100800000300000010010000,USB Gamepad,platform:Linux,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
+"05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
+"03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,\n"
+
+"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,\n"
+"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,\n"
+"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,\n"
+"78696e70757404000000000000000000,XInput Flight 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,\n"
+"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,\n"
+"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,\n"
+"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,\n";
+
diff --git a/src/external/glfw/src/mappings.h.in b/src/external/glfw/src/mappings.h.in
new file mode 100644
index 00000000..bf720670
--- /dev/null
+++ b/src/external/glfw/src/mappings.h.in
@@ -0,0 +1,70 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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 mappings.h.in, this file is used by CMake to produce the mappings.h
+// header file. If you are adding a GLFW specific gamepad mapping, this is
+// where to put it.
+//========================================================================
+// As mappings.h, this provides all pre-defined gamepad mappings, including
+// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
+// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
+// This file can be re-generated from mappings.h.in and the upstream
+// gamecontrollerdb.txt with the GenerateMappings.cmake script.
+//========================================================================
+
+// All gamepad mappings not labeled GLFW are copied from the
+// SDL_GameControllerDB project under the following license:
+//
+// Simple DirectMedia Layer
+// Copyright (C) 1997-2013 Sam Lantinga <[email protected]>
+//
+// 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.
+
+const char* _glfwDefaultMappings =
+@GLFW_GAMEPAD_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,\n"
+"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,\n"
+"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,\n"
+"78696e70757404000000000000000000,XInput Flight 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,\n"
+"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,\n"
+"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,\n"
+"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,\n";
+
diff --git a/src/external/glfw/src/mir_init.c b/src/external/glfw/src/mir_init.c
new file mode 100644
index 00000000..5f9ed373
--- /dev/null
+++ b/src/external/glfw/src/mir_init.c
@@ -0,0 +1,240 @@
+//========================================================================
+// GLFW 3.3 Mir - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014-2017 Brandon Schaefer <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <linux/input.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+// Create key code translation tables
+//
+static void createKeyTables(void)
+{
+ int scancode;
+
+ memset(_glfw.mir.keycodes, -1, sizeof(_glfw.mir.keycodes));
+ memset(_glfw.mir.scancodes, -1, sizeof(_glfw.mir.scancodes));
+
+ _glfw.mir.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT;
+ _glfw.mir.keycodes[KEY_1] = GLFW_KEY_1;
+ _glfw.mir.keycodes[KEY_2] = GLFW_KEY_2;
+ _glfw.mir.keycodes[KEY_3] = GLFW_KEY_3;
+ _glfw.mir.keycodes[KEY_4] = GLFW_KEY_4;
+ _glfw.mir.keycodes[KEY_5] = GLFW_KEY_5;
+ _glfw.mir.keycodes[KEY_6] = GLFW_KEY_6;
+ _glfw.mir.keycodes[KEY_7] = GLFW_KEY_7;
+ _glfw.mir.keycodes[KEY_8] = GLFW_KEY_8;
+ _glfw.mir.keycodes[KEY_9] = GLFW_KEY_9;
+ _glfw.mir.keycodes[KEY_0] = GLFW_KEY_0;
+ _glfw.mir.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
+ _glfw.mir.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
+ _glfw.mir.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
+ _glfw.mir.keycodes[KEY_Q] = GLFW_KEY_Q;
+ _glfw.mir.keycodes[KEY_W] = GLFW_KEY_W;
+ _glfw.mir.keycodes[KEY_E] = GLFW_KEY_E;
+ _glfw.mir.keycodes[KEY_R] = GLFW_KEY_R;
+ _glfw.mir.keycodes[KEY_T] = GLFW_KEY_T;
+ _glfw.mir.keycodes[KEY_Y] = GLFW_KEY_Y;
+ _glfw.mir.keycodes[KEY_U] = GLFW_KEY_U;
+ _glfw.mir.keycodes[KEY_I] = GLFW_KEY_I;
+ _glfw.mir.keycodes[KEY_O] = GLFW_KEY_O;
+ _glfw.mir.keycodes[KEY_P] = GLFW_KEY_P;
+ _glfw.mir.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET;
+ _glfw.mir.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
+ _glfw.mir.keycodes[KEY_A] = GLFW_KEY_A;
+ _glfw.mir.keycodes[KEY_S] = GLFW_KEY_S;
+ _glfw.mir.keycodes[KEY_D] = GLFW_KEY_D;
+ _glfw.mir.keycodes[KEY_F] = GLFW_KEY_F;
+ _glfw.mir.keycodes[KEY_G] = GLFW_KEY_G;
+ _glfw.mir.keycodes[KEY_H] = GLFW_KEY_H;
+ _glfw.mir.keycodes[KEY_J] = GLFW_KEY_J;
+ _glfw.mir.keycodes[KEY_K] = GLFW_KEY_K;
+ _glfw.mir.keycodes[KEY_L] = GLFW_KEY_L;
+ _glfw.mir.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON;
+ _glfw.mir.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
+ _glfw.mir.keycodes[KEY_Z] = GLFW_KEY_Z;
+ _glfw.mir.keycodes[KEY_X] = GLFW_KEY_X;
+ _glfw.mir.keycodes[KEY_C] = GLFW_KEY_C;
+ _glfw.mir.keycodes[KEY_V] = GLFW_KEY_V;
+ _glfw.mir.keycodes[KEY_B] = GLFW_KEY_B;
+ _glfw.mir.keycodes[KEY_N] = GLFW_KEY_N;
+ _glfw.mir.keycodes[KEY_M] = GLFW_KEY_M;
+ _glfw.mir.keycodes[KEY_COMMA] = GLFW_KEY_COMMA;
+ _glfw.mir.keycodes[KEY_DOT] = GLFW_KEY_PERIOD;
+ _glfw.mir.keycodes[KEY_SLASH] = GLFW_KEY_SLASH;
+ _glfw.mir.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH;
+ _glfw.mir.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE;
+ _glfw.mir.keycodes[KEY_TAB] = GLFW_KEY_TAB;
+ _glfw.mir.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT;
+ _glfw.mir.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
+ _glfw.mir.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL;
+ _glfw.mir.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL;
+ _glfw.mir.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT;
+ _glfw.mir.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
+ _glfw.mir.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
+ _glfw.mir.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
+ _glfw.mir.keycodes[KEY_MENU] = GLFW_KEY_MENU;
+ _glfw.mir.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
+ _glfw.mir.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
+ _glfw.mir.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
+ _glfw.mir.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
+ _glfw.mir.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE;
+ _glfw.mir.keycodes[KEY_DELETE] = GLFW_KEY_DELETE;
+ _glfw.mir.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE;
+ _glfw.mir.keycodes[KEY_ENTER] = GLFW_KEY_ENTER;
+ _glfw.mir.keycodes[KEY_HOME] = GLFW_KEY_HOME;
+ _glfw.mir.keycodes[KEY_END] = GLFW_KEY_END;
+ _glfw.mir.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP;
+ _glfw.mir.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN;
+ _glfw.mir.keycodes[KEY_INSERT] = GLFW_KEY_INSERT;
+ _glfw.mir.keycodes[KEY_LEFT] = GLFW_KEY_LEFT;
+ _glfw.mir.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT;
+ _glfw.mir.keycodes[KEY_DOWN] = GLFW_KEY_DOWN;
+ _glfw.mir.keycodes[KEY_UP] = GLFW_KEY_UP;
+ _glfw.mir.keycodes[KEY_F1] = GLFW_KEY_F1;
+ _glfw.mir.keycodes[KEY_F2] = GLFW_KEY_F2;
+ _glfw.mir.keycodes[KEY_F3] = GLFW_KEY_F3;
+ _glfw.mir.keycodes[KEY_F4] = GLFW_KEY_F4;
+ _glfw.mir.keycodes[KEY_F5] = GLFW_KEY_F5;
+ _glfw.mir.keycodes[KEY_F6] = GLFW_KEY_F6;
+ _glfw.mir.keycodes[KEY_F7] = GLFW_KEY_F7;
+ _glfw.mir.keycodes[KEY_F8] = GLFW_KEY_F8;
+ _glfw.mir.keycodes[KEY_F9] = GLFW_KEY_F9;
+ _glfw.mir.keycodes[KEY_F10] = GLFW_KEY_F10;
+ _glfw.mir.keycodes[KEY_F11] = GLFW_KEY_F11;
+ _glfw.mir.keycodes[KEY_F12] = GLFW_KEY_F12;
+ _glfw.mir.keycodes[KEY_F13] = GLFW_KEY_F13;
+ _glfw.mir.keycodes[KEY_F14] = GLFW_KEY_F14;
+ _glfw.mir.keycodes[KEY_F15] = GLFW_KEY_F15;
+ _glfw.mir.keycodes[KEY_F16] = GLFW_KEY_F16;
+ _glfw.mir.keycodes[KEY_F17] = GLFW_KEY_F17;
+ _glfw.mir.keycodes[KEY_F18] = GLFW_KEY_F18;
+ _glfw.mir.keycodes[KEY_F19] = GLFW_KEY_F19;
+ _glfw.mir.keycodes[KEY_F20] = GLFW_KEY_F20;
+ _glfw.mir.keycodes[KEY_F21] = GLFW_KEY_F21;
+ _glfw.mir.keycodes[KEY_F22] = GLFW_KEY_F22;
+ _glfw.mir.keycodes[KEY_F23] = GLFW_KEY_F23;
+ _glfw.mir.keycodes[KEY_F24] = GLFW_KEY_F24;
+ _glfw.mir.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
+ _glfw.mir.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY;
+ _glfw.mir.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
+ _glfw.mir.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
+ _glfw.mir.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
+ _glfw.mir.keycodes[KEY_KP1] = GLFW_KEY_KP_1;
+ _glfw.mir.keycodes[KEY_KP2] = GLFW_KEY_KP_2;
+ _glfw.mir.keycodes[KEY_KP3] = GLFW_KEY_KP_3;
+ _glfw.mir.keycodes[KEY_KP4] = GLFW_KEY_KP_4;
+ _glfw.mir.keycodes[KEY_KP5] = GLFW_KEY_KP_5;
+ _glfw.mir.keycodes[KEY_KP6] = GLFW_KEY_KP_6;
+ _glfw.mir.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
+ _glfw.mir.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
+ _glfw.mir.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
+ _glfw.mir.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL;
+ _glfw.mir.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
+ _glfw.mir.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
+
+ for (scancode = 0; scancode < 256; scancode++)
+ {
+ if (_glfw.mir.keycodes[scancode] > 0)
+ _glfw.mir.scancodes[_glfw.mir.keycodes[scancode]] = scancode;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformInit(void)
+{
+ int error;
+
+ _glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);
+
+ if (!mir_connection_is_valid(_glfw.mir.connection))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unable to connect to server: %s",
+ mir_connection_get_error_message(_glfw.mir.connection));
+
+ return GLFW_FALSE;
+ }
+
+ _glfw.mir.display =
+ mir_connection_get_egl_native_display(_glfw.mir.connection);
+
+ createKeyTables();
+
+ if (!_glfwInitJoysticksLinux())
+ return GLFW_FALSE;
+
+ _glfwInitTimerPOSIX();
+
+ _glfw.mir.eventQueue = calloc(1, sizeof(EventQueue));
+ _glfwInitEventQueueMir(_glfw.mir.eventQueue);
+
+ error = pthread_mutex_init(&_glfw.mir.eventMutex, NULL);
+ if (error)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Failed to create event mutex: %s",
+ strerror(error));
+ return GLFW_FALSE;
+ }
+
+ _glfwPollMonitorsMir();
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformTerminate(void)
+{
+ _glfwTerminateEGL();
+ _glfwTerminateJoysticksLinux();
+
+ _glfwDeleteEventQueueMir(_glfw.mir.eventQueue);
+
+ pthread_mutex_destroy(&_glfw.mir.eventMutex);
+
+ mir_connection_release(_glfw.mir.connection);
+}
+
+const char* _glfwPlatformGetVersionString(void)
+{
+ return _GLFW_VERSION_NUMBER " Mir EGL"
+#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
+ " clock_gettime"
+#else
+ " gettimeofday"
+#endif
+ " evdev"
+#if defined(_GLFW_BUILD_DLL)
+ " shared"
+#endif
+ ;
+}
+
diff --git a/src/external/glfw/src/mir_monitor.c b/src/external/glfw/src/mir_monitor.c
new file mode 100644
index 00000000..b300cac0
--- /dev/null
+++ b/src/external/glfw/src/mir_monitor.c
@@ -0,0 +1,214 @@
+//========================================================================
+// GLFW 3.3 Mir - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014-2017 Brandon Schaefer <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdlib.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Poll for changes in the set of connected monitors
+//
+void _glfwPollMonitorsMir(void)
+{
+ int i;
+ MirDisplayConfig* displayConfig =
+ mir_connection_create_display_configuration(_glfw.mir.connection);
+
+ int numOutputs = mir_display_config_get_num_outputs(displayConfig);
+
+ for (i = 0; i < numOutputs; i++)
+ {
+ const MirOutput* output = mir_display_config_get_output(displayConfig, i);
+ MirOutputConnectionState state = mir_output_get_connection_state(output);
+ bool enabled = mir_output_is_enabled(output);
+
+ if (enabled && state == mir_output_connection_state_connected)
+ {
+ int widthMM = mir_output_get_physical_width_mm(output);
+ int heightMM = mir_output_get_physical_height_mm(output);
+ int x = mir_output_get_position_x(output);
+ int y = mir_output_get_position_y(output);
+ int id = mir_output_get_id(output);
+ size_t currentMode = mir_output_get_current_mode_index(output);
+ const char* name = mir_output_type_name(mir_output_get_type(output));
+
+ _GLFWmonitor* monitor = _glfwAllocMonitor(name,
+ widthMM,
+ heightMM);
+ monitor->mir.x = x;
+ monitor->mir.y = y;
+ monitor->mir.outputId = id;
+ monitor->mir.curMode = currentMode;
+ monitor->modes = _glfwPlatformGetVideoModes(monitor, &monitor->modeCount);
+
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
+ }
+ }
+
+ mir_display_config_release(displayConfig);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
+{
+ if (xpos)
+ *xpos = monitor->mir.x;
+ if (ypos)
+ *ypos = monitor->mir.y;
+}
+
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = 1.f;
+ if (yscale)
+ *yscale = 1.f;
+}
+
+static void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)
+{
+ switch (pf)
+ {
+ case mir_pixel_format_rgb_565:
+ mode->redBits = 5;
+ mode->greenBits = 6;
+ mode->blueBits = 5;
+ break;
+ case mir_pixel_format_rgba_5551:
+ mode->redBits = 5;
+ mode->greenBits = 5;
+ mode->blueBits = 5;
+ break;
+ case mir_pixel_format_rgba_4444:
+ mode->redBits = 4;
+ mode->greenBits = 4;
+ mode->blueBits = 4;
+ break;
+ case mir_pixel_format_abgr_8888:
+ case mir_pixel_format_xbgr_8888:
+ case mir_pixel_format_argb_8888:
+ case mir_pixel_format_xrgb_8888:
+ case mir_pixel_format_bgr_888:
+ case mir_pixel_format_rgb_888:
+ default:
+ mode->redBits = 8;
+ mode->greenBits = 8;
+ mode->blueBits = 8;
+ break;
+ }
+}
+
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
+{
+ int i;
+ GLFWvidmode* modes = NULL;
+ MirDisplayConfig* displayConfig =
+ mir_connection_create_display_configuration(_glfw.mir.connection);
+
+ int numOutputs = mir_display_config_get_num_outputs(displayConfig);
+
+ for (i = 0; i < numOutputs; i++)
+ {
+ const MirOutput* output = mir_display_config_get_output(displayConfig, i);
+ int id = mir_output_get_id(output);
+
+ if (id != monitor->mir.outputId)
+ continue;
+
+ MirOutputConnectionState state = mir_output_get_connection_state(output);
+ bool enabled = mir_output_is_enabled(output);
+
+ // We must have been disconnected
+ if (!enabled || state != mir_output_connection_state_connected)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Monitor no longer connected");
+ return NULL;
+ }
+
+ int numModes = mir_output_get_num_modes(output);
+ modes = calloc(numModes, sizeof(GLFWvidmode));
+
+ for (*found = 0; *found < numModes; (*found)++)
+ {
+ const MirOutputMode* mode = mir_output_get_mode(output, *found);
+ int width = mir_output_mode_get_width(mode);
+ int height = mir_output_mode_get_height(mode);
+ double refreshRate = mir_output_mode_get_refresh_rate(mode);
+ MirPixelFormat currentFormat = mir_output_get_current_pixel_format(output);
+
+ modes[*found].width = width;
+ modes[*found].height = height;
+ modes[*found].refreshRate = refreshRate;
+
+ FillInRGBBitsFromPixelFormat(&modes[*found], currentFormat);
+ }
+
+ break;
+ }
+
+ mir_display_config_release(displayConfig);
+
+ return modes;
+}
+
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
+{
+ *mode = monitor->modes[monitor->mir.curMode];
+}
+
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI int glfwGetMirMonitor(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(0);
+ return monitor->mir.outputId;
+}
diff --git a/src/external/glfw/src/mir_platform.h b/src/external/glfw/src/mir_platform.h
new file mode 100644
index 00000000..da00a326
--- /dev/null
+++ b/src/external/glfw/src/mir_platform.h
@@ -0,0 +1,133 @@
+//========================================================================
+// GLFW 3.3 Mir - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014-2017 Brandon Schaefer <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <sys/queue.h>
+#include <pthread.h>
+#include <dlfcn.h>
+
+#include <mir_toolkit/mir_client_library.h>
+
+typedef VkFlags VkMirWindowCreateFlagsKHR;
+
+typedef struct VkMirWindowCreateInfoKHR
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkMirWindowCreateFlagsKHR flags;
+ MirConnection* connection;
+ MirWindow* mirWindow;
+} VkMirWindowCreateInfoKHR;
+
+typedef VkResult (APIENTRY *PFN_vkCreateMirWindowKHR)(VkInstance,const VkMirWindowCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);
+
+#include "posix_thread.h"
+#include "posix_time.h"
+#include "linux_joystick.h"
+#include "xkb_unicode.h"
+#include "egl_context.h"
+#include "osmesa_context.h"
+
+#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
+#define _glfw_dlclose(handle) dlclose(handle)
+#define _glfw_dlsym(handle, name) dlsym(handle, name)
+
+#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.nativeWindow)
+#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
+
+#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir
+#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorMir mir
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryMir mir
+#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorMir mir
+
+#define _GLFW_PLATFORM_CONTEXT_STATE
+#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
+
+
+// Mir-specific Event Queue
+//
+typedef struct EventQueue
+{
+ TAILQ_HEAD(, EventNode) head;
+} EventQueue;
+
+// Mir-specific per-window data
+//
+typedef struct _GLFWwindowMir
+{
+ MirWindow* window;
+ int width;
+ int height;
+ MirEGLNativeWindowType nativeWindow;
+ _GLFWcursor* currentCursor;
+
+} _GLFWwindowMir;
+
+// Mir-specific per-monitor data
+//
+typedef struct _GLFWmonitorMir
+{
+ int curMode;
+ int outputId;
+ int x;
+ int y;
+
+} _GLFWmonitorMir;
+
+// Mir-specific global data
+//
+typedef struct _GLFWlibraryMir
+{
+ MirConnection* connection;
+ MirEGLNativeDisplayType display;
+ EventQueue* eventQueue;
+
+ short int keycodes[256];
+ short int scancodes[GLFW_KEY_LAST + 1];
+
+ pthread_mutex_t eventMutex;
+ pthread_cond_t eventCond;
+
+ // The window whose disabled cursor mode is active
+ _GLFWwindow* disabledCursorWindow;
+
+} _GLFWlibraryMir;
+
+// Mir-specific per-cursor data
+// TODO: Only system cursors are implemented in Mir atm. Need to wait for support.
+//
+typedef struct _GLFWcursorMir
+{
+ MirCursorConfiguration* conf;
+ MirBufferStream* customCursor;
+ char const* cursorName; // only needed for system cursors
+} _GLFWcursorMir;
+
+
+extern void _glfwPollMonitorsMir(void);
+extern void _glfwInitEventQueueMir(EventQueue* queue);
+extern void _glfwDeleteEventQueueMir(EventQueue* queue);
+
diff --git a/src/external/glfw/src/mir_window.c b/src/external/glfw/src/mir_window.c
new file mode 100644
index 00000000..c752cdb4
--- /dev/null
+++ b/src/external/glfw/src/mir_window.c
@@ -0,0 +1,955 @@
+//========================================================================
+// GLFW 3.3 Mir - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014-2017 Brandon Schaefer <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <linux/input.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+typedef struct EventNode
+{
+ TAILQ_ENTRY(EventNode) entries;
+ const MirEvent* event;
+ _GLFWwindow* window;
+} EventNode;
+
+static void deleteNode(EventQueue* queue, EventNode* node)
+{
+ mir_event_unref(node->event);
+ free(node);
+}
+
+static GLFWbool emptyEventQueue(EventQueue* queue)
+{
+ return queue->head.tqh_first == NULL;
+}
+
+// TODO The mir_event_ref is not supposed to be used but ... its needed
+// in this case. Need to wait until we can read from an FD set up by mir
+// for single threaded event handling.
+static EventNode* newEventNode(const MirEvent* event, _GLFWwindow* context)
+{
+ EventNode* newNode = calloc(1, sizeof(EventNode));
+ newNode->event = mir_event_ref(event);
+ newNode->window = context;
+
+ return newNode;
+}
+
+static void enqueueEvent(const MirEvent* event, _GLFWwindow* context)
+{
+ pthread_mutex_lock(&_glfw.mir.eventMutex);
+
+ EventNode* newNode = newEventNode(event, context);
+ TAILQ_INSERT_TAIL(&_glfw.mir.eventQueue->head, newNode, entries);
+
+ pthread_cond_signal(&_glfw.mir.eventCond);
+
+ pthread_mutex_unlock(&_glfw.mir.eventMutex);
+}
+
+static EventNode* dequeueEvent(EventQueue* queue)
+{
+ EventNode* node = NULL;
+
+ pthread_mutex_lock(&_glfw.mir.eventMutex);
+
+ node = queue->head.tqh_first;
+
+ if (node)
+ TAILQ_REMOVE(&queue->head, node, entries);
+
+ pthread_mutex_unlock(&_glfw.mir.eventMutex);
+
+ return node;
+}
+
+static MirPixelFormat findValidPixelFormat(void)
+{
+ unsigned int i, validFormats, mirPixelFormats = 32;
+ MirPixelFormat formats[mir_pixel_formats];
+
+ mir_connection_get_available_surface_formats(_glfw.mir.connection, formats,
+ mirPixelFormats, &validFormats);
+
+ for (i = 0; i < validFormats; i++)
+ {
+ if (formats[i] == mir_pixel_format_abgr_8888 ||
+ formats[i] == mir_pixel_format_xbgr_8888 ||
+ formats[i] == mir_pixel_format_argb_8888 ||
+ formats[i] == mir_pixel_format_xrgb_8888)
+ {
+ return formats[i];
+ }
+ }
+
+ return mir_pixel_format_invalid;
+}
+
+static int mirModToGLFWMod(uint32_t mods)
+{
+ int publicMods = 0x0;
+
+ if (mods & mir_input_event_modifier_alt)
+ publicMods |= GLFW_MOD_ALT;
+ else if (mods & mir_input_event_modifier_shift)
+ publicMods |= GLFW_MOD_SHIFT;
+ else if (mods & mir_input_event_modifier_ctrl)
+ publicMods |= GLFW_MOD_CONTROL;
+ else if (mods & mir_input_event_modifier_meta)
+ publicMods |= GLFW_MOD_SUPER;
+
+ return publicMods;
+}
+
+static int toGLFWKeyCode(uint32_t key)
+{
+ if (key < sizeof(_glfw.mir.keycodes) / sizeof(_glfw.mir.keycodes[0]))
+ return _glfw.mir.keycodes[key];
+
+ return GLFW_KEY_UNKNOWN;
+}
+
+static void handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* window)
+{
+ const int action = mir_keyboard_event_action (key_event);
+ const int scan_code = mir_keyboard_event_scan_code(key_event);
+ const int key_code = mir_keyboard_event_key_code (key_event);
+ const int modifiers = mir_keyboard_event_modifiers(key_event);
+
+ const int pressed = action == mir_keyboard_action_up ? GLFW_RELEASE : GLFW_PRESS;
+ const int mods = mirModToGLFWMod(modifiers);
+ const long text = _glfwKeySym2Unicode(key_code);
+ const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
+
+ _glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods);
+
+ if (text != -1)
+ _glfwInputChar(window, text, mods, plain);
+}
+
+static void handlePointerButton(_GLFWwindow* window,
+ int pressed,
+ const MirPointerEvent* pointer_event)
+{
+ int mods = mir_pointer_event_modifiers(pointer_event);
+ const int publicMods = mirModToGLFWMod(mods);
+ MirPointerButton button = mir_pointer_button_primary;
+ static uint32_t oldButtonStates = 0;
+ uint32_t newButtonStates = mir_pointer_event_buttons(pointer_event);
+ int publicButton = GLFW_MOUSE_BUTTON_LEFT;
+
+ // XOR our old button states our new states to figure out what was added or removed
+ button = newButtonStates ^ oldButtonStates;
+
+ switch (button)
+ {
+ case mir_pointer_button_primary:
+ publicButton = GLFW_MOUSE_BUTTON_LEFT;
+ break;
+ case mir_pointer_button_secondary:
+ publicButton = GLFW_MOUSE_BUTTON_RIGHT;
+ break;
+ case mir_pointer_button_tertiary:
+ publicButton = GLFW_MOUSE_BUTTON_MIDDLE;
+ break;
+ case mir_pointer_button_forward:
+ // FIXME What is the forward button?
+ publicButton = GLFW_MOUSE_BUTTON_4;
+ break;
+ case mir_pointer_button_back:
+ // FIXME What is the back button?
+ publicButton = GLFW_MOUSE_BUTTON_5;
+ break;
+ default:
+ break;
+ }
+
+ oldButtonStates = newButtonStates;
+
+ _glfwInputMouseClick(window, publicButton, pressed, publicMods);
+}
+
+static void handlePointerMotion(_GLFWwindow* window,
+ const MirPointerEvent* pointer_event)
+{
+ const int hscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
+ const int vscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
+
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ {
+ if (_glfw.mir.disabledCursorWindow != window)
+ return;
+
+ const int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_x);
+ const int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_relative_y);
+ const int current_x = window->virtualCursorPosX;
+ const int current_y = window->virtualCursorPosY;
+
+ _glfwInputCursorPos(window, dx + current_x, dy + current_y);
+ }
+ else
+ {
+ const int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x);
+ const int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y);
+
+ _glfwInputCursorPos(window, x, y);
+ }
+
+ if (hscroll != 0 || vscroll != 0)
+ _glfwInputScroll(window, hscroll, vscroll);
+}
+
+static void handlePointerEvent(const MirPointerEvent* pointer_event,
+ _GLFWwindow* window)
+{
+ int action = mir_pointer_event_action(pointer_event);
+
+ switch (action)
+ {
+ case mir_pointer_action_button_down:
+ handlePointerButton(window, GLFW_PRESS, pointer_event);
+ break;
+ case mir_pointer_action_button_up:
+ handlePointerButton(window, GLFW_RELEASE, pointer_event);
+ break;
+ case mir_pointer_action_motion:
+ handlePointerMotion(window, pointer_event);
+ break;
+ case mir_pointer_action_enter:
+ case mir_pointer_action_leave:
+ break;
+ default:
+ break;
+ }
+}
+
+static void handleInput(const MirInputEvent* input_event, _GLFWwindow* window)
+{
+ int type = mir_input_event_get_type(input_event);
+
+ switch (type)
+ {
+ case mir_input_event_type_key:
+ handleKeyEvent(mir_input_event_get_keyboard_event(input_event), window);
+ break;
+ case mir_input_event_type_pointer:
+ handlePointerEvent(mir_input_event_get_pointer_event(input_event), window);
+ break;
+ default:
+ break;
+ }
+}
+
+static void handleEvent(const MirEvent* event, _GLFWwindow* window)
+{
+ int type = mir_event_get_type(event);
+
+ switch (type)
+ {
+ case mir_event_type_input:
+ handleInput(mir_event_get_input_event(event), window);
+ break;
+ default:
+ break;
+ }
+}
+
+static void addNewEvent(MirWindow* window, const MirEvent* event, void* context)
+{
+ enqueueEvent(event, context);
+}
+
+static GLFWbool createWindow(_GLFWwindow* window)
+{
+ MirWindowSpec* spec;
+ MirBufferUsage buffer_usage = mir_buffer_usage_hardware;
+ MirPixelFormat pixel_format = findValidPixelFormat();
+
+ if (pixel_format == mir_pixel_format_invalid)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unable to find a correct pixel format");
+ return GLFW_FALSE;
+ }
+
+ spec = mir_create_normal_window_spec(_glfw.mir.connection,
+ window->mir.width,
+ window->mir.height);
+
+ mir_window_spec_set_pixel_format(spec, pixel_format);
+ mir_window_spec_set_buffer_usage(spec, buffer_usage);
+
+ window->mir.window = mir_create_window_sync(spec);
+ mir_window_spec_release(spec);
+
+ if (!mir_window_is_valid(window->mir.window))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unable to create window: %s",
+ mir_window_get_error_message(window->mir.window));
+
+ return GLFW_FALSE;
+ }
+
+ mir_window_set_event_handler(window->mir.window, addNewEvent, window);
+
+ return GLFW_TRUE;
+}
+
+static void setWindowConfinement(_GLFWwindow* window, MirPointerConfinementState state)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_pointer_confinement(spec, state);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwInitEventQueueMir(EventQueue* queue)
+{
+ TAILQ_INIT(&queue->head);
+}
+
+void _glfwDeleteEventQueueMir(EventQueue* queue)
+{
+ if (queue)
+ {
+ EventNode* node, *node_next;
+ node = queue->head.tqh_first;
+
+ while (node != NULL)
+ {
+ node_next = node->entries.tqe_next;
+
+ TAILQ_REMOVE(&queue->head, node, entries);
+ deleteNode(queue, node);
+
+ node = node_next;
+ }
+
+ free(queue);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ if (window->monitor)
+ {
+ GLFWvidmode mode;
+ _glfwPlatformGetVideoMode(window->monitor, &mode);
+
+ mir_window_set_state(window->mir.window, mir_window_state_fullscreen);
+
+ if (wndconfig->width > mode.width || wndconfig->height > mode.height)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Requested window size too large: %ix%i",
+ wndconfig->width, wndconfig->height);
+
+ return GLFW_FALSE;
+ }
+ }
+
+ window->mir.width = wndconfig->width;
+ window->mir.height = wndconfig->height;
+ window->mir.currentCursor = NULL;
+
+ if (!createWindow(window))
+ return GLFW_FALSE;
+
+ window->mir.nativeWindow = mir_buffer_stream_get_egl_native_window(
+ mir_window_get_buffer_stream(window->mir.window));
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
+ ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
+ {
+ if (!_glfwInitEGL())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwInitOSMesa())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+{
+ if (_glfw.mir.disabledCursorWindow == window)
+ _glfw.mir.disabledCursorWindow = NULL;
+
+ if (mir_window_is_valid(window->mir.window))
+ {
+ mir_window_release_sync(window->mir.window);
+ window->mir.window= NULL;
+ }
+
+ if (window->context.destroy)
+ window->context.destroy(window);
+}
+
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_name(spec, title);
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
+ int count, const GLFWimage* images)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_width (spec, width);
+ mir_window_spec_set_height(spec, height);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_max_width (spec, maxwidth);
+ mir_window_spec_set_max_height(spec, maxheight);
+ mir_window_spec_set_min_width (spec, minwidth);
+ mir_window_spec_set_min_height(spec, minheight);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
+{
+ if (width)
+ *width = window->mir.width;
+ if (height)
+ *height = window->mir.height;
+}
+
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = 1.f;
+ if (yscale)
+ *yscale = 1.f;
+}
+
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_state(spec, mir_window_state_minimized);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_state(spec, mir_window_state_restored);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_state(spec, mir_window_state_maximized);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_state(spec, mir_window_state_hidden);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+ MirWindowSpec* spec;
+
+ spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_state(spec, mir_window_state_restored);
+
+ mir_window_apply_spec(window->mir.window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformFocusWindow(_GLFWwindow* window)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+ _GLFWmonitor* monitor,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+int _glfwPlatformWindowFocused(_GLFWwindow* window)
+{
+ return mir_window_get_focus_state(window->mir.window) == mir_window_focus_state_focused;
+}
+
+int _glfwPlatformWindowIconified(_GLFWwindow* window)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+ return GLFW_FALSE;
+}
+
+int _glfwPlatformWindowVisible(_GLFWwindow* window)
+{
+ return mir_window_get_visibility(window->mir.window) == mir_window_visibility_exposed;
+}
+
+int _glfwPlatformWindowMaximized(_GLFWwindow* window)
+{
+ return mir_window_get_state(window->mir.window) == mir_window_state_maximized;
+}
+
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+ return GLFW_FALSE;
+}
+
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformPollEvents(void)
+{
+ EventNode* node = NULL;
+
+ while ((node = dequeueEvent(_glfw.mir.eventQueue)))
+ {
+ handleEvent(node->event, node->window);
+ deleteNode(_glfw.mir.eventQueue, node);
+ }
+}
+
+void _glfwPlatformWaitEvents(void)
+{
+ pthread_mutex_lock(&_glfw.mir.eventMutex);
+
+ while (emptyEventQueue(_glfw.mir.eventQueue))
+ pthread_cond_wait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex);
+
+ pthread_mutex_unlock(&_glfw.mir.eventMutex);
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformWaitEventsTimeout(double timeout)
+{
+ pthread_mutex_lock(&_glfw.mir.eventMutex);
+
+ if (emptyEventQueue(_glfw.mir.eventQueue))
+ {
+ struct timespec time;
+ clock_gettime(CLOCK_REALTIME, &time);
+ time.tv_sec += (long) timeout;
+ time.tv_nsec += (long) ((timeout - (long) timeout) * 1e9);
+ pthread_cond_timedwait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex, &time);
+ }
+
+ pthread_mutex_unlock(&_glfw.mir.eventMutex);
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformPostEmptyEvent(void)
+{
+}
+
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
+{
+ if (width)
+ *width = window->mir.width;
+ if (height)
+ *height = window->mir.height;
+}
+
+int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
+ const GLFWimage* image,
+ int xhot, int yhot)
+{
+ MirBufferStream* stream;
+
+ int i_w = image->width;
+ int i_h = image->height;
+
+ stream = mir_connection_create_buffer_stream_sync(_glfw.mir.connection,
+ i_w, i_h,
+ mir_pixel_format_argb_8888,
+ mir_buffer_usage_software);
+
+ cursor->mir.conf = mir_cursor_configuration_from_buffer_stream(stream, xhot, yhot);
+
+ MirGraphicsRegion region;
+ mir_buffer_stream_get_graphics_region(stream, &region);
+
+ unsigned char* pixels = image->pixels;
+ char* dest = region.vaddr;
+ int i;
+
+ for (i = 0; i < i_w * i_h; i++, pixels += 4)
+ {
+ unsigned int alpha = pixels[3];
+ *dest++ = (char)(pixels[2] * alpha / 255);
+ *dest++ = (char)(pixels[1] * alpha / 255);
+ *dest++ = (char)(pixels[0] * alpha / 255);
+ *dest++ = (char)alpha;
+ }
+
+ mir_buffer_stream_swap_buffers_sync(stream);
+ cursor->mir.customCursor = stream;
+
+ return GLFW_TRUE;
+}
+
+static const char* getSystemCursorName(int shape)
+{
+ switch (shape)
+ {
+ case GLFW_ARROW_CURSOR:
+ return mir_arrow_cursor_name;
+ case GLFW_IBEAM_CURSOR:
+ return mir_caret_cursor_name;
+ case GLFW_CROSSHAIR_CURSOR:
+ return mir_crosshair_cursor_name;
+ case GLFW_HAND_CURSOR:
+ return mir_open_hand_cursor_name;
+ case GLFW_HRESIZE_CURSOR:
+ return mir_horizontal_resize_cursor_name;
+ case GLFW_VRESIZE_CURSOR:
+ return mir_vertical_resize_cursor_name;
+ }
+
+ return NULL;
+}
+
+int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
+{
+ cursor->mir.conf = NULL;
+ cursor->mir.customCursor = NULL;
+ cursor->mir.cursorName = getSystemCursorName(shape);
+
+ return cursor->mir.cursorName != NULL;
+}
+
+void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
+{
+ if (cursor->mir.conf)
+ mir_cursor_configuration_destroy(cursor->mir.conf);
+ if (cursor->mir.customCursor)
+ mir_buffer_stream_release_sync(cursor->mir.customCursor);
+}
+
+static void setCursorNameForWindow(MirWindow* window, char const* name)
+{
+ MirWindowSpec* spec = mir_create_window_spec(_glfw.mir.connection);
+ mir_window_spec_set_cursor_name(spec, name);
+ mir_window_apply_spec(window, spec);
+ mir_window_spec_release(spec);
+}
+
+void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+{
+ if (cursor)
+ {
+ window->mir.currentCursor = cursor;
+
+ if (cursor->mir.cursorName)
+ {
+ setCursorNameForWindow(window->mir.window, cursor->mir.cursorName);
+ }
+ else if (cursor->mir.conf)
+ {
+ mir_window_configure_cursor(window->mir.window, cursor->mir.conf);
+ }
+ }
+ else
+ {
+ setCursorNameForWindow(window->mir.window, mir_default_cursor_name);
+ }
+}
+
+void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
+{
+ if (mode == GLFW_CURSOR_DISABLED)
+ {
+ _glfw.mir.disabledCursorWindow = window;
+ setWindowConfinement(window, mir_pointer_confined_to_window);
+ setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
+ }
+ else
+ {
+ // If we were disabled before lets undo that!
+ if (_glfw.mir.disabledCursorWindow == window)
+ {
+ _glfw.mir.disabledCursorWindow = NULL;
+ setWindowConfinement(window, mir_pointer_unconfined);
+ }
+
+ if (window->cursorMode == GLFW_CURSOR_NORMAL)
+ {
+ _glfwPlatformSetCursor(window, window->mir.currentCursor);
+ }
+ else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ {
+ setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
+ }
+ }
+}
+
+const char* _glfwPlatformGetScancodeName(int scancode)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+ return NULL;
+}
+
+int _glfwPlatformGetKeyScancode(int key)
+{
+ return _glfw.mir.scancodes[key];
+}
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+}
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Unsupported function %s", __PRETTY_FUNCTION__);
+
+ return NULL;
+}
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
+{
+ if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_mir_surface)
+ return;
+
+ extensions[0] = "VK_KHR_surface";
+ extensions[1] = "VK_KHR_mir_surface";
+}
+
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
+ vkGetPhysicalDeviceMirPresentationSupportKHR =
+ (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
+ if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Mir: Vulkan instance missing VK_KHR_mir_surface extension");
+ return GLFW_FALSE;
+ }
+
+ return vkGetPhysicalDeviceMirPresentationSupportKHR(device,
+ queuefamily,
+ _glfw.mir.connection);
+}
+
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
+ _GLFWwindow* window,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+ VkResult err;
+ VkMirWindowCreateInfoKHR sci;
+ PFN_vkCreateMirWindowKHR vkCreateMirWindowKHR;
+
+ vkCreateMirWindowKHR = (PFN_vkCreateMirWindowKHR)
+ vkGetInstanceProcAddr(instance, "vkCreateMirWindowKHR");
+ if (!vkCreateMirWindowKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Mir: Vulkan instance missing VK_KHR_mir_surface extension");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ memset(&sci, 0, sizeof(sci));
+ sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
+ sci.connection = _glfw.mir.connection;
+ sci.mirWindow = window->mir.window;
+
+ err = vkCreateMirWindowKHR(instance, &sci, allocator, surface);
+ if (err)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Mir: Failed to create Vulkan surface: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ return err;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI MirConnection* glfwGetMirDisplay(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return _glfw.mir.connection;
+}
+
+GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return window->mir.window;
+}
+
diff --git a/src/external/glfw/src/monitor.c b/src/external/glfw/src/monitor.c
new file mode 100644
index 00000000..0dfb1958
--- /dev/null
+++ b/src/external/glfw/src/monitor.c
@@ -0,0 +1,467 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+
+
+// Lexically compare video modes, used by qsort
+//
+static int compareVideoModes(const void* fp, const void* sp)
+{
+ const GLFWvidmode* fm = fp;
+ const GLFWvidmode* sm = sp;
+ const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;
+ const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;
+ const int farea = fm->width * fm->height;
+ const int sarea = sm->width * sm->height;
+
+ // First sort on color bits per pixel
+ if (fbpp != sbpp)
+ return fbpp - sbpp;
+
+ // Then sort on screen area
+ if (farea != sarea)
+ return farea - sarea;
+
+ // Lastly sort on refresh rate
+ return fm->refreshRate - sm->refreshRate;
+}
+
+// Retrieves the available modes for the specified monitor
+//
+static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
+{
+ int modeCount;
+ GLFWvidmode* modes;
+
+ if (monitor->modes)
+ return GLFW_TRUE;
+
+ modes = _glfwPlatformGetVideoModes(monitor, &modeCount);
+ if (!modes)
+ return GLFW_FALSE;
+
+ qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
+
+ free(monitor->modes);
+ monitor->modes = modes;
+ monitor->modeCount = modeCount;
+
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW event API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
+{
+ if (action == GLFW_CONNECTED)
+ {
+ _glfw.monitorCount++;
+ _glfw.monitors =
+ realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
+
+ if (placement == _GLFW_INSERT_FIRST)
+ {
+ memmove(_glfw.monitors + 1,
+ _glfw.monitors,
+ (_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
+ _glfw.monitors[0] = monitor;
+ }
+ else
+ _glfw.monitors[_glfw.monitorCount - 1] = monitor;
+ }
+ else if (action == GLFW_DISCONNECTED)
+ {
+ int i;
+ _GLFWwindow* window;
+
+ for (window = _glfw.windowListHead; window; window = window->next)
+ {
+ if (window->monitor == monitor)
+ {
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ _glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
+ }
+ }
+
+ for (i = 0; i < _glfw.monitorCount; i++)
+ {
+ if (_glfw.monitors[i] == monitor)
+ {
+ _glfw.monitorCount--;
+ memmove(_glfw.monitors + i,
+ _glfw.monitors + i + 1,
+ (_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
+ break;
+ }
+ }
+ }
+
+ if (_glfw.callbacks.monitor)
+ _glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
+
+ if (action == GLFW_DISCONNECTED)
+ _glfwFreeMonitor(monitor);
+}
+
+void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
+{
+ monitor->window = window;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
+{
+ _GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor));
+ monitor->widthMM = widthMM;
+ monitor->heightMM = heightMM;
+
+ if (name)
+ monitor->name = strdup(name);
+
+ return monitor;
+}
+
+void _glfwFreeMonitor(_GLFWmonitor* monitor)
+{
+ if (monitor == NULL)
+ return;
+
+ _glfwFreeGammaArrays(&monitor->originalRamp);
+ _glfwFreeGammaArrays(&monitor->currentRamp);
+
+ free(monitor->modes);
+ free(monitor->name);
+ free(monitor);
+}
+
+void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
+{
+ ramp->red = calloc(size, sizeof(unsigned short));
+ ramp->green = calloc(size, sizeof(unsigned short));
+ ramp->blue = calloc(size, sizeof(unsigned short));
+ ramp->size = size;
+}
+
+void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
+{
+ free(ramp->red);
+ free(ramp->green);
+ free(ramp->blue);
+
+ memset(ramp, 0, sizeof(GLFWgammaramp));
+}
+
+const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
+ const GLFWvidmode* desired)
+{
+ int i;
+ unsigned int sizeDiff, leastSizeDiff = UINT_MAX;
+ unsigned int rateDiff, leastRateDiff = UINT_MAX;
+ unsigned int colorDiff, leastColorDiff = UINT_MAX;
+ const GLFWvidmode* current;
+ const GLFWvidmode* closest = NULL;
+
+ if (!refreshVideoModes(monitor))
+ return NULL;
+
+ for (i = 0; i < monitor->modeCount; i++)
+ {
+ current = monitor->modes + i;
+
+ colorDiff = 0;
+
+ if (desired->redBits != GLFW_DONT_CARE)
+ colorDiff += abs(current->redBits - desired->redBits);
+ if (desired->greenBits != GLFW_DONT_CARE)
+ colorDiff += abs(current->greenBits - desired->greenBits);
+ if (desired->blueBits != GLFW_DONT_CARE)
+ colorDiff += abs(current->blueBits - desired->blueBits);
+
+ sizeDiff = abs((current->width - desired->width) *
+ (current->width - desired->width) +
+ (current->height - desired->height) *
+ (current->height - desired->height));
+
+ if (desired->refreshRate != GLFW_DONT_CARE)
+ rateDiff = abs(current->refreshRate - desired->refreshRate);
+ else
+ rateDiff = UINT_MAX - current->refreshRate;
+
+ if ((colorDiff < leastColorDiff) ||
+ (colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) ||
+ (colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff))
+ {
+ closest = current;
+ leastSizeDiff = sizeDiff;
+ leastRateDiff = rateDiff;
+ leastColorDiff = colorDiff;
+ }
+ }
+
+ return closest;
+}
+
+int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm)
+{
+ return compareVideoModes(fm, sm);
+}
+
+void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
+{
+ int delta;
+
+ // We assume that by 32 the user really meant 24
+ if (bpp == 32)
+ bpp = 24;
+
+ // Convert "bits per pixel" to red, green & blue sizes
+
+ *red = *green = *blue = bpp / 3;
+ delta = bpp - (*red * 3);
+ if (delta >= 1)
+ *green = *green + 1;
+
+ if (delta == 2)
+ *red = *red + 1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
+{
+ assert(count != NULL);
+
+ *count = 0;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ *count = _glfw.monitorCount;
+ return (GLFWmonitor**) _glfw.monitors;
+}
+
+GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (!_glfw.monitorCount)
+ return NULL;
+
+ return (GLFWmonitor*) _glfw.monitors[0];
+}
+
+GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+
+ if (xpos)
+ *xpos = 0;
+ if (ypos)
+ *ypos = 0;
+
+ _GLFW_REQUIRE_INIT();
+
+ _glfwPlatformGetMonitorPos(monitor, xpos, ypos);
+}
+
+GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+
+ if (widthMM)
+ *widthMM = 0;
+ if (heightMM)
+ *heightMM = 0;
+
+ _GLFW_REQUIRE_INIT();
+
+ if (widthMM)
+ *widthMM = monitor->widthMM;
+ if (heightMM)
+ *heightMM = monitor->heightMM;
+}
+
+GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
+ float* xscale, float* yscale)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+
+ if (xscale)
+ *xscale = 0.f;
+ if (yscale)
+ *yscale = 0.f;
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformGetMonitorContentScale(monitor, xscale, yscale);
+}
+
+GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return monitor->name;
+}
+
+GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun);
+ return cbfun;
+}
+
+GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+ assert(count != NULL);
+
+ *count = 0;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (!refreshVideoModes(monitor))
+ return NULL;
+
+ *count = monitor->modeCount;
+ return monitor->modes;
+}
+
+GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ _glfwPlatformGetVideoMode(monitor, &monitor->currentMode);
+ return &monitor->currentMode;
+}
+
+GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
+{
+ int i;
+ unsigned short values[256];
+ GLFWgammaramp ramp;
+ assert(handle != NULL);
+ assert(gamma == gamma);
+ assert(gamma >= 0.f);
+ assert(gamma <= FLT_MAX);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
+ return;
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ double value;
+
+ // Calculate intensity
+ value = i / 255.0;
+ // Apply gamma curve
+ value = pow(value, 1.0 / gamma) * 65535.0 + 0.5;
+
+ // Clamp to value range
+ if (value > 65535.0)
+ value = 65535.0;
+
+ values[i] = (unsigned short) value;
+ }
+
+ ramp.red = values;
+ ramp.green = values;
+ ramp.blue = values;
+ ramp.size = 256;
+
+ glfwSetGammaRamp(handle, &ramp);
+}
+
+GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ _glfwFreeGammaArrays(&monitor->currentRamp);
+ _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp);
+
+ return &monitor->currentRamp;
+}
+
+GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ assert(monitor != NULL);
+ assert(ramp != NULL);
+ assert(ramp->size > 0);
+ assert(ramp->red != NULL);
+ assert(ramp->green != NULL);
+ assert(ramp->blue != NULL);
+
+ if (ramp->size <= 0)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid gamma ramp size %i",
+ ramp->size);
+ return;
+ }
+
+ _GLFW_REQUIRE_INIT();
+
+ if (!monitor->originalRamp.size)
+ _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp);
+
+ _glfwPlatformSetGammaRamp(monitor, ramp);
+}
+
diff --git a/src/external/glfw/src/nsgl_context.h b/src/external/glfw/src/nsgl_context.h
new file mode 100644
index 00000000..18042dee
--- /dev/null
+++ b/src/external/glfw/src/nsgl_context.h
@@ -0,0 +1,56 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+//
+// 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_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
+#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
+
+
+// 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;
+
+
+GLFWbool _glfwInitNSGL(void);
+void _glfwTerminateNSGL(void);
+GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig);
+void _glfwDestroyContextNSGL(_GLFWwindow* window);
+
diff --git a/src/external/glfw/src/nsgl_context.m b/src/external/glfw/src/nsgl_context.m
new file mode 100644
index 00000000..a7cbf00f
--- /dev/null
+++ b/src/external/glfw/src/nsgl_context.m
@@ -0,0 +1,335 @@
+//========================================================================
+// GLFW 3.3 macOS - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+static void makeContextCurrentNSGL(_GLFWwindow* window)
+{
+ if (window)
+ [window->context.nsgl.object makeCurrentContext];
+ else
+ [NSOpenGLContext clearCurrentContext];
+
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
+}
+
+static void swapBuffersNSGL(_GLFWwindow* window)
+{
+ // ARP appears to be unnecessary, but this is future-proof
+ [window->context.nsgl.object flushBuffer];
+}
+
+static void swapIntervalNSGL(int interval)
+{
+ _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
+
+ GLint sync = interval;
+ [window->context.nsgl.object setValues:&sync
+ forParameter:NSOpenGLCPSwapInterval];
+}
+
+static int extensionSupportedNSGL(const char* extension)
+{
+ // There are no NSGL extensions
+ return GLFW_FALSE;
+}
+
+static GLFWglproc getProcAddressNSGL(const char* procname)
+{
+ CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
+ procname,
+ kCFStringEncodingASCII);
+
+ GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
+ symbolName);
+
+ CFRelease(symbolName);
+
+ return symbol;
+}
+
+// Destroy the OpenGL context
+//
+static void destroyContextNSGL(_GLFWwindow* window)
+{
+ [window->context.nsgl.pixelFormat release];
+ window->context.nsgl.pixelFormat = nil;
+
+ [window->context.nsgl.object release];
+ window->context.nsgl.object = nil;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize OpenGL support
+//
+GLFWbool _glfwInitNSGL(void)
+{
+ if (_glfw.nsgl.framework)
+ return GLFW_TRUE;
+
+ _glfw.nsgl.framework =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
+ if (_glfw.nsgl.framework == NULL)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "NSGL: Failed to locate OpenGL framework");
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+// Terminate OpenGL support
+//
+void _glfwTerminateNSGL(void)
+{
+}
+
+// Create the OpenGL context
+//
+GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "NSGL: OpenGL ES is not available on macOS");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->major > 2)
+ {
+ if (ctxconfig->major == 3 && ctxconfig->minor < 2)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "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;
+ }
+
+ 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
+ // macOS but are not a hard constraint, so ignore and continue
+
+ // Context release behaviors (GL_KHR_context_flush_control) are not yet
+ // supported by macOS but are not a hard constraint, so ignore and continue
+
+ // Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
+ // a hard constraint, so ignore and continue
+
+ // No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
+ // are not a hard constraint, so ignore and continue
+
+#define addAttrib(a) \
+{ \
+ assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
+ attribs[index++] = a; \
+}
+#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
+
+ NSOpenGLPixelFormatAttribute attribs[40];
+ int index = 0;
+
+ addAttrib(NSOpenGLPFAAccelerated);
+ addAttrib(NSOpenGLPFAClosestPolicy);
+
+ if (ctxconfig->nsgl.offline)
+ {
+ addAttrib(NSOpenGLPFAAllowOfflineRenderers);
+ // NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
+ // Info.plist for unbundled applications
+ // HACK: This assumes that NSOpenGLPixelFormat will remain
+ // a straightforward wrapper of its CGL counterpart
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 100800
+ addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
+ }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
+ if (ctxconfig->major >= 4)
+ {
+ setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
+ }
+ else
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
+ if (ctxconfig->major >= 3)
+ {
+ setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
+ }
+
+ if (ctxconfig->major <= 2)
+ {
+ if (fbconfig->auxBuffers != GLFW_DONT_CARE)
+ setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
+
+ if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
+ fbconfig->accumGreenBits != GLFW_DONT_CARE &&
+ fbconfig->accumBlueBits != GLFW_DONT_CARE &&
+ fbconfig->accumAlphaBits != GLFW_DONT_CARE)
+ {
+ const int accumBits = fbconfig->accumRedBits +
+ fbconfig->accumGreenBits +
+ fbconfig->accumBlueBits +
+ fbconfig->accumAlphaBits;
+
+ setAttrib(NSOpenGLPFAAccumSize, accumBits);
+ }
+ }
+
+ if (fbconfig->redBits != GLFW_DONT_CARE &&
+ fbconfig->greenBits != GLFW_DONT_CARE &&
+ fbconfig->blueBits != GLFW_DONT_CARE)
+ {
+ int colorBits = fbconfig->redBits +
+ fbconfig->greenBits +
+ fbconfig->blueBits;
+
+ // macOS needs non-zero color size, so set reasonable values
+ if (colorBits == 0)
+ colorBits = 24;
+ else if (colorBits < 15)
+ colorBits = 15;
+
+ setAttrib(NSOpenGLPFAColorSize, colorBits);
+ }
+
+ if (fbconfig->alphaBits != GLFW_DONT_CARE)
+ setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
+
+ if (fbconfig->depthBits != GLFW_DONT_CARE)
+ setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
+
+ if (fbconfig->stencilBits != GLFW_DONT_CARE)
+ setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
+
+ if (fbconfig->stereo)
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "NSGL: Stereo rendering is deprecated");
+ return GLFW_FALSE;
+#else
+ addAttrib(NSOpenGLPFAStereo);
+#endif
+ }
+
+ if (fbconfig->doublebuffer)
+ addAttrib(NSOpenGLPFADoubleBuffer);
+
+ if (fbconfig->samples != GLFW_DONT_CARE)
+ {
+ if (fbconfig->samples == 0)
+ {
+ setAttrib(NSOpenGLPFASampleBuffers, 0);
+ }
+ else
+ {
+ setAttrib(NSOpenGLPFASampleBuffers, 1);
+ setAttrib(NSOpenGLPFASamples, fbconfig->samples);
+ }
+ }
+
+ // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
+ // framebuffer, so there's no need (and no way) to request it
+
+ addAttrib(0);
+
+#undef addAttrib
+#undef setAttrib
+
+ window->context.nsgl.pixelFormat =
+ [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
+ if (window->context.nsgl.pixelFormat == nil)
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "NSGL: Failed to find a suitable pixel format");
+ return GLFW_FALSE;
+ }
+
+ NSOpenGLContext* share = NULL;
+
+ if (ctxconfig->share)
+ share = ctxconfig->share->context.nsgl.object;
+
+ window->context.nsgl.object =
+ [[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
+ shareContext:share];
+ if (window->context.nsgl.object == nil)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "NSGL: Failed to create OpenGL context");
+ return GLFW_FALSE;
+ }
+
+ if (fbconfig->transparent)
+ {
+ GLint opaque = 0;
+ [window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
+ }
+
+ [window->context.nsgl.object setView:window->ns.view];
+
+ window->context.makeCurrent = makeContextCurrentNSGL;
+ window->context.swapBuffers = swapBuffersNSGL;
+ window->context.swapInterval = swapIntervalNSGL;
+ window->context.extensionSupported = extensionSupportedNSGL;
+ window->context.getProcAddress = getProcAddressNSGL;
+ window->context.destroy = destroyContextNSGL;
+
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(nil);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return NULL;
+ }
+
+ return window->context.nsgl.object;
+}
+
diff --git a/src/external/glfw/src/null_init.c b/src/external/glfw/src/null_init.c
new file mode 100644
index 00000000..34147388
--- /dev/null
+++ b/src/external/glfw/src/null_init.c
@@ -0,0 +1,50 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformInit(void)
+{
+ _glfwInitTimerPOSIX();
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformTerminate(void)
+{
+ _glfwTerminateOSMesa();
+}
+
+const char* _glfwPlatformGetVersionString(void)
+{
+ return _GLFW_VERSION_NUMBER " null OSMesa";
+}
+
diff --git a/src/external/glfw/src/null_joystick.c b/src/external/glfw/src/null_joystick.c
new file mode 100644
index 00000000..afd65e15
--- /dev/null
+++ b/src/external/glfw/src/null_joystick.c
@@ -0,0 +1,42 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
+{
+ return GLFW_FALSE;
+}
+
+void _glfwPlatformUpdateGamepadGUID(char* guid)
+{
+}
+
diff --git a/src/external/glfw/src/null_joystick.h b/src/external/glfw/src/null_joystick.h
new file mode 100644
index 00000000..3075815d
--- /dev/null
+++ b/src/external/glfw/src/null_joystick.h
@@ -0,0 +1,31 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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_PLATFORM_JOYSTICK_STATE int nulljs
+#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
+
+#define _GLFW_PLATFORM_MAPPING_NAME ""
+
diff --git a/src/external/glfw/src/null_monitor.c b/src/external/glfw/src/null_monitor.c
new file mode 100644
index 00000000..007dd1aa
--- /dev/null
+++ b/src/external/glfw/src/null_monitor.c
@@ -0,0 +1,64 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
+{
+}
+
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = 1.f;
+ if (yscale)
+ *yscale = 1.f;
+}
+
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
+{
+ return NULL;
+}
+
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
+{
+}
+
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
+{
+}
+
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
+{
+}
+
diff --git a/src/external/glfw/src/null_platform.h b/src/external/glfw/src/null_platform.h
new file mode 100644
index 00000000..2d67c50c
--- /dev/null
+++ b/src/external/glfw/src/null_platform.h
@@ -0,0 +1,62 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <dlfcn.h>
+
+#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
+
+#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
+//
+typedef struct _GLFWwindowNull
+{
+ int width;
+ int height;
+} _GLFWwindowNull;
+
diff --git a/src/external/glfw/src/null_window.c b/src/external/glfw/src/null_window.c
new file mode 100644
index 00000000..3cc3905d
--- /dev/null
+++ b/src/external/glfw/src/null_window.c
@@ -0,0 +1,307 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+static int createNativeWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig)
+{
+ window->null.width = wndconfig->width;
+ window->null.height = wndconfig->height;
+
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ if (!createNativeWindow(window, wndconfig))
+ return GLFW_FALSE;
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API ||
+ ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwInitOSMesa())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
+ return GLFW_FALSE;
+ }
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+{
+ if (window->context.destroy)
+ window->context.destroy(window);
+}
+
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
+{
+}
+
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count,
+ const GLFWimage* images)
+{
+}
+
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+ _GLFWmonitor* monitor,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+}
+
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+{
+}
+
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
+{
+}
+
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
+{
+ if (width)
+ *width = window->null.width;
+ if (height)
+ *height = window->null.height;
+}
+
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
+{
+ window->null.width = width;
+ window->null.height = height;
+}
+
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+}
+
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
+{
+}
+
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
+{
+ if (width)
+ *width = window->null.width;
+ if (height)
+ *height = window->null.height;
+}
+
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+}
+
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = 1.f;
+ if (yscale)
+ *yscale = 1.f;
+}
+
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
+{
+}
+
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
+{
+}
+
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
+{
+}
+
+int _glfwPlatformWindowMaximized(_GLFWwindow* window)
+{
+ return GLFW_FALSE;
+}
+
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
+{
+ return GLFW_FALSE;
+}
+
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
+{
+}
+
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
+{
+}
+
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
+{
+}
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+}
+
+
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+{
+}
+
+void _glfwPlatformUnhideWindow(_GLFWwindow* window)
+{
+}
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+}
+
+void _glfwPlatformFocusWindow(_GLFWwindow* window)
+{
+}
+
+int _glfwPlatformWindowFocused(_GLFWwindow* window)
+{
+ return GLFW_FALSE;
+}
+
+int _glfwPlatformWindowIconified(_GLFWwindow* window)
+{
+ return GLFW_FALSE;
+}
+
+int _glfwPlatformWindowVisible(_GLFWwindow* window)
+{
+ return GLFW_FALSE;
+}
+
+void _glfwPlatformPollEvents(void)
+{
+}
+
+void _glfwPlatformWaitEvents(void)
+{
+}
+
+void _glfwPlatformWaitEventsTimeout(double timeout)
+{
+}
+
+void _glfwPlatformPostEmptyEvent(void)
+{
+}
+
+void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
+{
+}
+
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
+{
+}
+
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
+{
+}
+
+int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
+ const GLFWimage* image,
+ int xhot, int yhot)
+{
+ return GLFW_TRUE;
+}
+
+int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
+{
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
+{
+}
+
+void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+{
+}
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+}
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ return NULL;
+}
+
+const char* _glfwPlatformGetScancodeName(int scancode)
+{
+ return "";
+}
+
+int _glfwPlatformGetKeyScancode(int key)
+{
+ return -1;
+}
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
+{
+}
+
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ return GLFW_FALSE;
+}
+
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
+ _GLFWwindow* window,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+ // This seems like the most appropriate error to return here
+ return VK_ERROR_INITIALIZATION_FAILED;
+}
+
diff --git a/src/external/glfw/src/osmesa_context.c b/src/external/glfw/src/osmesa_context.c
new file mode 100644
index 00000000..a7de33f2
--- /dev/null
+++ b/src/external/glfw/src/osmesa_context.c
@@ -0,0 +1,370 @@
+//========================================================================
+// GLFW 3.3 OSMesa - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "internal.h"
+
+
+static void makeContextCurrentOSMesa(_GLFWwindow* window)
+{
+ if (window)
+ {
+ int width, height;
+ _glfwPlatformGetFramebufferSize(window, &width, &height);
+
+ // Check to see if we need to allocate a new buffer
+ if ((window->context.osmesa.buffer == NULL) ||
+ (width != window->context.osmesa.width) ||
+ (height != window->context.osmesa.height))
+ {
+ free(window->context.osmesa.buffer);
+
+ // Allocate the new buffer (width * height * 8-bit RGBA)
+ window->context.osmesa.buffer = calloc(4, width * height);
+ window->context.osmesa.width = width;
+ window->context.osmesa.height = height;
+ }
+
+ if (!OSMesaMakeCurrent(window->context.osmesa.handle,
+ window->context.osmesa.buffer,
+ GL_UNSIGNED_BYTE,
+ width, height))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to make context current");
+ return;
+ }
+ }
+
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
+}
+
+static GLFWglproc getProcAddressOSMesa(const char* procname)
+{
+ return (GLFWglproc) OSMesaGetProcAddress(procname);
+}
+
+static void destroyContextOSMesa(_GLFWwindow* window)
+{
+ if (window->context.osmesa.handle)
+ {
+ OSMesaDestroyContext(window->context.osmesa.handle);
+ window->context.osmesa.handle = NULL;
+ }
+
+ if (window->context.osmesa.buffer)
+ {
+ free(window->context.osmesa.buffer);
+ window->context.osmesa.width = 0;
+ window->context.osmesa.height = 0;
+ }
+}
+
+static void swapBuffersOSMesa(_GLFWwindow* window)
+{
+ // No double buffering on OSMesa
+}
+
+static void swapIntervalOSMesa(int interval)
+{
+ // No swap interval on OSMesa
+}
+
+static int extensionSupportedOSMesa(const char* extension)
+{
+ // OSMesa does not have extensions
+ return GLFW_FALSE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWbool _glfwInitOSMesa(void)
+{
+ int i;
+ const char* sonames[] =
+ {
+#if defined(_GLFW_OSMESA_LIBRARY)
+ _GLFW_OSMESA_LIBRARY,
+#elif defined(_WIN32)
+ "libOSMesa.dll",
+ "OSMesa.dll",
+#elif defined(__APPLE__)
+ "libOSMesa.8.dylib",
+#elif defined(__CYGWIN__)
+ "libOSMesa-8.so",
+#else
+ "libOSMesa.so.8",
+ "libOSMesa.so.6",
+#endif
+ NULL
+ };
+
+ if (_glfw.osmesa.handle)
+ return GLFW_TRUE;
+
+ for (i = 0; sonames[i]; i++)
+ {
+ _glfw.osmesa.handle = _glfw_dlopen(sonames[i]);
+ if (_glfw.osmesa.handle)
+ break;
+ }
+
+ if (!_glfw.osmesa.handle)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
+ return GLFW_FALSE;
+ }
+
+ _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
+ _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
+ _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
+ _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
+ _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
+ _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
+ _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
+ _glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
+
+ if (!_glfw.osmesa.CreateContextExt ||
+ !_glfw.osmesa.DestroyContext ||
+ !_glfw.osmesa.MakeCurrent ||
+ !_glfw.osmesa.GetColorBuffer ||
+ !_glfw.osmesa.GetDepthBuffer ||
+ !_glfw.osmesa.GetProcAddress)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to load required entry points");
+
+ _glfwTerminateOSMesa();
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwTerminateOSMesa(void)
+{
+ if (_glfw.osmesa.handle)
+ {
+ _glfw_dlclose(_glfw.osmesa.handle);
+ _glfw.osmesa.handle = NULL;
+ }
+}
+
+#define setAttrib(a, v) \
+{ \
+ assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
+ attribs[index++] = a; \
+ attribs[index++] = v; \
+}
+
+GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ OSMesaContext share = NULL;
+ const int accumBits = fbconfig->accumRedBits +
+ fbconfig->accumGreenBits +
+ fbconfig->accumBlueBits +
+ fbconfig->accumAlphaBits;
+
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "OSMesa: OpenGL ES is not available on OSMesa");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->share)
+ share = ctxconfig->share->context.osmesa.handle;
+
+ if (OSMesaCreateContextAttribs)
+ {
+ int index = 0, attribs[40];
+
+ setAttrib(OSMESA_FORMAT, OSMESA_RGBA);
+ setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits);
+ setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
+ setAttrib(OSMESA_ACCUM_BITS, accumBits);
+
+ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
+ {
+ setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
+ }
+ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
+ {
+ setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
+ }
+
+ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
+ {
+ setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
+ setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
+ }
+
+ if (ctxconfig->forward)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "OSMesa: Foward-compatible contexts not supported");
+ return GLFW_FALSE;
+ }
+
+ setAttrib(0, 0);
+
+ window->context.osmesa.handle =
+ OSMesaCreateContextAttribs(attribs, share);
+ }
+ else
+ {
+ if (ctxconfig->profile)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "OSMesa: OpenGL profiles unavailable");
+ return GLFW_FALSE;
+ }
+
+ window->context.osmesa.handle =
+ OSMesaCreateContextExt(OSMESA_RGBA,
+ fbconfig->depthBits,
+ fbconfig->stencilBits,
+ accumBits,
+ share);
+ }
+
+ if (window->context.osmesa.handle == NULL)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "OSMesa: Failed to create context");
+ return GLFW_FALSE;
+ }
+
+ window->context.makeCurrent = makeContextCurrentOSMesa;
+ window->context.swapBuffers = swapBuffersOSMesa;
+ window->context.swapInterval = swapIntervalOSMesa;
+ window->context.extensionSupported = extensionSupportedOSMesa;
+ window->context.getProcAddress = getProcAddressOSMesa;
+ window->context.destroy = destroyContextOSMesa;
+
+ return GLFW_TRUE;
+}
+
+#undef setAttrib
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
+ int* height, int* format, void** buffer)
+{
+ void* mesaBuffer;
+ GLint mesaWidth, mesaHeight, mesaFormat;
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
+ &mesaWidth, &mesaHeight,
+ &mesaFormat, &mesaBuffer))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to retrieve color buffer");
+ return GLFW_FALSE;
+ }
+
+ if (width)
+ *width = mesaWidth;
+ if (height)
+ *height = mesaHeight;
+ if (format)
+ *format = mesaFormat;
+ if (buffer)
+ *buffer = mesaBuffer;
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
+ int* width, int* height,
+ int* bytesPerValue,
+ void** buffer)
+{
+ void* mesaBuffer;
+ GLint mesaWidth, mesaHeight, mesaBytes;
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
+ &mesaWidth, &mesaHeight,
+ &mesaBytes, &mesaBuffer))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "OSMesa: Failed to retrieve depth buffer");
+ return GLFW_FALSE;
+ }
+
+ if (width)
+ *width = mesaWidth;
+ if (height)
+ *height = mesaHeight;
+ if (bytesPerValue)
+ *bytesPerValue = mesaBytes;
+ if (buffer)
+ *buffer = mesaBuffer;
+
+ return GLFW_TRUE;
+}
+
+GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return NULL;
+ }
+
+ return window->context.osmesa.handle;
+}
+
diff --git a/src/external/glfw/src/osmesa_context.h b/src/external/glfw/src/osmesa_context.h
new file mode 100644
index 00000000..e6ae5781
--- /dev/null
+++ b/src/external/glfw/src/osmesa_context.h
@@ -0,0 +1,94 @@
+//========================================================================
+// GLFW 3.3 OSMesa - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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)();
+
+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);
+
diff --git a/src/external/glfw/src/posix_thread.c b/src/external/glfw/src/posix_thread.c
new file mode 100644
index 00000000..ce0bc39b
--- /dev/null
+++ b/src/external/glfw/src/posix_thread.c
@@ -0,0 +1,103 @@
+//========================================================================
+// GLFW 3.3 POSIX - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+#include <string.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
+{
+ assert(tls->posix.allocated == GLFW_FALSE);
+
+ if (pthread_key_create(&tls->posix.key, NULL) != 0)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "POSIX: Failed to create context TLS");
+ return GLFW_FALSE;
+ }
+
+ tls->posix.allocated = GLFW_TRUE;
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyTls(_GLFWtls* tls)
+{
+ if (tls->posix.allocated)
+ pthread_key_delete(tls->posix.key);
+ memset(tls, 0, sizeof(_GLFWtls));
+}
+
+void* _glfwPlatformGetTls(_GLFWtls* tls)
+{
+ assert(tls->posix.allocated == GLFW_TRUE);
+ return pthread_getspecific(tls->posix.key);
+}
+
+void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
+{
+ assert(tls->posix.allocated == GLFW_TRUE);
+ pthread_setspecific(tls->posix.key, value);
+}
+
+GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
+{
+ assert(mutex->posix.allocated == GLFW_FALSE);
+
+ if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
+ return GLFW_FALSE;
+ }
+
+ return mutex->posix.allocated = GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
+{
+ if (mutex->posix.allocated)
+ pthread_mutex_destroy(&mutex->posix.handle);
+ memset(mutex, 0, sizeof(_GLFWmutex));
+}
+
+void _glfwPlatformLockMutex(_GLFWmutex* mutex)
+{
+ assert(mutex->posix.allocated == GLFW_TRUE);
+ pthread_mutex_lock(&mutex->posix.handle);
+}
+
+void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
+{
+ assert(mutex->posix.allocated == GLFW_TRUE);
+ pthread_mutex_unlock(&mutex->posix.handle);
+}
+
diff --git a/src/external/glfw/src/posix_thread.h b/src/external/glfw/src/posix_thread.h
new file mode 100644
index 00000000..bdddf41a
--- /dev/null
+++ b/src/external/glfw/src/posix_thread.h
@@ -0,0 +1,51 @@
+//========================================================================
+// GLFW 3.3 POSIX - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <pthread.h>
+
+#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix
+#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix
+
+
+// POSIX-specific thread local storage data
+//
+typedef struct _GLFWtlsPOSIX
+{
+ GLFWbool allocated;
+ pthread_key_t key;
+
+} _GLFWtlsPOSIX;
+
+// POSIX-specific mutex data
+//
+typedef struct _GLFWmutexPOSIX
+{
+ GLFWbool allocated;
+ pthread_mutex_t handle;
+
+} _GLFWmutexPOSIX;
+
diff --git a/src/external/glfw/src/posix_time.c b/src/external/glfw/src/posix_time.c
new file mode 100644
index 00000000..00b2831d
--- /dev/null
+++ b/src/external/glfw/src/posix_time.c
@@ -0,0 +1,85 @@
+//========================================================================
+// GLFW 3.3 POSIX - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <sys/time.h>
+#include <time.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialise timer
+//
+void _glfwInitTimerPOSIX(void)
+{
+#if defined(CLOCK_MONOTONIC)
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+ {
+ _glfw.timer.posix.monotonic = GLFW_TRUE;
+ _glfw.timer.posix.frequency = 1000000000;
+ }
+ else
+#endif
+ {
+ _glfw.timer.posix.monotonic = GLFW_FALSE;
+ _glfw.timer.posix.frequency = 1000000;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+uint64_t _glfwPlatformGetTimerValue(void)
+{
+#if defined(CLOCK_MONOTONIC)
+ if (_glfw.timer.posix.monotonic)
+ {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
+ }
+ else
+#endif
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
+ }
+}
+
+uint64_t _glfwPlatformGetTimerFrequency(void)
+{
+ return _glfw.timer.posix.frequency;
+}
+
diff --git a/src/external/glfw/src/posix_time.h b/src/external/glfw/src/posix_time.h
new file mode 100644
index 00000000..f1a69eb2
--- /dev/null
+++ b/src/external/glfw/src/posix_time.h
@@ -0,0 +1,44 @@
+//========================================================================
+// GLFW 3.3 POSIX - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix
+
+#include <stdint.h>
+
+
+// POSIX-specific global timer data
+//
+typedef struct _GLFWtimerPOSIX
+{
+ GLFWbool monotonic;
+ uint64_t frequency;
+
+} _GLFWtimerPOSIX;
+
+
+void _glfwInitTimerPOSIX(void);
+
diff --git a/src/external/glfw/src/vulkan.c b/src/external/glfw/src/vulkan.c
new file mode 100644
index 00000000..1fd15fad
--- /dev/null
+++ b/src/external/glfw/src/vulkan.c
@@ -0,0 +1,322 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define _GLFW_FIND_LOADER 1
+#define _GLFW_REQUIRE_LOADER 2
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWbool _glfwInitVulkan(int mode)
+{
+ VkResult err;
+ VkExtensionProperties* ep;
+ uint32_t i, count;
+
+ if (_glfw.vk.available)
+ return GLFW_TRUE;
+
+#if !defined(_GLFW_VULKAN_STATIC)
+#if defined(_GLFW_VULKAN_LIBRARY)
+ _glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
+#elif defined(_GLFW_WIN32)
+ _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
+#elif defined(_GLFW_COCOA)
+ _glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib");
+#else
+ _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
+#endif
+ if (!_glfw.vk.handle)
+ {
+ if (mode == _GLFW_REQUIRE_LOADER)
+ _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
+
+ return GLFW_FALSE;
+ }
+
+ _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
+ _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
+ if (!_glfw.vk.GetInstanceProcAddr)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Vulkan: Loader does not export vkGetInstanceProcAddr");
+
+ _glfwTerminateVulkan();
+ return GLFW_FALSE;
+ }
+
+ _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
+ vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
+ if (!_glfw.vk.EnumerateInstanceExtensionProperties)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
+
+ _glfwTerminateVulkan();
+ return GLFW_FALSE;
+ }
+#endif // _GLFW_VULKAN_STATIC
+
+ err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
+ if (err)
+ {
+ // NOTE: This happens on systems with a loader but without any Vulkan ICD
+ if (mode == _GLFW_REQUIRE_LOADER)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Vulkan: Failed to query instance extension count: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ _glfwTerminateVulkan();
+ return GLFW_FALSE;
+ }
+
+ ep = calloc(count, sizeof(VkExtensionProperties));
+
+ err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
+ if (err)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Vulkan: Failed to query instance extensions: %s",
+ _glfwGetVulkanResultString(err));
+
+ free(ep);
+ _glfwTerminateVulkan();
+ return GLFW_FALSE;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
+ _glfw.vk.KHR_surface = GLFW_TRUE;
+#if defined(_GLFW_WIN32)
+ else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
+ _glfw.vk.KHR_win32_surface = GLFW_TRUE;
+#elif defined(_GLFW_COCOA)
+ else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
+ _glfw.vk.MVK_macos_surface = GLFW_TRUE;
+#elif defined(_GLFW_X11)
+ else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
+ _glfw.vk.KHR_xlib_surface = GLFW_TRUE;
+ else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
+ _glfw.vk.KHR_xcb_surface = GLFW_TRUE;
+#elif defined(_GLFW_WAYLAND)
+ else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
+ _glfw.vk.KHR_wayland_surface = GLFW_TRUE;
+#elif defined(_GLFW_MIR)
+ else if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0)
+ _glfw.vk.KHR_mir_surface = GLFW_TRUE;
+#endif
+ }
+
+ free(ep);
+
+ _glfw.vk.available = GLFW_TRUE;
+
+ _glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
+
+ return GLFW_TRUE;
+}
+
+void _glfwTerminateVulkan(void)
+{
+#if !defined(_GLFW_VULKAN_STATIC)
+ if (_glfw.vk.handle)
+ _glfw_dlclose(_glfw.vk.handle);
+#endif
+}
+
+const char* _glfwGetVulkanResultString(VkResult result)
+{
+ switch (result)
+ {
+ case VK_SUCCESS:
+ return "Success";
+ case VK_NOT_READY:
+ return "A fence or query has not yet completed";
+ case VK_TIMEOUT:
+ return "A wait operation has not completed in the specified time";
+ case VK_EVENT_SET:
+ return "An event is signaled";
+ case VK_EVENT_RESET:
+ return "An event is unsignaled";
+ case VK_INCOMPLETE:
+ return "A return array was too small for the result";
+ case VK_ERROR_OUT_OF_HOST_MEMORY:
+ return "A host memory allocation has failed";
+ case VK_ERROR_OUT_OF_DEVICE_MEMORY:
+ return "A device memory allocation has failed";
+ case VK_ERROR_INITIALIZATION_FAILED:
+ return "Initialization of an object could not be completed for implementation-specific reasons";
+ case VK_ERROR_DEVICE_LOST:
+ return "The logical or physical device has been lost";
+ case VK_ERROR_MEMORY_MAP_FAILED:
+ return "Mapping of a memory object has failed";
+ case VK_ERROR_LAYER_NOT_PRESENT:
+ return "A requested layer is not present or could not be loaded";
+ case VK_ERROR_EXTENSION_NOT_PRESENT:
+ return "A requested extension is not supported";
+ case VK_ERROR_FEATURE_NOT_PRESENT:
+ return "A requested feature is not supported";
+ case VK_ERROR_INCOMPATIBLE_DRIVER:
+ return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
+ case VK_ERROR_TOO_MANY_OBJECTS:
+ return "Too many objects of the type have already been created";
+ case VK_ERROR_FORMAT_NOT_SUPPORTED:
+ return "A requested format is not supported on this device";
+ case VK_ERROR_SURFACE_LOST_KHR:
+ return "A surface is no longer available";
+ case VK_SUBOPTIMAL_KHR:
+ return "A swapchain no longer matches the surface properties exactly, but can still be used";
+ case VK_ERROR_OUT_OF_DATE_KHR:
+ return "A surface has changed in such a way that it is no longer compatible with the swapchain";
+ case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
+ return "The display used by a swapchain does not use the same presentable image layout";
+ case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
+ return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
+ case VK_ERROR_VALIDATION_FAILED_EXT:
+ return "A validation layer found an error";
+ default:
+ return "ERROR: UNKNOWN VULKAN ERROR";
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI int glfwVulkanSupported(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+ return _glfwInitVulkan(_GLFW_FIND_LOADER);
+}
+
+GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
+{
+ assert(count != NULL);
+
+ *count = 0;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
+ return NULL;
+
+ if (!_glfw.vk.extensions[0])
+ return NULL;
+
+ *count = 2;
+ return (const char**) _glfw.vk.extensions;
+}
+
+GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
+ const char* procname)
+{
+ GLFWvkproc proc;
+ assert(procname != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
+ return NULL;
+
+ proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
+#if defined(_GLFW_VULKAN_STATIC)
+ if (!proc)
+ {
+ if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
+ return (GLFWvkproc) vkGetInstanceProcAddr;
+ }
+#else
+ if (!proc)
+ proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
+#endif
+
+ return proc;
+}
+
+GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ assert(instance != VK_NULL_HANDLE);
+ assert(device != VK_NULL_HANDLE);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
+
+ if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
+ return GLFW_FALSE;
+
+ if (!_glfw.vk.extensions[0])
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Vulkan: Window surface creation extensions not found");
+ return GLFW_FALSE;
+ }
+
+ return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
+ device,
+ queuefamily);
+}
+
+GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
+ GLFWwindow* handle,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(instance != VK_NULL_HANDLE);
+ assert(window != NULL);
+ assert(surface != NULL);
+
+ *surface = VK_NULL_HANDLE;
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
+
+ if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ if (!_glfw.vk.extensions[0])
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Vulkan: Window surface creation extensions not found");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
+}
+
diff --git a/src/external/glfw/src/wgl_context.c b/src/external/glfw/src/wgl_context.c
new file mode 100644
index 00000000..d864a47c
--- /dev/null
+++ b/src/external/glfw/src/wgl_context.c
@@ -0,0 +1,731 @@
+//========================================================================
+// GLFW 3.3 WGL - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdlib.h>
+#include <malloc.h>
+#include <assert.h>
+
+
+// Returns the specified attribute of the specified pixel format
+//
+static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib)
+{
+ int value = 0;
+
+ assert(_glfw.wgl.ARB_pixel_format);
+
+ if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
+ pixelFormat,
+ 0, 1, &attrib, &value))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to retrieve pixel format attribute");
+ return 0;
+ }
+
+ return value;
+}
+
+// Return a list of available and usable framebuffer configs
+//
+static int choosePixelFormat(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ _GLFWfbconfig* usableConfigs;
+ const _GLFWfbconfig* closest;
+ int i, pixelFormat, nativeCount, usableCount;
+
+ if (_glfw.wgl.ARB_pixel_format)
+ {
+ nativeCount = getPixelFormatAttrib(window,
+ 1,
+ WGL_NUMBER_PIXEL_FORMATS_ARB);
+ }
+ else
+ {
+ nativeCount = DescribePixelFormat(window->context.wgl.dc,
+ 1,
+ sizeof(PIXELFORMATDESCRIPTOR),
+ NULL);
+ }
+
+ usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
+ usableCount = 0;
+
+ for (i = 0; i < nativeCount; i++)
+ {
+ const int n = i + 1;
+ _GLFWfbconfig* u = usableConfigs + usableCount;
+
+ if (_glfw.wgl.ARB_pixel_format)
+ {
+ // Get pixel format attributes through "modern" extension
+
+ if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) ||
+ !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB))
+ {
+ continue;
+ }
+
+ if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) !=
+ WGL_TYPE_RGBA_ARB)
+ {
+ continue;
+ }
+
+ if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) ==
+ WGL_NO_ACCELERATION_ARB)
+ {
+ continue;
+ }
+
+ u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB);
+ u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB);
+ u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB);
+ u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB);
+
+ u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB);
+ u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB);
+
+ u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB);
+ u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB);
+ u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB);
+ u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB);
+
+ u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB);
+
+ if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB))
+ u->stereo = GLFW_TRUE;
+ if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB))
+ u->doublebuffer = GLFW_TRUE;
+
+ if (_glfw.wgl.ARB_multisample)
+ u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
+
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if (_glfw.wgl.ARB_framebuffer_sRGB ||
+ _glfw.wgl.EXT_framebuffer_sRGB)
+ {
+ if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
+ u->sRGB = GLFW_TRUE;
+ }
+ }
+ else
+ {
+ if (_glfw.wgl.EXT_colorspace)
+ {
+ if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) ==
+ WGL_COLORSPACE_SRGB_EXT)
+ {
+ u->sRGB = GLFW_TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Get pixel format attributes through legacy PFDs
+
+ PIXELFORMATDESCRIPTOR pfd;
+
+ if (!DescribePixelFormat(window->context.wgl.dc,
+ n,
+ sizeof(PIXELFORMATDESCRIPTOR),
+ &pfd))
+ {
+ continue;
+ }
+
+ if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
+ !(pfd.dwFlags & PFD_SUPPORT_OPENGL))
+ {
+ continue;
+ }
+
+ if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
+ (pfd.dwFlags & PFD_GENERIC_FORMAT))
+ {
+ continue;
+ }
+
+ if (pfd.iPixelType != PFD_TYPE_RGBA)
+ continue;
+
+ u->redBits = pfd.cRedBits;
+ u->greenBits = pfd.cGreenBits;
+ u->blueBits = pfd.cBlueBits;
+ u->alphaBits = pfd.cAlphaBits;
+
+ u->depthBits = pfd.cDepthBits;
+ u->stencilBits = pfd.cStencilBits;
+
+ u->accumRedBits = pfd.cAccumRedBits;
+ u->accumGreenBits = pfd.cAccumGreenBits;
+ u->accumBlueBits = pfd.cAccumBlueBits;
+ u->accumAlphaBits = pfd.cAccumAlphaBits;
+
+ u->auxBuffers = pfd.cAuxBuffers;
+
+ if (pfd.dwFlags & PFD_STEREO)
+ u->stereo = GLFW_TRUE;
+ if (pfd.dwFlags & PFD_DOUBLEBUFFER)
+ u->doublebuffer = GLFW_TRUE;
+ }
+
+ u->handle = n;
+ usableCount++;
+ }
+
+ if (!usableCount)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "WGL: The driver does not appear to support OpenGL");
+
+ free(usableConfigs);
+ return 0;
+ }
+
+ closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
+ if (!closest)
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "WGL: Failed to find a suitable pixel format");
+
+ free(usableConfigs);
+ return 0;
+ }
+
+ pixelFormat = (int) closest->handle;
+ free(usableConfigs);
+
+ return pixelFormat;
+}
+
+static void makeContextCurrentWGL(_GLFWwindow* window)
+{
+ if (window)
+ {
+ if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
+ else
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to make context current");
+ _glfwPlatformSetTls(&_glfw.contextSlot, NULL);
+ }
+ }
+ else
+ {
+ if (!wglMakeCurrent(NULL, NULL))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to clear current context");
+ }
+
+ _glfwPlatformSetTls(&_glfw.contextSlot, NULL);
+ }
+}
+
+static void swapBuffersWGL(_GLFWwindow* window)
+{
+ // HACK: Use DwmFlush when desktop composition is enabled
+ if (_glfwIsCompositionEnabledWin32() && !window->monitor)
+ {
+ int count = abs(window->context.wgl.interval);
+ while (count--)
+ DwmFlush();
+ }
+
+ SwapBuffers(window->context.wgl.dc);
+}
+
+static void swapIntervalWGL(int interval)
+{
+ _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
+
+ window->context.wgl.interval = interval;
+
+ // HACK: Disable WGL swap interval when desktop composition is enabled to
+ // avoid interfering with DWM vsync
+ if (_glfwIsCompositionEnabledWin32() && !window->monitor)
+ interval = 0;
+
+ if (_glfw.wgl.EXT_swap_control)
+ _glfw.wgl.SwapIntervalEXT(interval);
+}
+
+static int extensionSupportedWGL(const char* extension)
+{
+ const char* extensions;
+
+ if (_glfw.wgl.GetExtensionsStringEXT)
+ {
+ extensions = _glfw.wgl.GetExtensionsStringEXT();
+ if (extensions)
+ {
+ if (_glfwStringInExtensionString(extension, extensions))
+ return GLFW_TRUE;
+ }
+ }
+
+ if (_glfw.wgl.GetExtensionsStringARB)
+ {
+ extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
+ if (extensions)
+ {
+ if (_glfwStringInExtensionString(extension, extensions))
+ return GLFW_TRUE;
+ }
+ }
+
+ return GLFW_FALSE;
+}
+
+static GLFWglproc getProcAddressWGL(const char* procname)
+{
+ const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
+ if (proc)
+ return proc;
+
+ return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
+}
+
+// Destroy the OpenGL context
+//
+static void destroyContextWGL(_GLFWwindow* window)
+{
+ if (window->context.wgl.handle)
+ {
+ wglDeleteContext(window->context.wgl.handle);
+ window->context.wgl.handle = NULL;
+ }
+}
+
+// Initialize WGL-specific extensions
+//
+static void loadWGLExtensions(void)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ HGLRC rc;
+ HDC dc = GetDC(_glfw.win32.helperWindowHandle);;
+
+ _glfw.wgl.extensionsLoaded = GLFW_TRUE;
+
+ // NOTE: A dummy context has to be created for opengl32.dll to load the
+ // OpenGL ICD, from which we can then query WGL extensions
+ // NOTE: This code will accept the Microsoft GDI ICD; accelerated context
+ // creation failure occurs during manual pixel format enumeration
+
+ ZeroMemory(&pfd, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+
+ if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to set pixel format for dummy context");
+ return;
+ }
+
+ rc = wglCreateContext(dc);
+ if (!rc)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to create dummy context");
+ return;
+ }
+
+ if (!wglMakeCurrent(dc, rc))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to make dummy context current");
+ wglDeleteContext(rc);
+ return;
+ }
+
+ // NOTE: Functions must be loaded first as they're needed to retrieve the
+ // extension string that tells us whether the functions are supported
+ _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
+ wglGetProcAddress("wglGetExtensionsStringEXT");
+ _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
+ wglGetProcAddress("wglGetExtensionsStringARB");
+ _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
+ wglGetProcAddress("wglCreateContextAttribsARB");
+ _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
+ wglGetProcAddress("wglSwapIntervalEXT");
+ _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
+ wglGetProcAddress("wglGetPixelFormatAttribivARB");
+
+ // NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
+ // checked below as we are already using them
+ _glfw.wgl.ARB_multisample =
+ extensionSupportedWGL("WGL_ARB_multisample");
+ _glfw.wgl.ARB_framebuffer_sRGB =
+ extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
+ _glfw.wgl.EXT_framebuffer_sRGB =
+ extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
+ _glfw.wgl.ARB_create_context =
+ extensionSupportedWGL("WGL_ARB_create_context");
+ _glfw.wgl.ARB_create_context_profile =
+ extensionSupportedWGL("WGL_ARB_create_context_profile");
+ _glfw.wgl.EXT_create_context_es2_profile =
+ extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
+ _glfw.wgl.ARB_create_context_robustness =
+ extensionSupportedWGL("WGL_ARB_create_context_robustness");
+ _glfw.wgl.ARB_create_context_no_error =
+ extensionSupportedWGL("WGL_ARB_create_context_no_error");
+ _glfw.wgl.EXT_swap_control =
+ extensionSupportedWGL("WGL_EXT_swap_control");
+ _glfw.wgl.EXT_colorspace =
+ extensionSupportedWGL("WGL_EXT_colorspace");
+ _glfw.wgl.ARB_pixel_format =
+ extensionSupportedWGL("WGL_ARB_pixel_format");
+ _glfw.wgl.ARB_context_flush_control =
+ extensionSupportedWGL("WGL_ARB_context_flush_control");
+
+ wglMakeCurrent(dc, NULL);
+ wglDeleteContext(rc);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize WGL
+//
+GLFWbool _glfwInitWGL(void)
+{
+ if (_glfw.wgl.instance)
+ return GLFW_TRUE;
+
+ _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
+ if (!_glfw.wgl.instance)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to load opengl32.dll");
+ return GLFW_FALSE;
+ }
+
+ _glfw.wgl.CreateContext = (PFN_wglCreateContext)
+ GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
+ _glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
+ GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
+ _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
+ GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
+ _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
+ GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
+ _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
+ GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
+ _glfw.wgl.ShareLists = (PFN_wglShareLists)
+ GetProcAddress(_glfw.wgl.instance, "wglShareLists");
+
+ return GLFW_TRUE;
+}
+
+// Terminate WGL
+//
+void _glfwTerminateWGL(void)
+{
+ if (_glfw.wgl.instance)
+ FreeLibrary(_glfw.wgl.instance);
+}
+
+#define setAttrib(a, v) \
+{ \
+ assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
+ attribs[index++] = a; \
+ attribs[index++] = v; \
+}
+
+// Create the OpenGL or OpenGL ES context
+//
+GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ int attribs[40];
+ int pixelFormat;
+ PIXELFORMATDESCRIPTOR pfd;
+ HGLRC share = NULL;
+
+ if (!_glfw.wgl.extensionsLoaded)
+ loadWGLExtensions();
+
+ if (ctxconfig->share)
+ share = ctxconfig->share->context.wgl.handle;
+
+ window->context.wgl.dc = GetDC(window->win32.handle);
+ if (!window->context.wgl.dc)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to retrieve DC for window");
+ return GLFW_FALSE;
+ }
+
+ pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
+ if (!pixelFormat)
+ return GLFW_FALSE;
+
+ if (!DescribePixelFormat(window->context.wgl.dc,
+ pixelFormat, sizeof(pfd), &pfd))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to retrieve PFD for selected pixel format");
+ return GLFW_FALSE;
+ }
+
+ if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to set selected pixel format");
+ return GLFW_FALSE;
+ }
+
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if (ctxconfig->forward)
+ {
+ if (!_glfw.wgl.ARB_create_context)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->profile)
+ {
+ if (!_glfw.wgl.ARB_create_context_profile)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
+ return GLFW_FALSE;
+ }
+ }
+ }
+ else
+ {
+ if (!_glfw.wgl.ARB_create_context ||
+ !_glfw.wgl.ARB_create_context_profile ||
+ !_glfw.wgl.EXT_create_context_es2_profile)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
+ return GLFW_FALSE;
+ }
+ }
+
+ if (_glfw.wgl.ARB_create_context)
+ {
+ int index = 0, mask = 0, flags = 0;
+
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ if (ctxconfig->forward)
+ flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+
+ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
+ mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
+ mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ }
+ else
+ mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
+
+ if (ctxconfig->debug)
+ flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
+
+ if (ctxconfig->robustness)
+ {
+ if (_glfw.wgl.ARB_create_context_robustness)
+ {
+ if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
+ {
+ setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+ WGL_NO_RESET_NOTIFICATION_ARB);
+ }
+ else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
+ {
+ setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+ WGL_LOSE_CONTEXT_ON_RESET_ARB);
+ }
+
+ flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
+ }
+ }
+
+ if (ctxconfig->release)
+ {
+ if (_glfw.wgl.ARB_context_flush_control)
+ {
+ if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
+ {
+ setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
+ WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
+ }
+ else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
+ {
+ setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
+ WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
+ }
+ }
+ }
+
+ if (ctxconfig->noerror)
+ {
+ if (_glfw.wgl.ARB_create_context_no_error)
+ setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
+ }
+
+ // NOTE: Only request an explicitly versioned context when necessary, as
+ // explicitly requesting version 1.0 does not always return the
+ // highest version supported by the driver
+ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
+ {
+ setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
+ setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
+ }
+
+ if (flags)
+ setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
+
+ if (mask)
+ setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
+
+ setAttrib(0, 0);
+
+ window->context.wgl.handle =
+ _glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
+ share, attribs);
+ if (!window->context.wgl.handle)
+ {
+ const DWORD error = GetLastError();
+
+ if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
+ {
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: Driver does not support OpenGL version %i.%i",
+ ctxconfig->major,
+ ctxconfig->minor);
+ }
+ else
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: Driver does not support OpenGL ES version %i.%i",
+ ctxconfig->major,
+ ctxconfig->minor);
+ }
+ }
+ else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: Driver does not support the requested OpenGL profile");
+ }
+ else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "WGL: The share context is not compatible with the requested context");
+ }
+ else
+ {
+ if (ctxconfig->client == GLFW_OPENGL_API)
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: Failed to create OpenGL context");
+ }
+ else
+ {
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
+ "WGL: Failed to create OpenGL ES context");
+ }
+ }
+
+ return GLFW_FALSE;
+ }
+ }
+ else
+ {
+ window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
+ if (!window->context.wgl.handle)
+ {
+ _glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
+ "WGL: Failed to create OpenGL context");
+ return GLFW_FALSE;
+ }
+
+ if (share)
+ {
+ if (!wglShareLists(share, window->context.wgl.handle))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "WGL: Failed to enable sharing with specified OpenGL context");
+ return GLFW_FALSE;
+ }
+ }
+ }
+
+ window->context.makeCurrent = makeContextCurrentWGL;
+ window->context.swapBuffers = swapBuffersWGL;
+ window->context.swapInterval = swapIntervalWGL;
+ window->context.extensionSupported = extensionSupportedWGL;
+ window->context.getProcAddress = getProcAddressWGL;
+ window->context.destroy = destroyContextWGL;
+
+ return GLFW_TRUE;
+}
+
+#undef setAttrib
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (window->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return NULL;
+ }
+
+ return window->context.wgl.handle;
+}
+
diff --git a/src/external/glfw/src/wgl_context.h b/src/external/glfw/src/wgl_context.h
new file mode 100644
index 00000000..9fae9114
--- /dev/null
+++ b/src/external/glfw/src/wgl_context.h
@@ -0,0 +1,158 @@
+//========================================================================
+// GLFW 3.3 WGL - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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 WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_TYPE_RGBA_ARB 0x202b
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201a
+#define WGL_ALPHA_BITS_ARB 0x201b
+#define WGL_ALPHA_SHIFT_ARB 0x201c
+#define WGL_ACCUM_BITS_ARB 0x201d
+#define WGL_ACCUM_RED_BITS_ARB 0x201e
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_STEREO_ARB 0x2012
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_SAMPLES_ARB 0x2042
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
+#define WGL_COLORSPACE_EXT 0x309d
+#define WGL_COLORSPACE_SRGB_EXT 0x3089
+
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
+
+typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
+typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
+typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
+typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
+typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
+typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
+
+// opengl32.dll function pointer typedefs
+#define wglCreateContext _glfw.wgl.CreateContext
+#define wglDeleteContext _glfw.wgl.DeleteContext
+#define wglGetProcAddress _glfw.wgl.GetProcAddress
+#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
+#define wglMakeCurrent _glfw.wgl.MakeCurrent
+#define wglShareLists _glfw.wgl.ShareLists
+
+#define _GLFW_RECREATION_NOT_NEEDED 0
+#define _GLFW_RECREATION_REQUIRED 1
+#define _GLFW_RECREATION_IMPOSSIBLE 2
+
+#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
+#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
+
+
+// WGL-specific per-context data
+//
+typedef struct _GLFWcontextWGL
+{
+ HDC dc;
+ HGLRC handle;
+ int interval;
+
+} _GLFWcontextWGL;
+
+// WGL-specific global data
+//
+typedef struct _GLFWlibraryWGL
+{
+ HINSTANCE instance;
+ PFN_wglCreateContext CreateContext;
+ PFN_wglDeleteContext DeleteContext;
+ PFN_wglGetProcAddress GetProcAddress;
+ PFN_wglGetCurrentDC GetCurrentDC;
+ PFN_wglMakeCurrent MakeCurrent;
+ PFN_wglShareLists ShareLists;
+
+ GLFWbool extensionsLoaded;
+
+ PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
+ PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
+ PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
+ PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
+ PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
+ GLFWbool EXT_swap_control;
+ GLFWbool EXT_colorspace;
+ GLFWbool ARB_multisample;
+ GLFWbool ARB_framebuffer_sRGB;
+ GLFWbool EXT_framebuffer_sRGB;
+ GLFWbool ARB_pixel_format;
+ GLFWbool ARB_create_context;
+ GLFWbool ARB_create_context_profile;
+ GLFWbool EXT_create_context_es2_profile;
+ GLFWbool ARB_create_context_robustness;
+ GLFWbool ARB_create_context_no_error;
+ GLFWbool ARB_context_flush_control;
+
+} _GLFWlibraryWGL;
+
+
+GLFWbool _glfwInitWGL(void);
+void _glfwTerminateWGL(void);
+GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig);
+
diff --git a/src/external/glfw/src/win32_init.c b/src/external/glfw/src/win32_init.c
new file mode 100644
index 00000000..ee7ccfda
--- /dev/null
+++ b/src/external/glfw/src/win32_init.c
@@ -0,0 +1,583 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdlib.h>
+#include <malloc.h>
+
+static const GUID _glfw_GUID_DEVINTERFACE_HID =
+ {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
+
+#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
+
+#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
+
+// Executables (but not DLLs) exporting this symbol with this value will be
+// automatically directed to the high-performance GPU on Nvidia Optimus systems
+// with up-to-date drivers
+//
+__declspec(dllexport) DWORD NvOptimusEnablement = 1;
+
+// Executables (but not DLLs) exporting this symbol with this value will be
+// automatically directed to the high-performance GPU on AMD PowerXpress systems
+// with up-to-date drivers
+//
+__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
+
+#endif // _GLFW_USE_HYBRID_HPG
+
+#if defined(_GLFW_BUILD_DLL)
+
+// GLFW DLL entry point
+//
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+{
+ return TRUE;
+}
+
+#endif // _GLFW_BUILD_DLL
+
+// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
+BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp)
+{
+ OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
+ DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
+ ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
+ cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+ return VerifyVersionInfoW(&osvi, mask, cond);
+}
+
+// Load necessary libraries (DLLs)
+//
+static GLFWbool loadLibraries(void)
+{
+ _glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
+ if (!_glfw.win32.winmm.instance)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to load winmm.dll");
+ return GLFW_FALSE;
+ }
+
+ _glfw.win32.winmm.GetTime = (PFN_timeGetTime)
+ GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
+
+ _glfw.win32.user32.instance = LoadLibraryA("user32.dll");
+ if (!_glfw.win32.user32.instance)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to load user32.dll");
+ return GLFW_FALSE;
+ }
+
+ _glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
+ GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
+ _glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
+ GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
+
+ _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
+ if (_glfw.win32.dinput8.instance)
+ {
+ _glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
+ GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
+ }
+
+ {
+ int i;
+ const char* names[] =
+ {
+ "xinput1_4.dll",
+ "xinput1_3.dll",
+ "xinput9_1_0.dll",
+ "xinput1_2.dll",
+ "xinput1_1.dll",
+ NULL
+ };
+
+ for (i = 0; names[i]; i++)
+ {
+ _glfw.win32.xinput.instance = LoadLibraryA(names[i]);
+ if (_glfw.win32.xinput.instance)
+ {
+ _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
+ GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
+ _glfw.win32.xinput.GetState = (PFN_XInputGetState)
+ GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
+
+ break;
+ }
+ }
+ }
+
+ _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
+ if (_glfw.win32.dwmapi.instance)
+ {
+ _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
+ GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
+ _glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
+ GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
+ _glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
+ GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
+ }
+
+ _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
+ if (_glfw.win32.shcore.instance)
+ {
+ _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
+ GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
+ _glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
+ GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
+ }
+
+ return GLFW_TRUE;
+}
+
+// Unload used libraries (DLLs)
+//
+static void freeLibraries(void)
+{
+ if (_glfw.win32.xinput.instance)
+ FreeLibrary(_glfw.win32.xinput.instance);
+
+ if (_glfw.win32.dinput8.instance)
+ FreeLibrary(_glfw.win32.dinput8.instance);
+
+ if (_glfw.win32.winmm.instance)
+ FreeLibrary(_glfw.win32.winmm.instance);
+
+ if (_glfw.win32.user32.instance)
+ FreeLibrary(_glfw.win32.user32.instance);
+
+ if (_glfw.win32.dwmapi.instance)
+ FreeLibrary(_glfw.win32.dwmapi.instance);
+
+ if (_glfw.win32.shcore.instance)
+ FreeLibrary(_glfw.win32.shcore.instance);
+}
+
+// Create key code translation tables
+//
+static void createKeyTables(void)
+{
+ int scancode;
+
+ memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
+ memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
+
+ _glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
+ _glfw.win32.keycodes[0x002] = GLFW_KEY_1;
+ _glfw.win32.keycodes[0x003] = GLFW_KEY_2;
+ _glfw.win32.keycodes[0x004] = GLFW_KEY_3;
+ _glfw.win32.keycodes[0x005] = GLFW_KEY_4;
+ _glfw.win32.keycodes[0x006] = GLFW_KEY_5;
+ _glfw.win32.keycodes[0x007] = GLFW_KEY_6;
+ _glfw.win32.keycodes[0x008] = GLFW_KEY_7;
+ _glfw.win32.keycodes[0x009] = GLFW_KEY_8;
+ _glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
+ _glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
+ _glfw.win32.keycodes[0x030] = GLFW_KEY_B;
+ _glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
+ _glfw.win32.keycodes[0x020] = GLFW_KEY_D;
+ _glfw.win32.keycodes[0x012] = GLFW_KEY_E;
+ _glfw.win32.keycodes[0x021] = GLFW_KEY_F;
+ _glfw.win32.keycodes[0x022] = GLFW_KEY_G;
+ _glfw.win32.keycodes[0x023] = GLFW_KEY_H;
+ _glfw.win32.keycodes[0x017] = GLFW_KEY_I;
+ _glfw.win32.keycodes[0x024] = GLFW_KEY_J;
+ _glfw.win32.keycodes[0x025] = GLFW_KEY_K;
+ _glfw.win32.keycodes[0x026] = GLFW_KEY_L;
+ _glfw.win32.keycodes[0x032] = GLFW_KEY_M;
+ _glfw.win32.keycodes[0x031] = GLFW_KEY_N;
+ _glfw.win32.keycodes[0x018] = GLFW_KEY_O;
+ _glfw.win32.keycodes[0x019] = GLFW_KEY_P;
+ _glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
+ _glfw.win32.keycodes[0x013] = GLFW_KEY_R;
+ _glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
+ _glfw.win32.keycodes[0x014] = GLFW_KEY_T;
+ _glfw.win32.keycodes[0x016] = GLFW_KEY_U;
+ _glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
+ _glfw.win32.keycodes[0x011] = GLFW_KEY_W;
+ _glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
+ _glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
+ _glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
+
+ _glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
+ _glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
+ _glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
+ _glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
+ _glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
+ _glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
+ _glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
+ _glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
+ _glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
+ _glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
+ _glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
+ _glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
+
+ _glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
+ _glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
+ _glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
+ _glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
+ _glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
+ _glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
+ _glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
+ _glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
+ _glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
+ _glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
+ _glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
+ _glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
+ _glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
+ _glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
+ _glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
+ _glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
+ _glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
+ _glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
+ _glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
+ _glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
+ _glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
+ _glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
+ _glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
+ _glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
+ _glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
+ _glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
+ _glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
+ _glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
+ _glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
+ _glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
+ _glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
+ _glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
+ _glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
+ _glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
+ _glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
+ _glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
+ _glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
+ _glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
+ _glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
+ _glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
+ _glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
+ _glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
+ _glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
+ _glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
+ _glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
+ _glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
+ _glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
+ _glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
+ _glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
+ _glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
+ _glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
+ _glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
+ _glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
+ _glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
+
+ _glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
+ _glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
+ _glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
+ _glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
+ _glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
+ _glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
+ _glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
+ _glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
+ _glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
+ _glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
+ _glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
+ _glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
+ _glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
+ _glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
+ _glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
+ _glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
+
+ for (scancode = 0; scancode < 512; scancode++)
+ {
+ if (_glfw.win32.keycodes[scancode] > 0)
+ _glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
+ }
+}
+
+// Creates a dummy window for behind-the-scenes work
+//
+static HWND createHelperWindow(void)
+{
+ MSG msg;
+ HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
+ _GLFW_WNDCLASSNAME,
+ L"GLFW message window",
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ 0, 0, 1, 1,
+ NULL, NULL,
+ GetModuleHandleW(NULL),
+ NULL);
+ if (!window)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create helper window");
+ return NULL;
+ }
+
+ // HACK: The first call to ShowWindow is ignored if the parent process
+ // passed along a STARTUPINFO, so clear that flag with a no-op call
+ ShowWindow(window, SW_HIDE);
+
+ // Register for HID device notifications
+ {
+ DEV_BROADCAST_DEVICEINTERFACE_W dbi;
+ ZeroMemory(&dbi, sizeof(dbi));
+ dbi.dbcc_size = sizeof(dbi);
+ dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+ dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
+
+ RegisterDeviceNotificationW(window,
+ (DEV_BROADCAST_HDR*) &dbi,
+ DEVICE_NOTIFY_WINDOW_HANDLE);
+ }
+
+ while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+
+ return window;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Returns a wide string version of the specified UTF-8 string
+//
+WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
+{
+ WCHAR* target;
+ int count;
+
+ count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
+ if (!count)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to convert string from UTF-8");
+ return NULL;
+ }
+
+ target = calloc(count, sizeof(WCHAR));
+
+ if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to convert string from UTF-8");
+ free(target);
+ return NULL;
+ }
+
+ return target;
+}
+
+// Returns a UTF-8 string version of the specified wide string
+//
+char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
+{
+ char* target;
+ int size;
+
+ size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
+ if (!size)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to convert string to UTF-8");
+ return NULL;
+ }
+
+ target = calloc(size, 1);
+
+ if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to convert string to UTF-8");
+ free(target);
+ return NULL;
+ }
+
+ return target;
+}
+
+// Reports the specified error, appending information about the last Win32 error
+//
+void _glfwInputErrorWin32(int error, const char* description)
+{
+ WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
+ char message[_GLFW_MESSAGE_SIZE] = "";
+
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL,
+ GetLastError() & 0xffff,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buffer,
+ sizeof(buffer),
+ NULL);
+ WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
+
+ _glfwInputError(error, "%s: %s", description, message);
+}
+
+// Updates key names according to the current keyboard layout
+//
+void _glfwUpdateKeyNamesWin32(void)
+{
+ int key;
+ BYTE state[256] = {0};
+
+ memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
+
+ for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
+ {
+ UINT vk;
+ int scancode, length;
+ WCHAR chars[16];
+
+ scancode = _glfw.win32.scancodes[key];
+ if (scancode == -1)
+ continue;
+
+ if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
+ {
+ const UINT vks[] = {
+ VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
+ VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
+ VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
+ VK_MULTIPLY, VK_SUBTRACT, VK_ADD
+ };
+
+ vk = vks[key - GLFW_KEY_KP_0];
+ }
+ else
+ vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
+
+ length = ToUnicode(vk, scancode, state,
+ chars, sizeof(chars) / sizeof(WCHAR),
+ 0);
+
+ if (length == -1)
+ {
+ length = ToUnicode(vk, scancode, state,
+ chars, sizeof(chars) / sizeof(WCHAR),
+ 0);
+ }
+
+ if (length < 1)
+ continue;
+
+ WideCharToMultiByte(CP_UTF8, 0, chars, 1,
+ _glfw.win32.keynames[key],
+ sizeof(_glfw.win32.keynames[key]),
+ NULL, NULL);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformInit(void)
+{
+ // To make SetForegroundWindow work as we want, we need to fiddle
+ // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
+ // as possible in the hope of still being the foreground process)
+ SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
+ &_glfw.win32.foregroundLockTimeout, 0);
+ SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
+ SPIF_SENDCHANGE);
+
+ if (!loadLibraries())
+ return GLFW_FALSE;
+
+ createKeyTables();
+ _glfwUpdateKeyNamesWin32();
+
+ if (IsWindows8Point1OrGreater())
+ SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
+ else if (IsWindowsVistaOrGreater())
+ SetProcessDPIAware();
+
+ if (!_glfwRegisterWindowClassWin32())
+ return GLFW_FALSE;
+
+ _glfw.win32.helperWindowHandle = createHelperWindow();
+ if (!_glfw.win32.helperWindowHandle)
+ return GLFW_FALSE;
+
+ _glfwInitTimerWin32();
+ _glfwInitJoysticksWin32();
+
+ _glfwPollMonitorsWin32();
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformTerminate(void)
+{
+ if (_glfw.win32.helperWindowHandle)
+ DestroyWindow(_glfw.win32.helperWindowHandle);
+
+ _glfwUnregisterWindowClassWin32();
+
+ // Restore previous foreground lock timeout system setting
+ SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
+ UIntToPtr(_glfw.win32.foregroundLockTimeout),
+ SPIF_SENDCHANGE);
+
+ free(_glfw.win32.clipboardString);
+ free(_glfw.win32.rawInput);
+
+ _glfwTerminateWGL();
+ _glfwTerminateEGL();
+
+ _glfwTerminateJoysticksWin32();
+
+ freeLibraries();
+}
+
+const char* _glfwPlatformGetVersionString(void)
+{
+ return _GLFW_VERSION_NUMBER " Win32 WGL EGL"
+#if 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(_GLFW_BUILD_DLL)
+ " DLL"
+#endif
+ ;
+}
+
diff --git a/src/external/glfw/src/win32_joystick.c b/src/external/glfw/src/win32_joystick.c
new file mode 100644
index 00000000..ad2dbb2f
--- /dev/null
+++ b/src/external/glfw/src/win32_joystick.c
@@ -0,0 +1,751 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdio.h>
+#include <math.h>
+
+#define _GLFW_TYPE_AXIS 0
+#define _GLFW_TYPE_SLIDER 1
+#define _GLFW_TYPE_BUTTON 2
+#define _GLFW_TYPE_POV 3
+
+// Data produced with DirectInput device object enumeration
+//
+typedef struct _GLFWobjenumWin32
+{
+ IDirectInputDevice8W* device;
+ _GLFWjoyobjectWin32* objects;
+ int objectCount;
+ int axisCount;
+ int sliderCount;
+ int buttonCount;
+ int povCount;
+} _GLFWobjenumWin32;
+
+// Define local copies of the necessary GUIDs
+//
+static const GUID _glfw_IID_IDirectInput8W =
+ {0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
+static const GUID _glfw_GUID_XAxis =
+ {0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_YAxis =
+ {0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_ZAxis =
+ {0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_RxAxis =
+ {0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_RyAxis =
+ {0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_RzAxis =
+ {0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_Slider =
+ {0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+static const GUID _glfw_GUID_POV =
+ {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
+
+#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
+#define GUID_XAxis _glfw_GUID_XAxis
+#define GUID_YAxis _glfw_GUID_YAxis
+#define GUID_ZAxis _glfw_GUID_ZAxis
+#define GUID_RxAxis _glfw_GUID_RxAxis
+#define GUID_RyAxis _glfw_GUID_RyAxis
+#define GUID_RzAxis _glfw_GUID_RzAxis
+#define GUID_Slider _glfw_GUID_Slider
+#define GUID_POV _glfw_GUID_POV
+
+// Object data array for our clone of c_dfDIJoystick
+// Generated with https://github.com/elmindreda/c_dfDIJoystick2
+//
+static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
+{
+ { &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
+ { &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+ { NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
+};
+
+// Our clone of c_dfDIJoystick
+//
+static const DIDATAFORMAT _glfwDataFormat =
+{
+ sizeof(DIDATAFORMAT),
+ sizeof(DIOBJECTDATAFORMAT),
+ DIDFT_ABSAXIS,
+ sizeof(DIJOYSTATE),
+ sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
+ _glfwObjectDataFormats
+};
+
+// Returns a description fitting the specified XInput capabilities
+//
+static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
+{
+ switch (xic->SubType)
+ {
+ case XINPUT_DEVSUBTYPE_WHEEL:
+ return "XInput Wheel";
+ case XINPUT_DEVSUBTYPE_ARCADE_STICK:
+ return "XInput Arcade Stick";
+ case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
+ return "XInput Flight Stick";
+ case XINPUT_DEVSUBTYPE_DANCE_PAD:
+ return "XInput Dance Pad";
+ case XINPUT_DEVSUBTYPE_GUITAR:
+ return "XInput Guitar";
+ case XINPUT_DEVSUBTYPE_DRUM_KIT:
+ return "XInput Drum Kit";
+ case XINPUT_DEVSUBTYPE_GAMEPAD:
+ {
+ if (xic->Flags & XINPUT_CAPS_WIRELESS)
+ return "Wireless Xbox Controller";
+ else
+ return "Xbox Controller";
+ }
+ }
+
+ return "Unknown XInput Device";
+}
+
+// Lexically compare device objects
+//
+static int compareJoystickObjects(const void* first, const void* second)
+{
+ const _GLFWjoyobjectWin32* fo = first;
+ const _GLFWjoyobjectWin32* so = second;
+
+ if (fo->type != so->type)
+ return fo->type - so->type;
+
+ return fo->offset - so->offset;
+}
+
+// Checks whether the specified device supports XInput
+// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
+//
+static GLFWbool supportsXInput(const GUID* guid)
+{
+ UINT i, count = 0;
+ RAWINPUTDEVICELIST* ridl;
+ GLFWbool result = GLFW_FALSE;
+
+ if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
+ return GLFW_FALSE;
+
+ ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
+
+ if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
+ {
+ free(ridl);
+ return GLFW_FALSE;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ RID_DEVICE_INFO rdi;
+ char name[256];
+ UINT size;
+
+ if (ridl[i].dwType != RIM_TYPEHID)
+ continue;
+
+ ZeroMemory(&rdi, sizeof(rdi));
+ rdi.cbSize = sizeof(rdi);
+ size = sizeof(rdi);
+
+ if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
+ RIDI_DEVICEINFO,
+ &rdi, &size) == -1)
+ {
+ continue;
+ }
+
+ if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
+ continue;
+
+ memset(name, 0, sizeof(name));
+ size = sizeof(name);
+
+ if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
+ RIDI_DEVICENAME,
+ name, &size) == -1)
+ {
+ break;
+ }
+
+ name[sizeof(name) - 1] = '\0';
+ if (strstr(name, "IG_"))
+ {
+ result = GLFW_TRUE;
+ break;
+ }
+ }
+
+ free(ridl);
+ return result;
+}
+
+// Frees all resources associated with the specified joystick
+//
+static void closeJoystick(_GLFWjoystick* js)
+{
+ if (js->win32.device)
+ {
+ IDirectInputDevice8_Unacquire(js->win32.device);
+ IDirectInputDevice8_Release(js->win32.device);
+ }
+
+ _glfwFreeJoystick(js);
+ _glfwInputJoystick(js, GLFW_DISCONNECTED);
+}
+
+// DirectInput device object enumeration callback
+// Insights gleaned from SDL
+//
+static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
+ void* user)
+{
+ _GLFWobjenumWin32* data = user;
+ _GLFWjoyobjectWin32* object = data->objects + data->objectCount;
+
+ if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
+ {
+ DIPROPRANGE dipr;
+
+ if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_SLIDER(data->sliderCount);
+ else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_X;
+ else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_Y;
+ else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_Z;
+ else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_RX;
+ else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_RY;
+ else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
+ object->offset = DIJOFS_RZ;
+ else
+ return DIENUM_CONTINUE;
+
+ ZeroMemory(&dipr, sizeof(dipr));
+ dipr.diph.dwSize = sizeof(dipr);
+ dipr.diph.dwHeaderSize = sizeof(dipr.diph);
+ dipr.diph.dwObj = doi->dwType;
+ dipr.diph.dwHow = DIPH_BYID;
+ dipr.lMin = -32768;
+ dipr.lMax = 32767;
+
+ if (FAILED(IDirectInputDevice8_SetProperty(data->device,
+ DIPROP_RANGE,
+ &dipr.diph)))
+ {
+ return DIENUM_CONTINUE;
+ }
+
+ if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
+ {
+ object->type = _GLFW_TYPE_SLIDER;
+ data->sliderCount++;
+ }
+ else
+ {
+ object->type = _GLFW_TYPE_AXIS;
+ data->axisCount++;
+ }
+ }
+ else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
+ {
+ object->offset = DIJOFS_BUTTON(data->buttonCount);
+ object->type = _GLFW_TYPE_BUTTON;
+ data->buttonCount++;
+ }
+ else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
+ {
+ object->offset = DIJOFS_POV(data->povCount);
+ object->type = _GLFW_TYPE_POV;
+ data->povCount++;
+ }
+
+ data->objectCount++;
+ return DIENUM_CONTINUE;
+}
+
+// DirectInput device enumeration callback
+//
+static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
+{
+ int jid = 0;
+ DIDEVCAPS dc;
+ DIPROPDWORD dipd;
+ IDirectInputDevice8* device;
+ _GLFWobjenumWin32 data;
+ _GLFWjoystick* js;
+ char guid[33];
+ char name[256];
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ _GLFWjoystick* js = _glfw.joysticks + jid;
+ if (js->present)
+ {
+ if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
+ return DIENUM_CONTINUE;
+ }
+ }
+
+ if (supportsXInput(&di->guidProduct))
+ return DIENUM_CONTINUE;
+
+ if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
+ &di->guidInstance,
+ &device,
+ NULL)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
+ return DIENUM_CONTINUE;
+ }
+
+ if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to set device data format");
+
+ IDirectInputDevice8_Release(device);
+ return DIENUM_CONTINUE;
+ }
+
+ ZeroMemory(&dc, sizeof(dc));
+ dc.dwSize = sizeof(dc);
+
+ if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to query device capabilities");
+
+ IDirectInputDevice8_Release(device);
+ return DIENUM_CONTINUE;
+ }
+
+ ZeroMemory(&dipd, sizeof(dipd));
+ dipd.diph.dwSize = sizeof(dipd);
+ dipd.diph.dwHeaderSize = sizeof(dipd.diph);
+ dipd.diph.dwHow = DIPH_DEVICE;
+ dipd.dwData = DIPROPAXISMODE_ABS;
+
+ if (FAILED(IDirectInputDevice8_SetProperty(device,
+ DIPROP_AXISMODE,
+ &dipd.diph)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to set device axis mode");
+
+ IDirectInputDevice8_Release(device);
+ return DIENUM_CONTINUE;
+ }
+
+ memset(&data, 0, sizeof(data));
+ data.device = device;
+ data.objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs,
+ sizeof(_GLFWjoyobjectWin32));
+
+ if (FAILED(IDirectInputDevice8_EnumObjects(device,
+ deviceObjectCallback,
+ &data,
+ DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to enumerate device objects");
+
+ IDirectInputDevice8_Release(device);
+ free(data.objects);
+ return DIENUM_CONTINUE;
+ }
+
+ qsort(data.objects, data.objectCount,
+ sizeof(_GLFWjoyobjectWin32),
+ compareJoystickObjects);
+
+ if (!WideCharToMultiByte(CP_UTF8, 0,
+ di->tszInstanceName, -1,
+ name, sizeof(name),
+ NULL, NULL))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to convert joystick name to UTF-8");
+
+ IDirectInputDevice8_Release(device);
+ free(data.objects);
+ return DIENUM_STOP;
+ }
+
+ // Generate a joystick GUID that matches the SDL 2.0.5+ one
+ if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
+ {
+ sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
+ (uint8_t) di->guidProduct.Data1,
+ (uint8_t) (di->guidProduct.Data1 >> 8),
+ (uint8_t) (di->guidProduct.Data1 >> 16),
+ (uint8_t) (di->guidProduct.Data1 >> 24));
+ }
+ else
+ {
+ sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
+ name[0], name[1], name[2], name[3],
+ name[4], name[5], name[6], name[7],
+ name[8], name[9], name[10]);
+ }
+
+ js = _glfwAllocJoystick(name, guid,
+ data.axisCount + data.sliderCount,
+ data.buttonCount,
+ data.povCount);
+ if (!js)
+ {
+ IDirectInputDevice8_Release(device);
+ free(data.objects);
+ return DIENUM_STOP;
+ }
+
+ js->win32.device = device;
+ js->win32.guid = di->guidInstance;
+ js->win32.objects = data.objects;
+ js->win32.objectCount = data.objectCount;
+
+ _glfwInputJoystick(js, GLFW_CONNECTED);
+ return DIENUM_CONTINUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize joystick interface
+//
+void _glfwInitJoysticksWin32(void)
+{
+ if (_glfw.win32.dinput8.instance)
+ {
+ if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
+ DIRECTINPUT_VERSION,
+ &IID_IDirectInput8W,
+ (void**) &_glfw.win32.dinput8.api,
+ NULL)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create interface");
+ }
+ }
+
+ _glfwDetectJoystickConnectionWin32();
+}
+
+// Close all opened joystick handles
+//
+void _glfwTerminateJoysticksWin32(void)
+{
+ int jid;
+
+ for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
+ closeJoystick(_glfw.joysticks + jid);
+
+ if (_glfw.win32.dinput8.api)
+ IDirectInput8_Release(_glfw.win32.dinput8.api);
+}
+
+// Checks for new joysticks after DBT_DEVICEARRIVAL
+//
+void _glfwDetectJoystickConnectionWin32(void)
+{
+ if (_glfw.win32.xinput.instance)
+ {
+ DWORD index;
+
+ for (index = 0; index < XUSER_MAX_COUNT; index++)
+ {
+ int jid;
+ char guid[33];
+ XINPUT_CAPABILITIES xic;
+ _GLFWjoystick* js;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ if (_glfw.joysticks[jid].present &&
+ _glfw.joysticks[jid].win32.device == NULL &&
+ _glfw.joysticks[jid].win32.index == index)
+ {
+ break;
+ }
+ }
+
+ if (jid <= GLFW_JOYSTICK_LAST)
+ continue;
+
+ if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
+ continue;
+
+ // Generate a joystick GUID that matches the SDL 2.0.5+ one
+ sprintf(guid, "78696e707574%02x000000000000000000",
+ xic.SubType & 0xff);
+
+ js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
+ if (!js)
+ continue;
+
+ js->win32.index = index;
+
+ _glfwInputJoystick(js, GLFW_CONNECTED);
+ }
+ }
+
+ if (_glfw.win32.dinput8.api)
+ {
+ if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
+ DI8DEVCLASS_GAMECTRL,
+ deviceCallback,
+ NULL,
+ DIEDFL_ALLDEVICES)))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Failed to enumerate DirectInput8 devices");
+ return;
+ }
+ }
+}
+
+// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
+//
+void _glfwDetectJoystickDisconnectionWin32(void)
+{
+ int jid;
+
+ for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
+ {
+ _GLFWjoystick* js = _glfw.joysticks + jid;
+ if (js->present)
+ _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
+{
+ if (js->win32.device)
+ {
+ int i, ai = 0, bi = 0, pi = 0;
+ HRESULT result;
+ DIJOYSTATE state;
+
+ IDirectInputDevice8_Poll(js->win32.device);
+ result = IDirectInputDevice8_GetDeviceState(js->win32.device,
+ sizeof(state),
+ &state);
+ if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
+ {
+ IDirectInputDevice8_Acquire(js->win32.device);
+ IDirectInputDevice8_Poll(js->win32.device);
+ result = IDirectInputDevice8_GetDeviceState(js->win32.device,
+ sizeof(state),
+ &state);
+ }
+
+ if (FAILED(result))
+ {
+ closeJoystick(js);
+ return GLFW_FALSE;
+ }
+
+ if (mode == _GLFW_POLL_PRESENCE)
+ return GLFW_TRUE;
+
+ for (i = 0; i < js->win32.objectCount; i++)
+ {
+ const void* data = (char*) &state + js->win32.objects[i].offset;
+
+ switch (js->win32.objects[i].type)
+ {
+ case _GLFW_TYPE_AXIS:
+ case _GLFW_TYPE_SLIDER:
+ {
+ const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
+ _glfwInputJoystickAxis(js, ai, value);
+ ai++;
+ break;
+ }
+
+ case _GLFW_TYPE_BUTTON:
+ {
+ const char value = (*((BYTE*) data) & 0x80) != 0;
+ _glfwInputJoystickButton(js, bi, value);
+ bi++;
+ break;
+ }
+
+ case _GLFW_TYPE_POV:
+ {
+ const int states[9] =
+ {
+ GLFW_HAT_UP,
+ GLFW_HAT_RIGHT_UP,
+ GLFW_HAT_RIGHT,
+ GLFW_HAT_RIGHT_DOWN,
+ GLFW_HAT_DOWN,
+ GLFW_HAT_LEFT_DOWN,
+ GLFW_HAT_LEFT,
+ GLFW_HAT_LEFT_UP,
+ GLFW_HAT_CENTERED
+ };
+
+ // Screams of horror are appropriate at this point
+ int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
+ if (state < 0 || state > 8)
+ state = 8;
+
+ _glfwInputJoystickHat(js, pi, states[state]);
+ pi++;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ int i, dpad = 0;
+ DWORD result;
+ XINPUT_STATE xis;
+ const WORD buttons[10] =
+ {
+ XINPUT_GAMEPAD_A,
+ XINPUT_GAMEPAD_B,
+ XINPUT_GAMEPAD_X,
+ XINPUT_GAMEPAD_Y,
+ XINPUT_GAMEPAD_LEFT_SHOULDER,
+ XINPUT_GAMEPAD_RIGHT_SHOULDER,
+ XINPUT_GAMEPAD_BACK,
+ XINPUT_GAMEPAD_START,
+ XINPUT_GAMEPAD_LEFT_THUMB,
+ XINPUT_GAMEPAD_RIGHT_THUMB
+ };
+
+ result = XInputGetState(js->win32.index, &xis);
+ if (result != ERROR_SUCCESS)
+ {
+ if (result == ERROR_DEVICE_NOT_CONNECTED)
+ closeJoystick(js);
+
+ return GLFW_FALSE;
+ }
+
+ if (mode == _GLFW_POLL_PRESENCE)
+ return GLFW_TRUE;
+
+ _glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
+ _glfwInputJoystickAxis(js, 1, (xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
+ _glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
+ _glfwInputJoystickAxis(js, 3, (xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
+ _glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
+ _glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
+
+ for (i = 0; i < 10; i++)
+ {
+ const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
+ _glfwInputJoystickButton(js, i, value);
+ }
+
+ if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
+ dpad |= GLFW_HAT_UP;
+ if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
+ dpad |= GLFW_HAT_RIGHT;
+ if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
+ dpad |= GLFW_HAT_DOWN;
+ if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
+ dpad |= GLFW_HAT_LEFT;
+
+ _glfwInputJoystickHat(js, 0, dpad);
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformUpdateGamepadGUID(char* guid)
+{
+ if (strcmp(guid + 20, "504944564944") == 0)
+ {
+ char original[33];
+ strcpy(original, guid);
+ sprintf(guid, "03000000%.4s0000%.4s000000000000",
+ original, original + 4);
+ }
+}
+
diff --git a/src/external/glfw/src/win32_joystick.h b/src/external/glfw/src/win32_joystick.h
new file mode 100644
index 00000000..9156f6c1
--- /dev/null
+++ b/src/external/glfw/src/win32_joystick.h
@@ -0,0 +1,56 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
+#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
+
+#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
+
+// Joystick element (axis, button or slider)
+//
+typedef struct _GLFWjoyobjectWin32
+{
+ int offset;
+ int type;
+} _GLFWjoyobjectWin32;
+
+// Win32-specific per-joystick data
+//
+typedef struct _GLFWjoystickWin32
+{
+ _GLFWjoyobjectWin32* objects;
+ int objectCount;
+ IDirectInputDevice8W* device;
+ DWORD index;
+ GUID guid;
+} _GLFWjoystickWin32;
+
+
+void _glfwInitJoysticksWin32(void);
+void _glfwTerminateJoysticksWin32(void);
+void _glfwDetectJoystickConnectionWin32(void);
+void _glfwDetectJoystickDisconnectionWin32(void);
+
diff --git a/src/external/glfw/src/win32_monitor.c b/src/external/glfw/src/win32_monitor.c
new file mode 100644
index 00000000..74dd8252
--- /dev/null
+++ b/src/external/glfw/src/win32_monitor.c
@@ -0,0 +1,512 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <malloc.h>
+
+
+// Callback for EnumDisplayMonitors in createMonitor
+//
+static BOOL CALLBACK monitorCallback(HMONITOR handle,
+ HDC dc,
+ RECT* rect,
+ LPARAM data)
+{
+ MONITORINFOEXW mi;
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+
+ if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
+ {
+ _GLFWmonitor* monitor = (_GLFWmonitor*) data;
+ if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
+ monitor->win32.handle = handle;
+ }
+
+ return TRUE;
+}
+
+// Create monitor from an adapter and (optionally) a display
+//
+static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
+ DISPLAY_DEVICEW* display)
+{
+ _GLFWmonitor* monitor;
+ int widthMM, heightMM;
+ char* name;
+ HDC dc;
+ DEVMODEW dm;
+ RECT rect;
+
+ if (display)
+ name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
+ else
+ name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
+ if (!name)
+ return NULL;
+
+ ZeroMemory(&dm, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
+
+ dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
+
+ if (IsWindows8Point1OrGreater())
+ {
+ widthMM = GetDeviceCaps(dc, HORZSIZE);
+ heightMM = GetDeviceCaps(dc, VERTSIZE);
+ }
+ else
+ {
+ widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
+ heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
+ }
+
+ DeleteDC(dc);
+
+ monitor = _glfwAllocMonitor(name, widthMM, heightMM);
+ free(name);
+
+ if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
+ monitor->win32.modesPruned = GLFW_TRUE;
+
+ wcscpy(monitor->win32.adapterName, adapter->DeviceName);
+ WideCharToMultiByte(CP_UTF8, 0,
+ adapter->DeviceName, -1,
+ monitor->win32.publicAdapterName,
+ sizeof(monitor->win32.publicAdapterName),
+ NULL, NULL);
+
+ if (display)
+ {
+ wcscpy(monitor->win32.displayName, display->DeviceName);
+ WideCharToMultiByte(CP_UTF8, 0,
+ display->DeviceName, -1,
+ monitor->win32.publicDisplayName,
+ sizeof(monitor->win32.publicDisplayName),
+ NULL, NULL);
+ }
+
+ rect.left = dm.dmPosition.x;
+ rect.top = dm.dmPosition.y;
+ rect.right = dm.dmPosition.x + dm.dmPelsWidth;
+ rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
+
+ EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
+ return monitor;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Poll for changes in the set of connected monitors
+//
+void _glfwPollMonitorsWin32(void)
+{
+ int i, disconnectedCount;
+ _GLFWmonitor** disconnected = NULL;
+ DWORD adapterIndex, displayIndex;
+ DISPLAY_DEVICEW adapter, display;
+ _GLFWmonitor* monitor;
+
+ disconnectedCount = _glfw.monitorCount;
+ if (disconnectedCount)
+ {
+ disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
+ memcpy(disconnected,
+ _glfw.monitors,
+ _glfw.monitorCount * sizeof(_GLFWmonitor*));
+ }
+
+ for (adapterIndex = 0; ; adapterIndex++)
+ {
+ int type = _GLFW_INSERT_LAST;
+
+ ZeroMemory(&adapter, sizeof(adapter));
+ adapter.cb = sizeof(adapter);
+
+ if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
+ break;
+
+ if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
+ continue;
+
+ if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
+ type = _GLFW_INSERT_FIRST;
+
+ for (displayIndex = 0; ; displayIndex++)
+ {
+ ZeroMemory(&display, sizeof(display));
+ display.cb = sizeof(display);
+
+ if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
+ break;
+
+ if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
+ continue;
+
+ for (i = 0; i < disconnectedCount; i++)
+ {
+ if (disconnected[i] &&
+ wcscmp(disconnected[i]->win32.displayName,
+ display.DeviceName) == 0)
+ {
+ disconnected[i] = NULL;
+ break;
+ }
+ }
+
+ if (i < disconnectedCount)
+ continue;
+
+ monitor = createMonitor(&adapter, &display);
+ if (!monitor)
+ {
+ free(disconnected);
+ return;
+ }
+
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, type);
+
+ type = _GLFW_INSERT_LAST;
+ }
+
+ // HACK: If an active adapter does not have any display devices
+ // (as sometimes happens), add it directly as a monitor
+ if (displayIndex == 0)
+ {
+ for (i = 0; i < disconnectedCount; i++)
+ {
+ if (disconnected[i] &&
+ wcscmp(disconnected[i]->win32.adapterName,
+ adapter.DeviceName) == 0)
+ {
+ disconnected[i] = NULL;
+ break;
+ }
+ }
+
+ if (i < disconnectedCount)
+ continue;
+
+ monitor = createMonitor(&adapter, NULL);
+ if (!monitor)
+ {
+ free(disconnected);
+ return;
+ }
+
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, type);
+ }
+ }
+
+ for (i = 0; i < disconnectedCount; i++)
+ {
+ if (disconnected[i])
+ _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
+ }
+
+ free(disconnected);
+}
+
+// Change the current video mode
+//
+GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
+{
+ GLFWvidmode current;
+ const GLFWvidmode* best;
+ DEVMODEW dm;
+ LONG result;
+
+ best = _glfwChooseVideoMode(monitor, desired);
+ _glfwPlatformGetVideoMode(monitor, &current);
+ if (_glfwCompareVideoModes(&current, best) == 0)
+ return GLFW_TRUE;
+
+ ZeroMemory(&dm, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
+ DM_DISPLAYFREQUENCY;
+ dm.dmPelsWidth = best->width;
+ dm.dmPelsHeight = best->height;
+ dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
+ dm.dmDisplayFrequency = best->refreshRate;
+
+ if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
+ dm.dmBitsPerPel = 32;
+
+ result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
+ &dm,
+ NULL,
+ CDS_FULLSCREEN,
+ NULL);
+ if (result != DISP_CHANGE_SUCCESSFUL)
+ {
+ const char* description = "Unknown error";
+
+ if (result == DISP_CHANGE_BADDUALVIEW)
+ description = "The system uses DualView";
+ else if (result == DISP_CHANGE_BADFLAGS)
+ description = "Invalid flags";
+ else if (result == DISP_CHANGE_BADMODE)
+ description = "Graphics mode not supported";
+ else if (result == DISP_CHANGE_BADPARAM)
+ description = "Invalid parameter";
+ else if (result == DISP_CHANGE_FAILED)
+ description = "Graphics mode failed";
+ else if (result == DISP_CHANGE_NOTUPDATED)
+ description = "Failed to write to registry";
+ else if (result == DISP_CHANGE_RESTART)
+ description = "Computer restart required";
+
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to set video mode: %s",
+ description);
+
+ return GLFW_FALSE;
+ }
+
+ monitor->win32.modeChanged = GLFW_TRUE;
+ return GLFW_TRUE;
+}
+
+// Restore the previously saved (original) video mode
+//
+void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
+{
+ if (monitor->win32.modeChanged)
+ {
+ ChangeDisplaySettingsExW(monitor->win32.adapterName,
+ NULL, NULL, CDS_FULLSCREEN, NULL);
+ monitor->win32.modeChanged = GLFW_FALSE;
+ }
+}
+
+void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
+{
+ UINT xdpi, ydpi;
+
+ if (IsWindows8Point1OrGreater())
+ GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
+ else
+ {
+ const HDC dc = GetDC(NULL);
+ xdpi = GetDeviceCaps(dc, LOGPIXELSX);
+ ydpi = GetDeviceCaps(dc, LOGPIXELSY);
+ ReleaseDC(NULL, dc);
+ }
+
+ if (xscale)
+ *xscale = xdpi / 96.f;
+ if (yscale)
+ *yscale = ydpi / 96.f;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
+{
+ DEVMODEW dm;
+ ZeroMemory(&dm, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+
+ EnumDisplaySettingsExW(monitor->win32.adapterName,
+ ENUM_CURRENT_SETTINGS,
+ &dm,
+ EDS_ROTATEDMODE);
+
+ if (xpos)
+ *xpos = dm.dmPosition.x;
+ if (ypos)
+ *ypos = dm.dmPosition.y;
+}
+
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
+ float* xscale, float* yscale)
+{
+ _glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
+}
+
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
+{
+ int modeIndex = 0, size = 0;
+ GLFWvidmode* result = NULL;
+
+ *count = 0;
+
+ for (;;)
+ {
+ int i;
+ GLFWvidmode mode;
+ DEVMODEW dm;
+
+ ZeroMemory(&dm, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+
+ if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
+ break;
+
+ modeIndex++;
+
+ // Skip modes with less than 15 BPP
+ if (dm.dmBitsPerPel < 15)
+ continue;
+
+ mode.width = dm.dmPelsWidth;
+ mode.height = dm.dmPelsHeight;
+ mode.refreshRate = dm.dmDisplayFrequency;
+ _glfwSplitBPP(dm.dmBitsPerPel,
+ &mode.redBits,
+ &mode.greenBits,
+ &mode.blueBits);
+
+ for (i = 0; i < *count; i++)
+ {
+ if (_glfwCompareVideoModes(result + i, &mode) == 0)
+ break;
+ }
+
+ // Skip duplicate modes
+ if (i < *count)
+ continue;
+
+ if (monitor->win32.modesPruned)
+ {
+ // Skip modes not supported by the connected displays
+ if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
+ &dm,
+ NULL,
+ CDS_TEST,
+ NULL) != DISP_CHANGE_SUCCESSFUL)
+ {
+ continue;
+ }
+ }
+
+ if (*count == size)
+ {
+ size += 128;
+ result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
+ }
+
+ (*count)++;
+ result[*count - 1] = mode;
+ }
+
+ if (!*count)
+ {
+ // HACK: Report the current mode if no valid modes were found
+ result = calloc(1, sizeof(GLFWvidmode));
+ _glfwPlatformGetVideoMode(monitor, result);
+ *count = 1;
+ }
+
+ return result;
+}
+
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
+{
+ DEVMODEW dm;
+ ZeroMemory(&dm, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+
+ EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
+
+ mode->width = dm.dmPelsWidth;
+ mode->height = dm.dmPelsHeight;
+ mode->refreshRate = dm.dmDisplayFrequency;
+ _glfwSplitBPP(dm.dmBitsPerPel,
+ &mode->redBits,
+ &mode->greenBits,
+ &mode->blueBits);
+}
+
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
+{
+ HDC dc;
+ WORD values[768];
+
+ dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
+ GetDeviceGammaRamp(dc, values);
+ DeleteDC(dc);
+
+ _glfwAllocGammaArrays(ramp, 256);
+
+ memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
+ memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
+ memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
+}
+
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
+{
+ HDC dc;
+ WORD values[768];
+
+ if (ramp->size != 256)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Gamma ramp size must be 256");
+ return;
+ }
+
+ memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
+ memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
+ memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
+
+ dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
+ SetDeviceGammaRamp(dc, values);
+ DeleteDC(dc);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return monitor->win32.publicAdapterName;
+}
+
+GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return monitor->win32.publicDisplayName;
+}
+
diff --git a/src/external/glfw/src/win32_platform.h b/src/external/glfw/src/win32_platform.h
new file mode 100644
index 00000000..1bfc638f
--- /dev/null
+++ b/src/external/glfw/src/win32_platform.h
@@ -0,0 +1,409 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// 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.
+//
+//========================================================================
+
+// We don't need all the fancy stuff
+#ifndef NOMINMAX
+ #define NOMINMAX
+#endif
+
+#ifndef VC_EXTRALEAN
+ #define VC_EXTRALEAN
+#endif
+
+#ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN
+#endif
+
+// 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
+#undef APIENTRY
+
+// GLFW on Windows is Unicode only and does not work in MBCS mode
+#ifndef UNICODE
+ #define UNICODE
+#endif
+
+// GLFW requires Windows XP or later
+#if WINVER < 0x0501
+ #undef WINVER
+ #define WINVER 0x0501
+#endif
+#if _WIN32_WINNT < 0x0501
+ #undef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0501
+#endif
+
+// GLFW uses DirectInput8 interfaces
+#define DIRECTINPUT_VERSION 0x0800
+
+#include <wctype.h>
+#include <windows.h>
+#include <dinput.h>
+#include <xinput.h>
+#include <dbt.h>
+
+#if defined(_MSC_VER)
+ #include <malloc.h>
+ #define strdup _strdup
+#endif
+
+// HACK: Define macros that some windows.h variants don't
+#ifndef WM_MOUSEHWHEEL
+ #define WM_MOUSEHWHEEL 0x020E
+#endif
+#ifndef WM_DWMCOMPOSITIONCHANGED
+ #define WM_DWMCOMPOSITIONCHANGED 0x031E
+#endif
+#ifndef WM_COPYGLOBALDATA
+ #define WM_COPYGLOBALDATA 0x0049
+#endif
+#ifndef WM_UNICHAR
+ #define WM_UNICHAR 0x0109
+#endif
+#ifndef UNICODE_NOCHAR
+ #define UNICODE_NOCHAR 0xFFFF
+#endif
+#ifndef WM_DPICHANGED
+ #define WM_DPICHANGED 0x02E0
+#endif
+#ifndef GET_XBUTTON_WPARAM
+ #define GET_XBUTTON_WPARAM(w) (HIWORD(w))
+#endif
+#ifndef EDS_ROTATEDMODE
+ #define EDS_ROTATEDMODE 0x00000004
+#endif
+#ifndef DISPLAY_DEVICE_ACTIVE
+ #define DISPLAY_DEVICE_ACTIVE 0x00000001
+#endif
+#ifndef _WIN32_WINNT_WINBLUE
+ #define _WIN32_WINNT_WINBLUE 0x0602
+#endif
+
+#if WINVER < 0x0601
+typedef struct tagCHANGEFILTERSTRUCT
+{
+ DWORD cbSize;
+ DWORD ExtStatus;
+
+} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT;
+#ifndef MSGFLT_ALLOW
+ #define MSGFLT_ALLOW 1
+#endif
+#endif /*Windows 7*/
+
+#if WINVER < 0x0600
+#define DWM_BB_ENABLE 0x00000001
+#define DWM_BB_BLURREGION 0x00000002
+typedef struct
+{
+ DWORD dwFlags;
+ BOOL fEnable;
+ HRGN hRgnBlur;
+ BOOL fTransitionOnMaximized;
+} DWM_BLURBEHIND;
+#endif /*Windows Vista*/
+
+#ifndef DPI_ENUMS_DECLARED
+typedef enum PROCESS_DPI_AWARENESS
+{
+ PROCESS_DPI_UNAWARE = 0,
+ PROCESS_SYSTEM_DPI_AWARE = 1,
+ PROCESS_PER_MONITOR_DPI_AWARE = 2
+} PROCESS_DPI_AWARENESS;
+typedef enum MONITOR_DPI_TYPE
+{
+ MDT_EFFECTIVE_DPI = 0,
+ MDT_ANGULAR_DPI = 1,
+ MDT_RAW_DPI = 2,
+ MDT_DEFAULT = MDT_EFFECTIVE_DPI
+} MONITOR_DPI_TYPE;
+#endif /*DPI_ENUMS_DECLARED*/
+
+// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
+BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp);
+#define IsWindowsVistaOrGreater() \
+ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), \
+ LOBYTE(_WIN32_WINNT_VISTA), 0)
+#define IsWindows7OrGreater() \
+ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), \
+ LOBYTE(_WIN32_WINNT_WIN7), 0)
+#define IsWindows8OrGreater() \
+ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), \
+ LOBYTE(_WIN32_WINNT_WIN8), 0)
+#define IsWindows8Point1OrGreater() \
+ IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), \
+ LOBYTE(_WIN32_WINNT_WINBLUE), 0)
+
+// HACK: Define macros that some xinput.h variants don't
+#ifndef XINPUT_CAPS_WIRELESS
+ #define XINPUT_CAPS_WIRELESS 0x0002
+#endif
+#ifndef XINPUT_DEVSUBTYPE_WHEEL
+ #define XINPUT_DEVSUBTYPE_WHEEL 0x02
+#endif
+#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
+ #define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
+#endif
+#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
+ #define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
+#endif
+#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
+ #define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
+#endif
+#ifndef XINPUT_DEVSUBTYPE_GUITAR
+ #define XINPUT_DEVSUBTYPE_GUITAR 0x06
+#endif
+#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
+ #define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
+#endif
+#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
+ #define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
+#endif
+#ifndef XUSER_MAX_COUNT
+ #define XUSER_MAX_COUNT 4
+#endif
+
+// HACK: Define macros that some dinput.h variants don't
+#ifndef DIDFT_OPTIONAL
+ #define DIDFT_OPTIONAL 0x80000000
+#endif
+
+// winmm.dll function pointer typedefs
+typedef DWORD (WINAPI * PFN_timeGetTime)(void);
+#define timeGetTime _glfw.win32.winmm.GetTime
+
+// xinput.dll function pointer typedefs
+typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
+typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
+#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
+#define XInputGetState _glfw.win32.xinput.GetState
+
+// dinput8.dll function pointer typedefs
+typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
+#define DirectInput8Create _glfw.win32.dinput8.Create
+
+// user32.dll function pointer typedefs
+typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
+typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);
+#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
+#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
+
+// dwmapi.dll function pointer typedefs
+typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
+typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
+typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
+#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
+#define DwmFlush _glfw.win32.dwmapi.Flush
+#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
+
+// shcore.dll function pointer typedefs
+typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
+typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
+#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
+#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
+
+typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
+
+typedef struct VkWin32SurfaceCreateInfoKHR
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkWin32SurfaceCreateFlagsKHR flags;
+ HINSTANCE hinstance;
+ HWND hwnd;
+} VkWin32SurfaceCreateInfoKHR;
+
+typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
+
+#include "win32_joystick.h"
+#include "wgl_context.h"
+#include "egl_context.h"
+#include "osmesa_context.h"
+
+#define _GLFW_WNDCLASSNAME L"GLFW30"
+
+#define _glfw_dlopen(name) LoadLibraryA(name)
+#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
+#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
+
+#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
+#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
+
+#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
+#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
+#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
+#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
+#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
+#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
+
+
+// Win32-specific per-window data
+//
+typedef struct _GLFWwindowWin32
+{
+ HWND handle;
+ HICON bigIcon;
+ HICON smallIcon;
+
+ GLFWbool cursorTracked;
+ GLFWbool frameAction;
+ GLFWbool iconified;
+ GLFWbool maximized;
+ // Whether to enable framebuffer transparency on DWM
+ GLFWbool transparent;
+
+ // The last received cursor position, regardless of source
+ int lastCursorPosX, lastCursorPosY;
+
+} _GLFWwindowWin32;
+
+// Win32-specific global data
+//
+typedef struct _GLFWlibraryWin32
+{
+ HWND helperWindowHandle;
+ DWORD foregroundLockTimeout;
+ int acquiredMonitorCount;
+ char* clipboardString;
+ short int keycodes[512];
+ short int scancodes[GLFW_KEY_LAST + 1];
+ char keynames[GLFW_KEY_LAST + 1][5];
+ // Where to place the cursor when re-enabled
+ double restoreCursorPosX, restoreCursorPosY;
+ // The window whose disabled cursor mode is active
+ _GLFWwindow* disabledCursorWindow;
+ RAWINPUT* rawInput;
+ int rawInputSize;
+
+ struct {
+ HINSTANCE instance;
+ PFN_timeGetTime GetTime;
+ } winmm;
+
+ struct {
+ HINSTANCE instance;
+ PFN_DirectInput8Create Create;
+ IDirectInput8W* api;
+ } dinput8;
+
+ struct {
+ HINSTANCE instance;
+ PFN_XInputGetCapabilities GetCapabilities;
+ PFN_XInputGetState GetState;
+ } xinput;
+
+ struct {
+ HINSTANCE instance;
+ PFN_SetProcessDPIAware SetProcessDPIAware_;
+ PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
+ } user32;
+
+ struct {
+ HINSTANCE instance;
+ PFN_DwmIsCompositionEnabled IsCompositionEnabled;
+ PFN_DwmFlush Flush;
+ PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
+ } dwmapi;
+
+ struct {
+ HINSTANCE instance;
+ PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
+ PFN_GetDpiForMonitor GetDpiForMonitor_;
+ } shcore;
+
+} _GLFWlibraryWin32;
+
+// Win32-specific per-monitor data
+//
+typedef struct _GLFWmonitorWin32
+{
+ HMONITOR handle;
+ // This size matches the static size of DISPLAY_DEVICE.DeviceName
+ WCHAR adapterName[32];
+ WCHAR displayName[32];
+ char publicAdapterName[64];
+ char publicDisplayName[64];
+ GLFWbool modesPruned;
+ GLFWbool modeChanged;
+
+} _GLFWmonitorWin32;
+
+// Win32-specific per-cursor data
+//
+typedef struct _GLFWcursorWin32
+{
+ HCURSOR handle;
+
+} _GLFWcursorWin32;
+
+// Win32-specific global timer data
+//
+typedef struct _GLFWtimerWin32
+{
+ GLFWbool hasPC;
+ uint64_t frequency;
+
+} _GLFWtimerWin32;
+
+// Win32-specific thread local storage data
+//
+typedef struct _GLFWtlsWin32
+{
+ GLFWbool allocated;
+ DWORD index;
+
+} _GLFWtlsWin32;
+
+// Win32-specific mutex data
+//
+typedef struct _GLFWmutexWin32
+{
+ GLFWbool allocated;
+ CRITICAL_SECTION section;
+
+} _GLFWmutexWin32;
+
+
+GLFWbool _glfwRegisterWindowClassWin32(void);
+void _glfwUnregisterWindowClassWin32(void);
+GLFWbool _glfwIsCompositionEnabledWin32(void);
+
+WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
+char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
+void _glfwInputErrorWin32(int error, const char* description);
+void _glfwUpdateKeyNamesWin32(void);
+
+void _glfwInitTimerWin32(void);
+
+void _glfwPollMonitorsWin32(void);
+GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
+void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
+void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
+
diff --git a/src/external/glfw/src/win32_thread.c b/src/external/glfw/src/win32_thread.c
new file mode 100644
index 00000000..98231c1e
--- /dev/null
+++ b/src/external/glfw/src/win32_thread.c
@@ -0,0 +1,97 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
+{
+ assert(tls->win32.allocated == GLFW_FALSE);
+
+ tls->win32.index = TlsAlloc();
+ if (tls->win32.index == TLS_OUT_OF_INDEXES)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to allocate TLS index");
+ return GLFW_FALSE;
+ }
+
+ tls->win32.allocated = GLFW_TRUE;
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyTls(_GLFWtls* tls)
+{
+ if (tls->win32.allocated)
+ TlsFree(tls->win32.index);
+ memset(tls, 0, sizeof(_GLFWtls));
+}
+
+void* _glfwPlatformGetTls(_GLFWtls* tls)
+{
+ assert(tls->win32.allocated == GLFW_TRUE);
+ return TlsGetValue(tls->win32.index);
+}
+
+void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
+{
+ assert(tls->win32.allocated == GLFW_TRUE);
+ TlsSetValue(tls->win32.index, value);
+}
+
+GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
+{
+ assert(mutex->win32.allocated == GLFW_FALSE);
+ InitializeCriticalSection(&mutex->win32.section);
+ return mutex->win32.allocated = GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
+{
+ if (mutex->win32.allocated)
+ DeleteCriticalSection(&mutex->win32.section);
+ memset(mutex, 0, sizeof(_GLFWmutex));
+}
+
+void _glfwPlatformLockMutex(_GLFWmutex* mutex)
+{
+ assert(mutex->win32.allocated == GLFW_TRUE);
+ EnterCriticalSection(&mutex->win32.section);
+}
+
+void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
+{
+ assert(mutex->win32.allocated == GLFW_TRUE);
+ LeaveCriticalSection(&mutex->win32.section);
+}
+
diff --git a/src/external/glfw/src/win32_time.c b/src/external/glfw/src/win32_time.c
new file mode 100644
index 00000000..f333cd44
--- /dev/null
+++ b/src/external/glfw/src/win32_time.c
@@ -0,0 +1,74 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialise timer
+//
+void _glfwInitTimerWin32(void)
+{
+ uint64_t frequency;
+
+ if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
+ {
+ _glfw.timer.win32.hasPC = GLFW_TRUE;
+ _glfw.timer.win32.frequency = frequency;
+ }
+ else
+ {
+ _glfw.timer.win32.hasPC = GLFW_FALSE;
+ _glfw.timer.win32.frequency = 1000;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+uint64_t _glfwPlatformGetTimerValue(void)
+{
+ if (_glfw.timer.win32.hasPC)
+ {
+ uint64_t value;
+ QueryPerformanceCounter((LARGE_INTEGER*) &value);
+ return value;
+ }
+ else
+ return (uint64_t) timeGetTime();
+}
+
+uint64_t _glfwPlatformGetTimerFrequency(void)
+{
+ return _glfw.timer.win32.frequency;
+}
+
diff --git a/src/external/glfw/src/win32_window.c b/src/external/glfw/src/win32_window.c
new file mode 100644
index 00000000..6d3e76cc
--- /dev/null
+++ b/src/external/glfw/src/win32_window.c
@@ -0,0 +1,1953 @@
+//========================================================================
+// GLFW 3.3 Win32 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include <windowsx.h>
+#include <shellapi.h>
+
+#define _GLFW_KEY_INVALID -2
+
+// Returns the window style for the specified window
+//
+static DWORD getWindowStyle(const _GLFWwindow* window)
+{
+ DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+ if (window->monitor)
+ style |= WS_POPUP;
+ else
+ {
+ style |= WS_SYSMENU | WS_MINIMIZEBOX;
+
+ if (window->decorated)
+ {
+ style |= WS_CAPTION;
+
+ if (window->resizable)
+ style |= WS_MAXIMIZEBOX | WS_THICKFRAME;
+ }
+ else
+ style |= WS_POPUP;
+ }
+
+ return style;
+}
+
+// Returns the extended window style for the specified window
+//
+static DWORD getWindowExStyle(const _GLFWwindow* window)
+{
+ DWORD style = WS_EX_APPWINDOW;
+
+ if (window->monitor || window->floating)
+ style |= WS_EX_TOPMOST;
+
+ return style;
+}
+
+// Returns the image whose area most closely matches the desired one
+//
+static const GLFWimage* chooseImage(int count, const GLFWimage* images,
+ int width, int height)
+{
+ int i, leastDiff = INT_MAX;
+ const GLFWimage* closest = NULL;
+
+ for (i = 0; i < count; i++)
+ {
+ const int currDiff = abs(images[i].width * images[i].height -
+ width * height);
+ if (currDiff < leastDiff)
+ {
+ closest = images + i;
+ leastDiff = currDiff;
+ }
+ }
+
+ return closest;
+}
+
+// Creates an RGBA icon or cursor
+//
+static HICON createIcon(const GLFWimage* image,
+ int xhot, int yhot, GLFWbool icon)
+{
+ int i;
+ HDC dc;
+ HICON handle;
+ HBITMAP color, mask;
+ BITMAPV5HEADER bi;
+ ICONINFO ii;
+ unsigned char* target = NULL;
+ unsigned char* source = image->pixels;
+
+ ZeroMemory(&bi, sizeof(bi));
+ bi.bV5Size = sizeof(bi);
+ bi.bV5Width = image->width;
+ bi.bV5Height = -image->height;
+ bi.bV5Planes = 1;
+ bi.bV5BitCount = 32;
+ bi.bV5Compression = BI_BITFIELDS;
+ bi.bV5RedMask = 0x00ff0000;
+ bi.bV5GreenMask = 0x0000ff00;
+ bi.bV5BlueMask = 0x000000ff;
+ bi.bV5AlphaMask = 0xff000000;
+
+ dc = GetDC(NULL);
+ color = CreateDIBSection(dc,
+ (BITMAPINFO*) &bi,
+ DIB_RGB_COLORS,
+ (void**) &target,
+ NULL,
+ (DWORD) 0);
+ ReleaseDC(NULL, dc);
+
+ if (!color)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create RGBA bitmap");
+ return NULL;
+ }
+
+ mask = CreateBitmap(image->width, image->height, 1, 1, NULL);
+ if (!mask)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create mask bitmap");
+ DeleteObject(color);
+ return NULL;
+ }
+
+ for (i = 0; i < image->width * image->height; i++)
+ {
+ target[0] = source[2];
+ target[1] = source[1];
+ target[2] = source[0];
+ target[3] = source[3];
+ target += 4;
+ source += 4;
+ }
+
+ ZeroMemory(&ii, sizeof(ii));
+ ii.fIcon = icon;
+ ii.xHotspot = xhot;
+ ii.yHotspot = yhot;
+ ii.hbmMask = mask;
+ ii.hbmColor = color;
+
+ handle = CreateIconIndirect(&ii);
+
+ DeleteObject(color);
+ DeleteObject(mask);
+
+ if (!handle)
+ {
+ if (icon)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create icon");
+ }
+ else
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create cursor");
+ }
+ }
+
+ return handle;
+}
+
+// Translate client window size to full window size according to styles
+//
+static void getFullWindowSize(DWORD style, DWORD exStyle,
+ int clientWidth, int clientHeight,
+ int* fullWidth, int* fullHeight)
+{
+ RECT rect = { 0, 0, clientWidth, clientHeight };
+ AdjustWindowRectEx(&rect, style, FALSE, exStyle);
+ *fullWidth = rect.right - rect.left;
+ *fullHeight = rect.bottom - rect.top;
+}
+
+// Enforce the client rect aspect ratio based on which edge is being dragged
+//
+static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
+{
+ int xoff, yoff;
+ const float ratio = (float) window->numer / (float) window->denom;
+
+ getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
+ 0, 0, &xoff, &yoff);
+
+ if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT ||
+ edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT)
+ {
+ area->bottom = area->top + yoff +
+ (int) ((area->right - area->left - xoff) / ratio);
+ }
+ else if (edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)
+ {
+ area->top = area->bottom - yoff -
+ (int) ((area->right - area->left - xoff) / ratio);
+ }
+ else if (edge == WMSZ_TOP || edge == WMSZ_BOTTOM)
+ {
+ area->right = area->left + xoff +
+ (int) ((area->bottom - area->top - yoff) * ratio);
+ }
+}
+
+// Centers the cursor over the window client area
+//
+static void centerCursor(_GLFWwindow* window)
+{
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
+}
+
+// Returns whether the cursor is in the client area of the specified window
+//
+static GLFWbool cursorInClientArea(_GLFWwindow* window)
+{
+ RECT area;
+ POINT pos;
+
+ if (!GetCursorPos(&pos))
+ return GLFW_FALSE;
+
+ if (WindowFromPoint(pos) != window->win32.handle)
+ return GLFW_FALSE;
+
+ GetClientRect(window->win32.handle, &area);
+ ClientToScreen(window->win32.handle, (POINT*) &area.left);
+ ClientToScreen(window->win32.handle, (POINT*) &area.right);
+
+ return PtInRect(&area, pos);
+}
+
+// Updates the cursor image according to its cursor mode
+//
+static void updateCursorImage(_GLFWwindow* window)
+{
+ if (window->cursorMode == GLFW_CURSOR_NORMAL)
+ {
+ if (window->cursor)
+ SetCursor(window->cursor->win32.handle);
+ else
+ SetCursor(LoadCursorW(NULL, IDC_ARROW));
+ }
+ else
+ SetCursor(NULL);
+}
+
+// Updates the cursor clip rect
+//
+static void updateClipRect(_GLFWwindow* window)
+{
+ if (window)
+ {
+ RECT clipRect;
+ GetClientRect(window->win32.handle, &clipRect);
+ ClientToScreen(window->win32.handle, (POINT*) &clipRect.left);
+ ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
+ ClipCursor(&clipRect);
+ }
+ else
+ ClipCursor(NULL);
+}
+
+// Update native window styles to match attributes
+//
+static void updateWindowStyles(const _GLFWwindow* window)
+{
+ RECT rect;
+ DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
+ style &= ~(WS_OVERLAPPEDWINDOW | WS_POPUP);
+ style |= getWindowStyle(window);
+
+ GetClientRect(window->win32.handle, &rect);
+ AdjustWindowRectEx(&rect, style, FALSE, getWindowExStyle(window));
+ ClientToScreen(window->win32.handle, (POINT*) &rect.left);
+ ClientToScreen(window->win32.handle, (POINT*) &rect.right);
+ SetWindowLongW(window->win32.handle, GWL_STYLE, style);
+ SetWindowPos(window->win32.handle, HWND_TOP,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
+}
+
+// Update window framebuffer transparency
+//
+static void updateFramebufferTransparency(const _GLFWwindow* window)
+{
+ if (!IsWindowsVistaOrGreater())
+ return;
+
+ if (_glfwIsCompositionEnabledWin32())
+ {
+ HRGN region = CreateRectRgn(0, 0, -1, -1);
+ DWM_BLURBEHIND bb = {0};
+ bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
+ bb.hRgnBlur = region;
+ bb.fEnable = TRUE;
+
+ if (SUCCEEDED(DwmEnableBlurBehindWindow(window->win32.handle, &bb)))
+ {
+ // Decorated windows don't repaint the transparent background
+ // leaving a trail behind animations
+ // HACK: Making the window layered with a transparency color key
+ // seems to fix this. Normally, when specifying
+ // a transparency color key to be used when composing the
+ // layered window, all pixels painted by the window in this
+ // color will be transparent. That doesn't seem to be the
+ // case anymore, at least when used with blur behind window
+ // plus negative region.
+ LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
+ exStyle |= WS_EX_LAYERED;
+ SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
+
+ // Using a color key not equal to black to fix the trailing
+ // issue. When set to black, something is making the hit test
+ // not resize with the window frame.
+ SetLayeredWindowAttributes(window->win32.handle,
+ RGB(0, 193, 48), 255, LWA_COLORKEY);
+ }
+
+ DeleteObject(region);
+ }
+ else
+ {
+ LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
+ exStyle &= ~WS_EX_LAYERED;
+ SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
+ RedrawWindow(window->win32.handle, NULL, NULL,
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
+ }
+}
+
+// Translates a GLFW standard cursor to a resource ID
+//
+static LPWSTR translateCursorShape(int shape)
+{
+ switch (shape)
+ {
+ case GLFW_ARROW_CURSOR:
+ return IDC_ARROW;
+ case GLFW_IBEAM_CURSOR:
+ return IDC_IBEAM;
+ case GLFW_CROSSHAIR_CURSOR:
+ return IDC_CROSS;
+ case GLFW_HAND_CURSOR:
+ return IDC_HAND;
+ case GLFW_HRESIZE_CURSOR:
+ return IDC_SIZEWE;
+ case GLFW_VRESIZE_CURSOR:
+ return IDC_SIZENS;
+ }
+
+ return NULL;
+}
+
+// Retrieves and translates modifier keys
+//
+static int getKeyMods(void)
+{
+ int mods = 0;
+
+ if (GetKeyState(VK_SHIFT) & (1 << 31))
+ mods |= GLFW_MOD_SHIFT;
+ if (GetKeyState(VK_CONTROL) & (1 << 31))
+ mods |= GLFW_MOD_CONTROL;
+ if (GetKeyState(VK_MENU) & (1 << 31))
+ mods |= GLFW_MOD_ALT;
+ if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & (1 << 31))
+ mods |= GLFW_MOD_SUPER;
+
+ return mods;
+}
+
+// Retrieves and translates modifier keys
+//
+static int getAsyncKeyMods(void)
+{
+ int mods = 0;
+
+ if (GetAsyncKeyState(VK_SHIFT) & (1 << 31))
+ mods |= GLFW_MOD_SHIFT;
+ if (GetAsyncKeyState(VK_CONTROL) & (1 << 31))
+ mods |= GLFW_MOD_CONTROL;
+ if (GetAsyncKeyState(VK_MENU) & (1 << 31))
+ mods |= GLFW_MOD_ALT;
+ if ((GetAsyncKeyState(VK_LWIN) | GetAsyncKeyState(VK_RWIN)) & (1 << 31))
+ mods |= GLFW_MOD_SUPER;
+
+ return mods;
+}
+
+// Translates a Windows key to the corresponding GLFW key
+//
+static int translateKey(WPARAM wParam, LPARAM lParam)
+{
+ // The Ctrl keys require special handling
+ if (wParam == VK_CONTROL)
+ {
+ MSG next;
+ DWORD time;
+
+ // Right side keys have the extended key bit set
+ if (lParam & 0x01000000)
+ return GLFW_KEY_RIGHT_CONTROL;
+
+ // HACK: Alt Gr sends Left Ctrl and then Right Alt in close sequence
+ // We only want the Right Alt message, so if the next message is
+ // Right Alt we ignore this (synthetic) Left Ctrl message
+ time = GetMessageTime();
+
+ if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
+ {
+ if (next.message == WM_KEYDOWN ||
+ next.message == WM_SYSKEYDOWN ||
+ next.message == WM_KEYUP ||
+ next.message == WM_SYSKEYUP)
+ {
+ if (next.wParam == VK_MENU &&
+ (next.lParam & 0x01000000) &&
+ next.time == time)
+ {
+ // Next message is Right Alt down so discard this
+ return _GLFW_KEY_INVALID;
+ }
+ }
+ }
+
+ return GLFW_KEY_LEFT_CONTROL;
+ }
+
+ if (wParam == VK_PROCESSKEY)
+ {
+ // IME notifies that keys have been filtered by setting the virtual
+ // key-code to VK_PROCESSKEY
+ return _GLFW_KEY_INVALID;
+ }
+
+ return _glfw.win32.keycodes[HIWORD(lParam) & 0x1FF];
+}
+
+// Make the specified window and its video mode active on its monitor
+//
+static GLFWbool acquireMonitor(_GLFWwindow* window)
+{
+ GLFWvidmode mode;
+ GLFWbool status;
+ int xpos, ypos;
+
+ if (!_glfw.win32.acquiredMonitorCount)
+ SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
+ if (!window->monitor->window)
+ _glfw.win32.acquiredMonitorCount++;
+
+ status = _glfwSetVideoModeWin32(window->monitor, &window->videoMode);
+
+ _glfwPlatformGetVideoMode(window->monitor, &mode);
+ _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
+
+ SetWindowPos(window->win32.handle, HWND_TOPMOST,
+ xpos, ypos, mode.width, mode.height,
+ SWP_NOACTIVATE | SWP_NOCOPYBITS);
+
+ _glfwInputMonitorWindow(window->monitor, window);
+ return status;
+}
+
+// Remove the window and restore the original video mode
+//
+static void releaseMonitor(_GLFWwindow* window)
+{
+ if (window->monitor->window != window)
+ return;
+
+ _glfw.win32.acquiredMonitorCount--;
+ if (!_glfw.win32.acquiredMonitorCount)
+ SetThreadExecutionState(ES_CONTINUOUS);
+
+ _glfwInputMonitorWindow(window->monitor, NULL);
+ _glfwRestoreVideoModeWin32(window->monitor);
+}
+
+// Window callback function (handles window messages)
+//
+static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+ _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
+ if (!window)
+ {
+ // This is the message handling for the hidden helper window
+
+ switch (uMsg)
+ {
+ case WM_DISPLAYCHANGE:
+ _glfwPollMonitorsWin32();
+ break;
+
+ case WM_DEVICECHANGE:
+ {
+ if (wParam == DBT_DEVICEARRIVAL)
+ {
+ DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
+ if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+ _glfwDetectJoystickConnectionWin32();
+ }
+ else if (wParam == DBT_DEVICEREMOVECOMPLETE)
+ {
+ DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
+ if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+ _glfwDetectJoystickDisconnectionWin32();
+ }
+
+ break;
+ }
+ }
+
+ return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+ }
+
+ switch (uMsg)
+ {
+ case WM_MOUSEACTIVATE:
+ {
+ // HACK: Postpone cursor disabling when the window was activated by
+ // clicking a caption button
+ if (HIWORD(lParam) == WM_LBUTTONDOWN)
+ {
+ if (LOWORD(lParam) == HTCLOSE ||
+ LOWORD(lParam) == HTMINBUTTON ||
+ LOWORD(lParam) == HTMAXBUTTON)
+ {
+ window->win32.frameAction = GLFW_TRUE;
+ }
+ }
+
+ break;
+ }
+
+ case WM_CAPTURECHANGED:
+ {
+ // HACK: Disable the cursor once the caption button action has been
+ // completed or cancelled
+ if (lParam == 0 && window->win32.frameAction)
+ {
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
+
+ window->win32.frameAction = GLFW_FALSE;
+ }
+
+ break;
+ }
+
+ case WM_SETFOCUS:
+ {
+ _glfwInputWindowFocus(window, GLFW_TRUE);
+
+ // HACK: Do not disable cursor while the user is interacting with
+ // a caption button
+ if (window->win32.frameAction)
+ break;
+
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
+
+ return 0;
+ }
+
+ case WM_KILLFOCUS:
+ {
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
+
+ if (window->monitor && window->autoIconify)
+ _glfwPlatformIconifyWindow(window);
+
+ _glfwInputWindowFocus(window, GLFW_FALSE);
+ return 0;
+ }
+
+ case WM_SYSCOMMAND:
+ {
+ switch (wParam & 0xfff0)
+ {
+ case SC_SCREENSAVE:
+ case SC_MONITORPOWER:
+ {
+ if (window->monitor)
+ {
+ // We are running in full screen mode, so disallow
+ // screen saver and screen blanking
+ return 0;
+ }
+ else
+ break;
+ }
+
+ // User trying to access application menu using ALT?
+ case SC_KEYMENU:
+ return 0;
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ _glfwInputWindowCloseRequest(window);
+ return 0;
+ }
+
+ case WM_INPUTLANGCHANGE:
+ {
+ _glfwUpdateKeyNamesWin32();
+ break;
+ }
+
+ case WM_CHAR:
+ case WM_SYSCHAR:
+ case WM_UNICHAR:
+ {
+ const GLFWbool plain = (uMsg != WM_SYSCHAR);
+
+ if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
+ {
+ // WM_UNICHAR is not sent by Windows, but is sent by some
+ // third-party input method engine
+ // Returning TRUE here announces support for this message
+ return TRUE;
+ }
+
+ _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), plain);
+ return 0;
+ }
+
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ {
+ const int key = translateKey(wParam, lParam);
+ const int scancode = (lParam >> 16) & 0x1ff;
+ const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;
+ const int mods = getKeyMods();
+
+ if (key == _GLFW_KEY_INVALID)
+ break;
+
+ if (action == GLFW_RELEASE && wParam == VK_SHIFT)
+ {
+ // HACK: Release both Shift keys on Shift up event, as when both
+ // are pressed the first release does not emit any event
+ // NOTE: The other half of this is in _glfwPlatformPollEvents
+ _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
+ _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
+ }
+ else if (wParam == VK_SNAPSHOT)
+ {
+ // HACK: Key down is not reported for the Print Screen key
+ _glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
+ _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
+ }
+ else
+ _glfwInputKey(window, key, scancode, action, mods);
+
+ break;
+ }
+
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_XBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_XBUTTONUP:
+ {
+ int i, button, action;
+
+ if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
+ button = GLFW_MOUSE_BUTTON_LEFT;
+ else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP)
+ button = GLFW_MOUSE_BUTTON_RIGHT;
+ else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
+ button = GLFW_MOUSE_BUTTON_MIDDLE;
+ else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
+ button = GLFW_MOUSE_BUTTON_4;
+ else
+ button = GLFW_MOUSE_BUTTON_5;
+
+ if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN ||
+ uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
+ {
+ action = GLFW_PRESS;
+ }
+ else
+ action = GLFW_RELEASE;
+
+ for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
+ {
+ if (window->mouseButtons[i] == GLFW_PRESS)
+ break;
+ }
+
+ if (i > GLFW_MOUSE_BUTTON_LAST)
+ SetCapture(hWnd);
+
+ _glfwInputMouseClick(window, button, action, getKeyMods());
+
+ for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
+ {
+ if (window->mouseButtons[i] == GLFW_PRESS)
+ break;
+ }
+
+ if (i > GLFW_MOUSE_BUTTON_LAST)
+ ReleaseCapture();
+
+ if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
+ return TRUE;
+
+ return 0;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ const int x = GET_X_LPARAM(lParam);
+ const int y = GET_Y_LPARAM(lParam);
+
+ // Disabled cursor motion input is provided by WM_INPUT
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ break;
+
+ _glfwInputCursorPos(window, x, y);
+
+ window->win32.lastCursorPosX = x;
+ window->win32.lastCursorPosY = y;
+
+ if (!window->win32.cursorTracked)
+ {
+ TRACKMOUSEEVENT tme;
+ ZeroMemory(&tme, sizeof(tme));
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = window->win32.handle;
+ TrackMouseEvent(&tme);
+
+ window->win32.cursorTracked = GLFW_TRUE;
+ _glfwInputCursorEnter(window, GLFW_TRUE);
+ }
+
+ return 0;
+ }
+
+ case WM_INPUT:
+ {
+ UINT size;
+ HRAWINPUT ri = (HRAWINPUT) lParam;
+ RAWINPUT* data;
+ int dx, dy;
+
+ // Only process input when disabled cursor mode is applied
+ if (_glfw.win32.disabledCursorWindow != window)
+ break;
+
+ GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
+ if (size > (UINT) _glfw.win32.rawInputSize)
+ {
+ free(_glfw.win32.rawInput);
+ _glfw.win32.rawInput = calloc(size, 1);
+ _glfw.win32.rawInputSize = size;
+ }
+
+ size = _glfw.win32.rawInputSize;
+ if (GetRawInputData(ri, RID_INPUT,
+ _glfw.win32.rawInput, &size,
+ sizeof(RAWINPUTHEADER)) == (UINT) -1)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to retrieve raw input data");
+ break;
+ }
+
+ data = _glfw.win32.rawInput;
+ if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
+ {
+ dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
+ dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
+ }
+ else
+ {
+ dx = data->data.mouse.lLastX;
+ dy = data->data.mouse.lLastY;
+ }
+
+ _glfwInputCursorPos(window,
+ window->virtualCursorPosX + dx,
+ window->virtualCursorPosY + dy);
+
+ window->win32.lastCursorPosX += dx;
+ window->win32.lastCursorPosY += dy;
+ break;
+ }
+
+ case WM_MOUSELEAVE:
+ {
+ window->win32.cursorTracked = GLFW_FALSE;
+ _glfwInputCursorEnter(window, GLFW_FALSE);
+ return 0;
+ }
+
+ case WM_MOUSEWHEEL:
+ {
+ _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
+ return 0;
+ }
+
+ case WM_MOUSEHWHEEL:
+ {
+ // This message is only sent on Windows Vista and later
+ // NOTE: The X-axis is inverted for consistency with macOS and X11
+ _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
+ return 0;
+ }
+
+ case WM_ENTERSIZEMOVE:
+ case WM_ENTERMENULOOP:
+ {
+ // HACK: Postpone cursor disabling while the user is moving or
+ // resizing the window or using the menu
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
+
+ break;
+ }
+
+ case WM_EXITSIZEMOVE:
+ case WM_EXITMENULOOP:
+ {
+ // HACK: Disable the cursor once the user is done moving or
+ // resizing the window or using the menu
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
+
+ break;
+ }
+
+ case WM_SIZE:
+ {
+ const GLFWbool iconified = wParam == SIZE_MINIMIZED;
+ const GLFWbool maximized = wParam == SIZE_MAXIMIZED ||
+ (window->win32.maximized &&
+ wParam != SIZE_RESTORED);
+
+ if (_glfw.win32.disabledCursorWindow == window)
+ updateClipRect(window);
+
+ if (window->win32.iconified != iconified)
+ _glfwInputWindowIconify(window, iconified);
+
+ if (window->win32.maximized != maximized)
+ _glfwInputWindowMaximize(window, maximized);
+
+ _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));
+ _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));
+
+ if (window->monitor && window->win32.iconified != iconified)
+ {
+ if (iconified)
+ releaseMonitor(window);
+ else
+ acquireMonitor(window);
+ }
+
+ window->win32.iconified = iconified;
+ window->win32.maximized = maximized;
+ return 0;
+ }
+
+ case WM_MOVE:
+ {
+ if (_glfw.win32.disabledCursorWindow == window)
+ updateClipRect(window);
+
+ // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
+ // those macros do not handle negative window positions correctly
+ _glfwInputWindowPos(window,
+ GET_X_LPARAM(lParam),
+ GET_Y_LPARAM(lParam));
+ return 0;
+ }
+
+ case WM_SIZING:
+ {
+ if (window->numer == GLFW_DONT_CARE ||
+ window->denom == GLFW_DONT_CARE)
+ {
+ break;
+ }
+
+ applyAspectRatio(window, (int) wParam, (RECT*) lParam);
+ return TRUE;
+ }
+
+ case WM_GETMINMAXINFO:
+ {
+ int xoff, yoff;
+ MINMAXINFO* mmi = (MINMAXINFO*) lParam;
+
+ if (window->monitor)
+ break;
+
+ getFullWindowSize(getWindowStyle(window), getWindowExStyle(window),
+ 0, 0, &xoff, &yoff);
+
+ if (window->minwidth != GLFW_DONT_CARE &&
+ window->minheight != GLFW_DONT_CARE)
+ {
+ mmi->ptMinTrackSize.x = window->minwidth + xoff;
+ mmi->ptMinTrackSize.y = window->minheight + yoff;
+ }
+
+ if (window->maxwidth != GLFW_DONT_CARE &&
+ window->maxheight != GLFW_DONT_CARE)
+ {
+ mmi->ptMaxTrackSize.x = window->maxwidth + xoff;
+ mmi->ptMaxTrackSize.y = window->maxheight + yoff;
+ }
+
+ if (!window->decorated)
+ {
+ MONITORINFO mi;
+ const HMONITOR mh = MonitorFromWindow(window->win32.handle,
+ MONITOR_DEFAULTTONEAREST);
+
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfo(mh, &mi);
+
+ mmi->ptMaxPosition.x = mi.rcWork.left - mi.rcMonitor.left;
+ mmi->ptMaxPosition.y = mi.rcWork.top - mi.rcMonitor.top;
+ mmi->ptMaxSize.x = mi.rcWork.right - mi.rcWork.left;
+ mmi->ptMaxSize.y = mi.rcWork.bottom - mi.rcWork.top;
+ }
+
+ return 0;
+ }
+
+ case WM_PAINT:
+ {
+ _glfwInputWindowDamage(window);
+ break;
+ }
+
+ case WM_ERASEBKGND:
+ {
+ return TRUE;
+ }
+
+ case WM_DWMCOMPOSITIONCHANGED:
+ {
+ if (window->win32.transparent)
+ updateFramebufferTransparency(window);
+ return 0;
+ }
+
+ case WM_SETCURSOR:
+ {
+ if (LOWORD(lParam) == HTCLIENT)
+ {
+ updateCursorImage(window);
+ return TRUE;
+ }
+
+ break;
+ }
+
+ case WM_DROPFILES:
+ {
+ HDROP drop = (HDROP) wParam;
+ POINT pt;
+ int i;
+
+ const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
+ char** paths = calloc(count, sizeof(char*));
+
+ // Move the mouse to the position of the drop
+ DragQueryPoint(drop, &pt);
+ _glfwInputCursorPos(window, pt.x, pt.y);
+
+ for (i = 0; i < count; i++)
+ {
+ const UINT length = DragQueryFileW(drop, i, NULL, 0);
+ WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));
+
+ DragQueryFileW(drop, i, buffer, length + 1);
+ paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
+
+ free(buffer);
+ }
+
+ _glfwInputDrop(window, count, (const char**) paths);
+
+ for (i = 0; i < count; i++)
+ free(paths[i]);
+ free(paths);
+
+ DragFinish(drop);
+ return 0;
+ }
+ }
+
+ return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+}
+
+// Creates the GLFW window
+//
+static int createNativeWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ int xpos, ypos, fullWidth, fullHeight;
+ WCHAR* wideTitle;
+ DWORD style = getWindowStyle(window);
+ DWORD exStyle = getWindowExStyle(window);
+
+ if (window->monitor)
+ {
+ GLFWvidmode mode;
+
+ // NOTE: This window placement is temporary and approximate, as the
+ // correct position and size cannot be known until the monitor
+ // video mode has been picked in _glfwSetVideoModeWin32
+ _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
+ _glfwPlatformGetVideoMode(window->monitor, &mode);
+ fullWidth = mode.width;
+ fullHeight = mode.height;
+ }
+ else
+ {
+ xpos = CW_USEDEFAULT;
+ ypos = CW_USEDEFAULT;
+
+ if (wndconfig->maximized)
+ style |= WS_MAXIMIZE;
+
+ getFullWindowSize(style, exStyle,
+ wndconfig->width, wndconfig->height,
+ &fullWidth, &fullHeight);
+ }
+
+ wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
+ if (!wideTitle)
+ return GLFW_FALSE;
+
+ window->win32.handle = CreateWindowExW(exStyle,
+ _GLFW_WNDCLASSNAME,
+ wideTitle,
+ style,
+ xpos, ypos,
+ fullWidth, fullHeight,
+ NULL, // No parent window
+ NULL, // No window menu
+ GetModuleHandleW(NULL),
+ NULL);
+
+ free(wideTitle);
+
+ if (!window->win32.handle)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create window");
+ return GLFW_FALSE;
+ }
+
+ SetPropW(window->win32.handle, L"GLFW", window);
+
+ if (IsWindows7OrGreater())
+ {
+ ChangeWindowMessageFilterEx(window->win32.handle,
+ WM_DROPFILES, MSGFLT_ALLOW, NULL);
+ ChangeWindowMessageFilterEx(window->win32.handle,
+ WM_COPYDATA, MSGFLT_ALLOW, NULL);
+ ChangeWindowMessageFilterEx(window->win32.handle,
+ WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
+ }
+
+ DragAcceptFiles(window->win32.handle, TRUE);
+
+ if (fbconfig->transparent)
+ {
+ updateFramebufferTransparency(window);
+ window->win32.transparent = GLFW_TRUE;
+ }
+
+ return GLFW_TRUE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Registers the GLFW window class
+//
+GLFWbool _glfwRegisterWindowClassWin32(void)
+{
+ WNDCLASSEXW wc;
+
+ ZeroMemory(&wc, sizeof(wc));
+ wc.cbSize = sizeof(wc);
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+ wc.lpfnWndProc = (WNDPROC) windowProc;
+ wc.hInstance = GetModuleHandleW(NULL);
+ wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
+ wc.lpszClassName = _GLFW_WNDCLASSNAME;
+
+ // Load user-provided icon if available
+ wc.hIcon = LoadImageW(GetModuleHandleW(NULL),
+ L"GLFW_ICON", IMAGE_ICON,
+ 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ if (!wc.hIcon)
+ {
+ // No user-provided icon found, load default icon
+ wc.hIcon = LoadImageW(NULL,
+ IDI_APPLICATION, IMAGE_ICON,
+ 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ }
+
+ if (!RegisterClassExW(&wc))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to register window class");
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+// Unregisters the GLFW window class
+//
+void _glfwUnregisterWindowClassWin32(void)
+{
+ UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
+}
+
+// Returns whether desktop compositing is enabled
+//
+GLFWbool _glfwIsCompositionEnabledWin32(void)
+{
+ if (IsWindowsVistaOrGreater())
+ {
+ BOOL enabled;
+ if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)))
+ return enabled;
+ }
+
+ return FALSE;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ if (!createNativeWindow(window, wndconfig, fbconfig))
+ return GLFW_FALSE;
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
+ {
+ if (!_glfwInitWGL())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
+ {
+ if (!_glfwInitEGL())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwInitOSMesa())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ }
+
+ if (window->monitor)
+ {
+ _glfwPlatformShowWindow(window);
+ _glfwPlatformFocusWindow(window);
+ if (!acquireMonitor(window))
+ return GLFW_FALSE;
+
+ if (wndconfig->centerCursor)
+ centerCursor(window);
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+{
+ if (window->monitor)
+ releaseMonitor(window);
+
+ if (window->context.destroy)
+ window->context.destroy(window);
+
+ if (_glfw.win32.disabledCursorWindow == window)
+ _glfw.win32.disabledCursorWindow = NULL;
+
+ if (window->win32.handle)
+ {
+ RemovePropW(window->win32.handle, L"GLFW");
+ DestroyWindow(window->win32.handle);
+ window->win32.handle = NULL;
+ }
+
+ if (window->win32.bigIcon)
+ DestroyIcon(window->win32.bigIcon);
+
+ if (window->win32.smallIcon)
+ DestroyIcon(window->win32.smallIcon);
+}
+
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
+{
+ WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
+ if (!wideTitle)
+ return;
+
+ SetWindowTextW(window->win32.handle, wideTitle);
+ free(wideTitle);
+}
+
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
+ int count, const GLFWimage* images)
+{
+ HICON bigIcon = NULL, smallIcon = NULL;
+
+ if (count)
+ {
+ const GLFWimage* bigImage = chooseImage(count, images,
+ GetSystemMetrics(SM_CXICON),
+ GetSystemMetrics(SM_CYICON));
+ const GLFWimage* smallImage = chooseImage(count, images,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON));
+
+ bigIcon = createIcon(bigImage, 0, 0, GLFW_TRUE);
+ smallIcon = createIcon(smallImage, 0, 0, GLFW_TRUE);
+ }
+ else
+ {
+ bigIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICON);
+ smallIcon = (HICON) GetClassLongPtrW(window->win32.handle, GCLP_HICONSM);
+ }
+
+ SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon);
+ SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon);
+
+ if (window->win32.bigIcon)
+ DestroyIcon(window->win32.bigIcon);
+
+ if (window->win32.smallIcon)
+ DestroyIcon(window->win32.smallIcon);
+
+ if (count)
+ {
+ window->win32.bigIcon = bigIcon;
+ window->win32.smallIcon = smallIcon;
+ }
+}
+
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+{
+ POINT pos = { 0, 0 };
+ ClientToScreen(window->win32.handle, &pos);
+
+ if (xpos)
+ *xpos = pos.x;
+ if (ypos)
+ *ypos = pos.y;
+}
+
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
+{
+ RECT rect = { xpos, ypos, xpos, ypos };
+ AdjustWindowRectEx(&rect, getWindowStyle(window),
+ FALSE, getWindowExStyle(window));
+ SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
+}
+
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
+{
+ RECT area;
+ GetClientRect(window->win32.handle, &area);
+
+ if (width)
+ *width = area.right;
+ if (height)
+ *height = area.bottom;
+}
+
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
+{
+ if (window->monitor)
+ {
+ if (window->monitor->window == window)
+ acquireMonitor(window);
+ }
+ else
+ {
+ RECT rect = { 0, 0, width, height };
+ AdjustWindowRectEx(&rect, getWindowStyle(window),
+ FALSE, getWindowExStyle(window));
+ SetWindowPos(window->win32.handle, HWND_TOP,
+ 0, 0, rect.right - rect.left, rect.bottom - rect.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
+ }
+}
+
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+ RECT area;
+
+ if ((minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) &&
+ (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE))
+ {
+ return;
+ }
+
+ GetWindowRect(window->win32.handle, &area);
+ MoveWindow(window->win32.handle,
+ area.left, area.top,
+ area.right - area.left,
+ area.bottom - area.top, TRUE);
+}
+
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
+{
+ RECT area;
+
+ if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
+ return;
+
+ GetWindowRect(window->win32.handle, &area);
+ applyAspectRatio(window, WMSZ_BOTTOMRIGHT, &area);
+ MoveWindow(window->win32.handle,
+ area.left, area.top,
+ area.right - area.left,
+ area.bottom - area.top, TRUE);
+}
+
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
+{
+ _glfwPlatformGetWindowSize(window, width, height);
+}
+
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+ RECT rect;
+ int width, height;
+
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ SetRect(&rect, 0, 0, width, height);
+ AdjustWindowRectEx(&rect, getWindowStyle(window),
+ FALSE, getWindowExStyle(window));
+
+ if (left)
+ *left = -rect.left;
+ if (top)
+ *top = -rect.top;
+ if (right)
+ *right = rect.right - width;
+ if (bottom)
+ *bottom = rect.bottom - height;
+}
+
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+ float* xscale, float* yscale)
+{
+ const HANDLE handle = MonitorFromWindow(window->win32.handle,
+ MONITOR_DEFAULTTONEAREST);
+ _glfwGetMonitorContentScaleWin32(handle, xscale, yscale);
+}
+
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
+{
+ ShowWindow(window->win32.handle, SW_MINIMIZE);
+}
+
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
+{
+ ShowWindow(window->win32.handle, SW_RESTORE);
+}
+
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
+{
+ ShowWindow(window->win32.handle, SW_MAXIMIZE);
+}
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+ ShowWindow(window->win32.handle, SW_SHOW);
+}
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+ ShowWindow(window->win32.handle, SW_HIDE);
+}
+
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+{
+ FlashWindow(window->win32.handle, TRUE);
+}
+
+void _glfwPlatformFocusWindow(_GLFWwindow* window)
+{
+ BringWindowToTop(window->win32.handle);
+ SetForegroundWindow(window->win32.handle);
+ SetFocus(window->win32.handle);
+}
+
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+ _GLFWmonitor* monitor,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+ if (window->monitor == monitor)
+ {
+ if (monitor)
+ {
+ if (monitor->window == window)
+ acquireMonitor(window);
+ }
+ else
+ {
+ RECT rect = { xpos, ypos, xpos + width, ypos + height };
+ AdjustWindowRectEx(&rect, getWindowStyle(window),
+ FALSE, getWindowExStyle(window));
+ SetWindowPos(window->win32.handle, HWND_TOP,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER);
+ }
+
+ return;
+ }
+
+ if (window->monitor)
+ releaseMonitor(window);
+
+ _glfwInputWindowMonitor(window, monitor);
+
+ if (monitor)
+ {
+ GLFWvidmode mode;
+ DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
+ UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS;
+
+ if (window->decorated)
+ {
+ style &= ~WS_OVERLAPPEDWINDOW;
+ style |= getWindowStyle(window);
+ SetWindowLongW(window->win32.handle, GWL_STYLE, style);
+
+ flags |= SWP_FRAMECHANGED;
+ }
+
+ _glfwPlatformGetVideoMode(monitor, &mode);
+ _glfwPlatformGetMonitorPos(monitor, &xpos, &ypos);
+
+ SetWindowPos(window->win32.handle, HWND_TOPMOST,
+ xpos, ypos, mode.width, mode.height,
+ flags);
+
+ acquireMonitor(window);
+ }
+ else
+ {
+ HWND after;
+ RECT rect = { xpos, ypos, xpos + width, ypos + height };
+ DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
+ UINT flags = SWP_NOACTIVATE | SWP_NOCOPYBITS;
+
+ if (window->decorated)
+ {
+ style &= ~WS_POPUP;
+ style |= getWindowStyle(window);
+ SetWindowLongW(window->win32.handle, GWL_STYLE, style);
+
+ flags |= SWP_FRAMECHANGED;
+ }
+
+ if (window->floating)
+ after = HWND_TOPMOST;
+ else
+ after = HWND_NOTOPMOST;
+
+ AdjustWindowRectEx(&rect, getWindowStyle(window),
+ FALSE, getWindowExStyle(window));
+ SetWindowPos(window->win32.handle, after,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ flags);
+ }
+}
+
+int _glfwPlatformWindowFocused(_GLFWwindow* window)
+{
+ return window->win32.handle == GetActiveWindow();
+}
+
+int _glfwPlatformWindowIconified(_GLFWwindow* window)
+{
+ return IsIconic(window->win32.handle);
+}
+
+int _glfwPlatformWindowVisible(_GLFWwindow* window)
+{
+ return IsWindowVisible(window->win32.handle);
+}
+
+int _glfwPlatformWindowMaximized(_GLFWwindow* window)
+{
+ return IsZoomed(window->win32.handle);
+}
+
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
+{
+ return window->win32.transparent && _glfwIsCompositionEnabledWin32();
+}
+
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
+{
+ updateWindowStyles(window);
+}
+
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
+{
+ updateWindowStyles(window);
+}
+
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
+{
+ const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST;
+ SetWindowPos(window->win32.handle, after, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+}
+
+void _glfwPlatformPollEvents(void)
+{
+ MSG msg;
+ HWND handle;
+ _GLFWwindow* window;
+
+ while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_QUIT)
+ {
+ // NOTE: While GLFW does not itself post WM_QUIT, other processes
+ // may post it to this one, for example Task Manager
+ // HACK: Treat WM_QUIT as a close on all windows
+
+ window = _glfw.windowListHead;
+ while (window)
+ {
+ _glfwInputWindowCloseRequest(window);
+ window = window->next;
+ }
+ }
+ else
+ {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+
+ handle = GetActiveWindow();
+ if (handle)
+ {
+ // NOTE: Shift keys on Windows tend to "stick" when both are pressed as
+ // no key up message is generated by the first key release
+ // The other half of this is in the handling of WM_KEYUP
+ // HACK: Query actual key state and synthesize release events as needed
+ window = GetPropW(handle, L"GLFW");
+ if (window)
+ {
+ const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
+ const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
+
+ if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
+ {
+ const int mods = getAsyncKeyMods();
+ const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT];
+ _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
+ }
+ else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS)
+ {
+ const int mods = getAsyncKeyMods();
+ const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT];
+ _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
+ }
+ }
+ }
+
+ window = _glfw.win32.disabledCursorWindow;
+ if (window)
+ {
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+
+ // NOTE: Re-center the cursor only if it has moved since the last call,
+ // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
+ if (window->win32.lastCursorPosX != width / 2 ||
+ window->win32.lastCursorPosY != height / 2)
+ {
+ _glfwPlatformSetCursorPos(window, width / 2, height / 2);
+ }
+ }
+}
+
+void _glfwPlatformWaitEvents(void)
+{
+ WaitMessage();
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformWaitEventsTimeout(double timeout)
+{
+ MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS);
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformPostEmptyEvent(void)
+{
+ PostMessage(_glfw.win32.helperWindowHandle, WM_NULL, 0, 0);
+}
+
+void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
+{
+ POINT pos;
+
+ if (GetCursorPos(&pos))
+ {
+ ScreenToClient(window->win32.handle, &pos);
+
+ if (xpos)
+ *xpos = pos.x;
+ if (ypos)
+ *ypos = pos.y;
+ }
+}
+
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
+{
+ POINT pos = { (int) xpos, (int) ypos };
+
+ // Store the new position so it can be recognized later
+ window->win32.lastCursorPosX = pos.x;
+ window->win32.lastCursorPosY = pos.y;
+
+ ClientToScreen(window->win32.handle, &pos);
+ SetCursorPos(pos.x, pos.y);
+}
+
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
+{
+ if (mode == GLFW_CURSOR_DISABLED)
+ {
+ const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
+
+ _glfw.win32.disabledCursorWindow = window;
+ _glfwPlatformGetCursorPos(window,
+ &_glfw.win32.restoreCursorPosX,
+ &_glfw.win32.restoreCursorPosY);
+ centerCursor(window);
+ updateClipRect(window);
+
+ if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to register raw input device");
+ }
+ }
+ else if (_glfw.win32.disabledCursorWindow == window)
+ {
+ const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
+
+ _glfw.win32.disabledCursorWindow = NULL;
+ updateClipRect(NULL);
+ _glfwPlatformSetCursorPos(window,
+ _glfw.win32.restoreCursorPosX,
+ _glfw.win32.restoreCursorPosY);
+
+ if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to remove raw input device");
+ }
+ }
+
+ if (cursorInClientArea(window))
+ updateCursorImage(window);
+}
+
+const char* _glfwPlatformGetScancodeName(int scancode)
+{
+ return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
+}
+
+int _glfwPlatformGetKeyScancode(int key)
+{
+ return _glfw.win32.scancodes[key];
+}
+
+int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
+ const GLFWimage* image,
+ int xhot, int yhot)
+{
+ cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE);
+ if (!cursor->win32.handle)
+ return GLFW_FALSE;
+
+ return GLFW_TRUE;
+}
+
+int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
+{
+ cursor->win32.handle =
+ CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
+ if (!cursor->win32.handle)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create standard cursor");
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
+{
+ if (cursor->win32.handle)
+ DestroyIcon((HICON) cursor->win32.handle);
+}
+
+void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+{
+ if (cursorInClientArea(window))
+ updateCursorImage(window);
+}
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ int characterCount;
+ HANDLE object;
+ WCHAR* buffer;
+
+ characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
+ if (!characterCount)
+ return;
+
+ object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
+ if (!object)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to allocate global handle for clipboard");
+ return;
+ }
+
+ buffer = GlobalLock(object);
+ if (!buffer)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to lock global handle");
+ GlobalFree(object);
+ return;
+ }
+
+ MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount);
+ GlobalUnlock(object);
+
+ if (!OpenClipboard(_glfw.win32.helperWindowHandle))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to open clipboard");
+ GlobalFree(object);
+ return;
+ }
+
+ EmptyClipboard();
+ SetClipboardData(CF_UNICODETEXT, object);
+ CloseClipboard();
+}
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ HANDLE object;
+ WCHAR* buffer;
+
+ if (!OpenClipboard(_glfw.win32.helperWindowHandle))
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to open clipboard");
+ return NULL;
+ }
+
+ object = GetClipboardData(CF_UNICODETEXT);
+ if (!object)
+ {
+ _glfwInputErrorWin32(GLFW_FORMAT_UNAVAILABLE,
+ "Win32: Failed to convert clipboard to string");
+ CloseClipboard();
+ return NULL;
+ }
+
+ buffer = GlobalLock(object);
+ if (!buffer)
+ {
+ _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to lock global handle");
+ CloseClipboard();
+ return NULL;
+ }
+
+ free(_glfw.win32.clipboardString);
+ _glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer);
+
+ GlobalUnlock(object);
+ CloseClipboard();
+
+ return _glfw.win32.clipboardString;
+}
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
+{
+ if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
+ return;
+
+ extensions[0] = "VK_KHR_surface";
+ extensions[1] = "VK_KHR_win32_surface";
+}
+
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
+ vkGetPhysicalDeviceWin32PresentationSupportKHR =
+ (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+ if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Win32: Vulkan instance missing VK_KHR_win32_surface extension");
+ return GLFW_FALSE;
+ }
+
+ return vkGetPhysicalDeviceWin32PresentationSupportKHR(device, queuefamily);
+}
+
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
+ _GLFWwindow* window,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+ VkResult err;
+ VkWin32SurfaceCreateInfoKHR sci;
+ PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
+
+ vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
+ vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
+ if (!vkCreateWin32SurfaceKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Win32: Vulkan instance missing VK_KHR_win32_surface extension");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ memset(&sci, 0, sizeof(sci));
+ sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ sci.hinstance = GetModuleHandle(NULL);
+ sci.hwnd = window->win32.handle;
+
+ err = vkCreateWin32SurfaceKHR(instance, &sci, allocator, surface);
+ if (err)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Win32: Failed to create Vulkan surface: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ return err;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return window->win32.handle;
+}
+
diff --git a/src/external/glfw/src/window.c b/src/external/glfw/src/window.c
new file mode 100644
index 00000000..30321733
--- /dev/null
+++ b/src/external/glfw/src/window.c
@@ -0,0 +1,1021 @@
+//========================================================================
+// GLFW 3.3 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+// Copyright (c) 2012 Torsten Walluhn <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <float.h>
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW event API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
+{
+ if (window->callbacks.focus)
+ window->callbacks.focus((GLFWwindow*) window, focused);
+
+ if (!focused)
+ {
+ int key, button;
+
+ for (key = 0; key <= GLFW_KEY_LAST; key++)
+ {
+ if (window->keys[key] == GLFW_PRESS)
+ {
+ const int scancode = _glfwPlatformGetKeyScancode(key);
+ _glfwInputKey(window, key, scancode, GLFW_RELEASE, 0);
+ }
+ }
+
+ for (button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++)
+ {
+ if (window->mouseButtons[button] == GLFW_PRESS)
+ _glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
+ }
+ }
+}
+
+void _glfwInputWindowPos(_GLFWwindow* window, int x, int y)
+{
+ if (window->callbacks.pos)
+ window->callbacks.pos((GLFWwindow*) window, x, y);
+}
+
+void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
+{
+ if (window->callbacks.size)
+ window->callbacks.size((GLFWwindow*) window, width, height);
+}
+
+void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
+{
+ if (window->callbacks.iconify)
+ window->callbacks.iconify((GLFWwindow*) window, iconified);
+}
+
+void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
+{
+ if (window->callbacks.maximize)
+ window->callbacks.maximize((GLFWwindow*) window, maximized);
+}
+
+void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
+{
+ if (window->callbacks.fbsize)
+ window->callbacks.fbsize((GLFWwindow*) window, width, height);
+}
+
+void _glfwInputWindowDamage(_GLFWwindow* window)
+{
+ if (window->callbacks.refresh)
+ window->callbacks.refresh((GLFWwindow*) window);
+}
+
+void _glfwInputWindowCloseRequest(_GLFWwindow* window)
+{
+ window->shouldClose = GLFW_TRUE;
+
+ if (window->callbacks.close)
+ window->callbacks.close((GLFWwindow*) window);
+}
+
+void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
+{
+ window->monitor = monitor;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW public API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
+ const char* title,
+ GLFWmonitor* monitor,
+ GLFWwindow* share)
+{
+ _GLFWfbconfig fbconfig;
+ _GLFWctxconfig ctxconfig;
+ _GLFWwndconfig wndconfig;
+ _GLFWwindow* window;
+ _GLFWwindow* previous;
+
+ assert(title != NULL);
+ assert(width >= 0);
+ assert(height >= 0);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+
+ if (width <= 0 || height <= 0)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid window size %ix%i",
+ width, height);
+
+ return NULL;
+ }
+
+ fbconfig = _glfw.hints.framebuffer;
+ ctxconfig = _glfw.hints.context;
+ wndconfig = _glfw.hints.window;
+
+ wndconfig.width = width;
+ wndconfig.height = height;
+ wndconfig.title = title;
+ ctxconfig.share = (_GLFWwindow*) share;
+
+ if (ctxconfig.share)
+ {
+ if (ctxconfig.client == GLFW_NO_API ||
+ ctxconfig.share->context.client == GLFW_NO_API)
+ {
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
+ return NULL;
+ }
+ }
+
+ if (!_glfwIsValidContextConfig(&ctxconfig))
+ return NULL;
+
+ window = calloc(1, sizeof(_GLFWwindow));
+ window->next = _glfw.windowListHead;
+ _glfw.windowListHead = window;
+
+ window->videoMode.width = width;
+ window->videoMode.height = height;
+ window->videoMode.redBits = fbconfig.redBits;
+ window->videoMode.greenBits = fbconfig.greenBits;
+ window->videoMode.blueBits = fbconfig.blueBits;
+ window->videoMode.refreshRate = _glfw.hints.refreshRate;
+
+ window->monitor = (_GLFWmonitor*) monitor;
+ window->resizable = wndconfig.resizable;
+ window->decorated = wndconfig.decorated;
+ window->autoIconify = wndconfig.autoIconify;
+ window->floating = wndconfig.floating;
+ window->cursorMode = GLFW_CURSOR_NORMAL;
+
+ window->minwidth = GLFW_DONT_CARE;
+ window->minheight = GLFW_DONT_CARE;
+ window->maxwidth = GLFW_DONT_CARE;
+ window->maxheight = GLFW_DONT_CARE;
+ window->numer = GLFW_DONT_CARE;
+ window->denom = GLFW_DONT_CARE;
+
+ // Save the currently current context so it can be restored later
+ previous = _glfwPlatformGetTls(&_glfw.contextSlot);
+ if (ctxconfig.client != GLFW_NO_API)
+ glfwMakeContextCurrent(NULL);
+
+ // Open the actual window and create its context
+ if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
+ {
+ glfwMakeContextCurrent((GLFWwindow*) previous);
+ glfwDestroyWindow((GLFWwindow*) window);
+ return NULL;
+ }
+
+ if (ctxconfig.client != GLFW_NO_API)
+ {
+ window->context.makeCurrent(window);
+
+ // Retrieve the actual (as opposed to requested) context attributes
+ if (!_glfwRefreshContextAttribs(&ctxconfig))
+ {
+ glfwMakeContextCurrent((GLFWwindow*) previous);
+ glfwDestroyWindow((GLFWwindow*) window);
+ return NULL;
+ }
+
+ // Restore the previously current context (or NULL)
+ glfwMakeContextCurrent((GLFWwindow*) previous);
+ }
+
+ if (!window->monitor)
+ {
+ if (wndconfig.visible)
+ {
+ _glfwPlatformShowWindow(window);
+ if (wndconfig.focused)
+ _glfwPlatformFocusWindow(window);
+ }
+ }
+
+ return (GLFWwindow*) window;
+}
+
+void glfwDefaultWindowHints(void)
+{
+ _GLFW_REQUIRE_INIT();
+
+ // The default is OpenGL with minimum version 1.0
+ memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context));
+ _glfw.hints.context.client = GLFW_OPENGL_API;
+ _glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
+ _glfw.hints.context.major = 1;
+ _glfw.hints.context.minor = 0;
+
+ // The default is a focused, visible, resizable window with decorations
+ memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
+ _glfw.hints.window.resizable = GLFW_TRUE;
+ _glfw.hints.window.visible = GLFW_TRUE;
+ _glfw.hints.window.decorated = GLFW_TRUE;
+ _glfw.hints.window.focused = GLFW_TRUE;
+ _glfw.hints.window.autoIconify = GLFW_TRUE;
+ _glfw.hints.window.centerCursor = GLFW_TRUE;
+
+ // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
+ // double buffered
+ memset(&_glfw.hints.framebuffer, 0, sizeof(_glfw.hints.framebuffer));
+ _glfw.hints.framebuffer.redBits = 8;
+ _glfw.hints.framebuffer.greenBits = 8;
+ _glfw.hints.framebuffer.blueBits = 8;
+ _glfw.hints.framebuffer.alphaBits = 8;
+ _glfw.hints.framebuffer.depthBits = 24;
+ _glfw.hints.framebuffer.stencilBits = 8;
+ _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
+
+ // The default is to select the highest available refresh rate
+ _glfw.hints.refreshRate = GLFW_DONT_CARE;
+
+ // The default is to use full Retina resolution framebuffers
+ _glfw.hints.window.ns.retina = GLFW_TRUE;
+}
+
+GLFWAPI void glfwWindowHint(int hint, int value)
+{
+ _GLFW_REQUIRE_INIT();
+
+ switch (hint)
+ {
+ case GLFW_RED_BITS:
+ _glfw.hints.framebuffer.redBits = value;
+ return;
+ case GLFW_GREEN_BITS:
+ _glfw.hints.framebuffer.greenBits = value;
+ return;
+ case GLFW_BLUE_BITS:
+ _glfw.hints.framebuffer.blueBits = value;
+ return;
+ case GLFW_ALPHA_BITS:
+ _glfw.hints.framebuffer.alphaBits = value;
+ return;
+ case GLFW_DEPTH_BITS:
+ _glfw.hints.framebuffer.depthBits = value;
+ return;
+ case GLFW_STENCIL_BITS:
+ _glfw.hints.framebuffer.stencilBits = value;
+ return;
+ case GLFW_ACCUM_RED_BITS:
+ _glfw.hints.framebuffer.accumRedBits = value;
+ return;
+ case GLFW_ACCUM_GREEN_BITS:
+ _glfw.hints.framebuffer.accumGreenBits = value;
+ return;
+ case GLFW_ACCUM_BLUE_BITS:
+ _glfw.hints.framebuffer.accumBlueBits = value;
+ return;
+ case GLFW_ACCUM_ALPHA_BITS:
+ _glfw.hints.framebuffer.accumAlphaBits = value;
+ return;
+ case GLFW_AUX_BUFFERS:
+ _glfw.hints.framebuffer.auxBuffers = value;
+ return;
+ case GLFW_STEREO:
+ _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_DOUBLEBUFFER:
+ _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_TRANSPARENT:
+ _glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_SAMPLES:
+ _glfw.hints.framebuffer.samples = value;
+ return;
+ case GLFW_SRGB_CAPABLE:
+ _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_RESIZABLE:
+ _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_DECORATED:
+ _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_FOCUSED:
+ _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_AUTO_ICONIFY:
+ _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_FLOATING:
+ _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_MAXIMIZED:
+ _glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_VISIBLE:
+ _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_COCOA_RETINA_FRAMEBUFFER:
+ _glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_COCOA_FRAME_AUTOSAVE:
+ _glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_COCOA_GRAPHICS_SWITCHING:
+ _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_CENTER_CURSOR:
+ _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_CLIENT_API:
+ _glfw.hints.context.client = value;
+ return;
+ case GLFW_CONTEXT_CREATION_API:
+ _glfw.hints.context.source = value;
+ return;
+ case GLFW_CONTEXT_VERSION_MAJOR:
+ _glfw.hints.context.major = value;
+ return;
+ case GLFW_CONTEXT_VERSION_MINOR:
+ _glfw.hints.context.minor = value;
+ return;
+ case GLFW_CONTEXT_ROBUSTNESS:
+ _glfw.hints.context.robustness = value;
+ return;
+ case GLFW_OPENGL_FORWARD_COMPAT:
+ _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_OPENGL_DEBUG_CONTEXT:
+ _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_CONTEXT_NO_ERROR:
+ _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
+ return;
+ case GLFW_OPENGL_PROFILE:
+ _glfw.hints.context.profile = value;
+ return;
+ case GLFW_CONTEXT_RELEASE_BEHAVIOR:
+ _glfw.hints.context.release = value;
+ return;
+ case GLFW_REFRESH_RATE:
+ _glfw.hints.refreshRate = value;
+ return;
+ }
+
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
+}
+
+GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+
+ _GLFW_REQUIRE_INIT();
+
+ // Allow closing of NULL (to match the behavior of free)
+ if (window == NULL)
+ return;
+
+ // Clear all callbacks to avoid exposing a half torn-down window object
+ memset(&window->callbacks, 0, sizeof(window->callbacks));
+
+ // The window's context must not be current on another thread when the
+ // window is destroyed
+ if (window == _glfwPlatformGetTls(&_glfw.contextSlot))
+ glfwMakeContextCurrent(NULL);
+
+ _glfwPlatformDestroyWindow(window);
+
+ // Unlink window from global linked list
+ {
+ _GLFWwindow** prev = &_glfw.windowListHead;
+
+ while (*prev != window)
+ prev = &((*prev)->next);
+
+ *prev = window->next;
+ }
+
+ free(window);
+}
+
+GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(0);
+ return window->shouldClose;
+}
+
+GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ window->shouldClose = value;
+}
+
+GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+ assert(title != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformSetWindowTitle(window, title);
+}
+
+GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
+ int count, const GLFWimage* images)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+ assert(count >= 0);
+ assert(count == 0 || images != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformSetWindowIcon(window, count, images);
+}
+
+GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ if (xpos)
+ *xpos = 0;
+ if (ypos)
+ *ypos = 0;
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformGetWindowPos(window, xpos, ypos);
+}
+
+GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window->monitor)
+ return;
+
+ _glfwPlatformSetWindowPos(window, xpos, ypos);
+}
+
+GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ if (width)
+ *width = 0;
+ if (height)
+ *height = 0;
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformGetWindowSize(window, width, height);
+}
+
+GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+ assert(width >= 0);
+ assert(height >= 0);
+
+ _GLFW_REQUIRE_INIT();
+
+ window->videoMode.width = width;
+ window->videoMode.height = height;
+
+ _glfwPlatformSetWindowSize(window, width, height);
+}
+
+GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE)
+ {
+ if (minwidth < 0 || minheight < 0)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid window minimum size %ix%i",
+ minwidth, minheight);
+ return;
+ }
+ }
+
+ if (maxwidth != GLFW_DONT_CARE && maxheight != GLFW_DONT_CARE)
+ {
+ if (maxwidth < 0 || maxheight < 0 ||
+ maxwidth < minwidth || maxheight < minheight)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid window maximum size %ix%i",
+ maxwidth, maxheight);
+ return;
+ }
+ }
+
+ window->minwidth = minwidth;
+ window->minheight = minheight;
+ window->maxwidth = maxwidth;
+ window->maxheight = maxheight;
+
+ if (window->monitor || !window->resizable)
+ return;
+
+ _glfwPlatformSetWindowSizeLimits(window,
+ minwidth, minheight,
+ maxwidth, maxheight);
+}
+
+GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+ assert(numer != 0);
+ assert(denom != 0);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)
+ {
+ if (numer <= 0 || denom <= 0)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid window aspect ratio %i:%i",
+ numer, denom);
+ return;
+ }
+ }
+
+ window->numer = numer;
+ window->denom = denom;
+
+ if (window->monitor || !window->resizable)
+ return;
+
+ _glfwPlatformSetWindowAspectRatio(window, numer, denom);
+}
+
+GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ if (width)
+ *width = 0;
+ if (height)
+ *height = 0;
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformGetFramebufferSize(window, width, height);
+}
+
+GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ if (left)
+ *left = 0;
+ if (top)
+ *top = 0;
+ if (right)
+ *right = 0;
+ if (bottom)
+ *bottom = 0;
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom);
+}
+
+GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
+ float* xscale, float* yscale)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ if (xscale)
+ *xscale = 0.f;
+ if (yscale)
+ *yscale = 0.f;
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformGetWindowContentScale(window, xscale, yscale);
+}
+
+GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformIconifyWindow(window);
+}
+
+GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformRestoreWindow(window);
+}
+
+GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window->monitor)
+ return;
+
+ _glfwPlatformMaximizeWindow(window);
+}
+
+GLFWAPI void glfwShowWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window->monitor)
+ return;
+
+ _glfwPlatformShowWindow(window);
+ _glfwPlatformFocusWindow(window);
+}
+
+GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ _glfwPlatformRequestWindowAttention(window);
+}
+
+GLFWAPI void glfwHideWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (window->monitor)
+ return;
+
+ _glfwPlatformHideWindow(window);
+}
+
+GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ _glfwPlatformFocusWindow(window);
+}
+
+GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(0);
+
+ switch (attrib)
+ {
+ case GLFW_FOCUSED:
+ return _glfwPlatformWindowFocused(window);
+ case GLFW_ICONIFIED:
+ return _glfwPlatformWindowIconified(window);
+ case GLFW_VISIBLE:
+ return _glfwPlatformWindowVisible(window);
+ case GLFW_MAXIMIZED:
+ return _glfwPlatformWindowMaximized(window);
+ case GLFW_TRANSPARENT:
+ return _glfwPlatformFramebufferTransparent(window);
+ case GLFW_RESIZABLE:
+ return window->resizable;
+ case GLFW_DECORATED:
+ return window->decorated;
+ case GLFW_FLOATING:
+ return window->floating;
+ case GLFW_AUTO_ICONIFY:
+ return window->autoIconify;
+ case GLFW_CLIENT_API:
+ return window->context.client;
+ case GLFW_CONTEXT_CREATION_API:
+ return window->context.source;
+ case GLFW_CONTEXT_VERSION_MAJOR:
+ return window->context.major;
+ case GLFW_CONTEXT_VERSION_MINOR:
+ return window->context.minor;
+ case GLFW_CONTEXT_REVISION:
+ return window->context.revision;
+ case GLFW_CONTEXT_ROBUSTNESS:
+ return window->context.robustness;
+ case GLFW_OPENGL_FORWARD_COMPAT:
+ return window->context.forward;
+ case GLFW_OPENGL_DEBUG_CONTEXT:
+ return window->context.debug;
+ case GLFW_OPENGL_PROFILE:
+ return window->context.profile;
+ case GLFW_CONTEXT_RELEASE_BEHAVIOR:
+ return window->context.release;
+ case GLFW_CONTEXT_NO_ERROR:
+ return window->context.noerror;
+ }
+
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
+ return 0;
+}
+
+GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+
+ value = value ? GLFW_TRUE : GLFW_FALSE;
+
+ if (attrib == GLFW_AUTO_ICONIFY)
+ window->autoIconify = value;
+ else if (attrib == GLFW_RESIZABLE)
+ {
+ if (window->resizable == value)
+ return;
+
+ window->resizable = value;
+ if (!window->monitor)
+ _glfwPlatformSetWindowResizable(window, value);
+ }
+ else if (attrib == GLFW_DECORATED)
+ {
+ if (window->decorated == value)
+ return;
+
+ window->decorated = value;
+ if (!window->monitor)
+ _glfwPlatformSetWindowDecorated(window, value);
+ }
+ else if (attrib == GLFW_FLOATING)
+ {
+ if (window->floating == value)
+ return;
+
+ window->floating = value;
+ if (!window->monitor)
+ _glfwPlatformSetWindowFloating(window, value);
+ }
+ else
+ _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
+}
+
+GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return (GLFWmonitor*) window->monitor;
+}
+
+GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
+ GLFWmonitor* mh,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+ _GLFWwindow* window = (_GLFWwindow*) wh;
+ _GLFWmonitor* monitor = (_GLFWmonitor*) mh;
+ assert(window != NULL);
+ assert(width >= 0);
+ assert(height >= 0);
+
+ _GLFW_REQUIRE_INIT();
+
+ if (width <= 0 || height <= 0)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid window size %ix%i",
+ width, height);
+ return;
+ }
+
+ if (refreshRate < 0 && refreshRate != GLFW_DONT_CARE)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE,
+ "Invalid refresh rate %i",
+ refreshRate);
+ return;
+ }
+
+ window->videoMode.width = width;
+ window->videoMode.height = height;
+ window->videoMode.refreshRate = refreshRate;
+
+ _glfwPlatformSetWindowMonitor(window, monitor,
+ xpos, ypos, width, height,
+ refreshRate);
+}
+
+GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT();
+ window->userPointer = pointer;
+}
+
+GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return window->userPointer;
+}
+
+GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
+ GLFWwindowposfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
+ GLFWwindowsizefun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
+ GLFWwindowclosefun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
+ GLFWwindowrefreshfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
+ GLFWwindowfocusfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
+ GLFWwindowiconifyfun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
+ GLFWwindowmaximizefun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun);
+ return cbfun;
+}
+
+GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle,
+ GLFWframebuffersizefun cbfun)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ assert(window != NULL);
+
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun);
+ return cbfun;
+}
+
+GLFWAPI void glfwPollEvents(void)
+{
+ _GLFW_REQUIRE_INIT();
+ _glfwPlatformPollEvents();
+}
+
+GLFWAPI void glfwWaitEvents(void)
+{
+ _GLFW_REQUIRE_INIT();
+
+ if (!_glfw.windowListHead)
+ return;
+
+ _glfwPlatformWaitEvents();
+}
+
+GLFWAPI void glfwWaitEventsTimeout(double timeout)
+{
+ _GLFW_REQUIRE_INIT();
+ assert(timeout == timeout);
+ assert(timeout >= 0.0);
+ assert(timeout <= DBL_MAX);
+
+ if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
+ {
+ _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
+ return;
+ }
+
+ _glfwPlatformWaitEventsTimeout(timeout);
+}
+
+GLFWAPI void glfwPostEmptyEvent(void)
+{
+ _GLFW_REQUIRE_INIT();
+
+ if (!_glfw.windowListHead)
+ return;
+
+ _glfwPlatformPostEmptyEvent();
+}
+
diff --git a/src/external/glfw/src/wl_init.c b/src/external/glfw/src/wl_init.c
new file mode 100644
index 00000000..3841636f
--- /dev/null
+++ b/src/external/glfw/src/wl_init.c
@@ -0,0 +1,792 @@
+//========================================================================
+// GLFW 3.3 Wayland - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014 Jonas Ã…dahl <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <wayland-client.h>
+#include <wayland-cursor.h>
+
+
+static inline int min(int n1, int n2)
+{
+ return n1 < n2 ? n1 : n2;
+}
+
+static void pointerHandleEnter(void* data,
+ struct wl_pointer* pointer,
+ uint32_t serial,
+ struct wl_surface* surface,
+ wl_fixed_t sx,
+ wl_fixed_t sy)
+{
+ _GLFWwindow* window = wl_surface_get_user_data(surface);
+
+ _glfw.wl.pointerSerial = serial;
+ _glfw.wl.pointerFocus = window;
+
+ _glfwPlatformSetCursor(window, window->wl.currentCursor);
+ _glfwInputCursorEnter(window, GLFW_TRUE);
+}
+
+static void pointerHandleLeave(void* data,
+ struct wl_pointer* pointer,
+ uint32_t serial,
+ struct wl_surface* surface)
+{
+ _GLFWwindow* window = _glfw.wl.pointerFocus;
+
+ if (!window)
+ return;
+
+ _glfw.wl.pointerSerial = serial;
+ _glfw.wl.pointerFocus = NULL;
+ _glfwInputCursorEnter(window, GLFW_FALSE);
+}
+
+static void pointerHandleMotion(void* data,
+ struct wl_pointer* pointer,
+ uint32_t time,
+ wl_fixed_t sx,
+ wl_fixed_t sy)
+{
+ _GLFWwindow* window = _glfw.wl.pointerFocus;
+
+ if (!window)
+ return;
+
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ return;
+ else
+ {
+ window->wl.cursorPosX = wl_fixed_to_double(sx);
+ window->wl.cursorPosY = wl_fixed_to_double(sy);
+ }
+
+ _glfwInputCursorPos(window,
+ wl_fixed_to_double(sx),
+ wl_fixed_to_double(sy));
+}
+
+static void pointerHandleButton(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t button,
+ uint32_t state)
+{
+ _GLFWwindow* window = _glfw.wl.pointerFocus;
+ int glfwButton;
+
+ if (!window)
+ return;
+
+ _glfw.wl.pointerSerial = serial;
+
+ /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
+ * codes. */
+ glfwButton = button - BTN_LEFT;
+
+ _glfwInputMouseClick(window,
+ glfwButton,
+ state == WL_POINTER_BUTTON_STATE_PRESSED
+ ? GLFW_PRESS
+ : GLFW_RELEASE,
+ _glfw.wl.xkb.modifiers);
+}
+
+static void pointerHandleAxis(void* data,
+ struct wl_pointer* wl_pointer,
+ uint32_t time,
+ uint32_t axis,
+ wl_fixed_t value)
+{
+ _GLFWwindow* window = _glfw.wl.pointerFocus;
+ double scrollFactor;
+ double x, y;
+
+ if (!window)
+ return;
+
+ /* Wayland scroll events are in pointer motion coordinate space (think
+ * two finger scroll). The factor 10 is commonly used to convert to
+ * "scroll step means 1.0. */
+ scrollFactor = 1.0/10.0;
+
+ switch (axis)
+ {
+ case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
+ x = wl_fixed_to_double(value) * scrollFactor;
+ y = 0.0;
+ break;
+ case WL_POINTER_AXIS_VERTICAL_SCROLL:
+ x = 0.0;
+ y = wl_fixed_to_double(value) * scrollFactor;
+ break;
+ default:
+ break;
+ }
+
+ _glfwInputScroll(window, x, y);
+}
+
+static const struct wl_pointer_listener pointerListener = {
+ pointerHandleEnter,
+ pointerHandleLeave,
+ pointerHandleMotion,
+ pointerHandleButton,
+ pointerHandleAxis,
+};
+
+static void keyboardHandleKeymap(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t format,
+ int fd,
+ uint32_t size)
+{
+ struct xkb_keymap* keymap;
+ struct xkb_state* state;
+ struct xkb_compose_table* composeTable;
+ struct xkb_compose_state* composeState;
+ char* mapStr;
+ const char* locale;
+
+ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
+ {
+ close(fd);
+ return;
+ }
+
+ mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+ if (mapStr == MAP_FAILED) {
+ close(fd);
+ return;
+ }
+
+ keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,
+ mapStr,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ 0);
+ munmap(mapStr, size);
+ close(fd);
+
+ if (!keymap)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to compile keymap");
+ return;
+ }
+
+ state = xkb_state_new(keymap);
+ if (!state)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to create XKB state");
+ xkb_keymap_unref(keymap);
+ return;
+ }
+
+ // Look up the preferred locale, falling back to "C" as default.
+ locale = getenv("LC_ALL");
+ if (!locale)
+ locale = getenv("LC_CTYPE");
+ if (!locale)
+ locale = getenv("LANG");
+ if (!locale)
+ locale = "C";
+
+ composeTable =
+ xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
+ XKB_COMPOSE_COMPILE_NO_FLAGS);
+ if (composeTable)
+ {
+ composeState =
+ xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
+ xkb_compose_table_unref(composeTable);
+ if (composeState)
+ _glfw.wl.xkb.composeState = composeState;
+ else
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to create XKB compose state");
+ }
+ else
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to create XKB compose table");
+ }
+
+ xkb_keymap_unref(_glfw.wl.xkb.keymap);
+ xkb_state_unref(_glfw.wl.xkb.state);
+ _glfw.wl.xkb.keymap = keymap;
+ _glfw.wl.xkb.state = state;
+
+ _glfw.wl.xkb.controlMask =
+ 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control");
+ _glfw.wl.xkb.altMask =
+ 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1");
+ _glfw.wl.xkb.shiftMask =
+ 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift");
+ _glfw.wl.xkb.superMask =
+ 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");
+}
+
+static void keyboardHandleEnter(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface,
+ struct wl_array* keys)
+{
+ _GLFWwindow* window = wl_surface_get_user_data(surface);
+
+ _glfw.wl.keyboardFocus = window;
+ _glfwInputWindowFocus(window, GLFW_TRUE);
+}
+
+static void keyboardHandleLeave(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface)
+{
+ _GLFWwindow* window = _glfw.wl.keyboardFocus;
+
+ if (!window)
+ return;
+
+ _glfw.wl.keyboardFocus = NULL;
+ _glfwInputWindowFocus(window, GLFW_FALSE);
+}
+
+static int toGLFWKeyCode(uint32_t key)
+{
+ if (key < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
+ return _glfw.wl.keycodes[key];
+
+ return GLFW_KEY_UNKNOWN;
+}
+
+static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
+{
+ if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
+ return sym;
+ if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
+ != XKB_COMPOSE_FEED_ACCEPTED)
+ return sym;
+ switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))
+ {
+ case XKB_COMPOSE_COMPOSED:
+ return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);
+ case XKB_COMPOSE_COMPOSING:
+ case XKB_COMPOSE_CANCELLED:
+ return XKB_KEY_NoSymbol;
+ case XKB_COMPOSE_NOTHING:
+ default:
+ return sym;
+ }
+}
+
+static void inputChar(_GLFWwindow* window, uint32_t key)
+{
+ uint32_t code, numSyms;
+ long cp;
+ const xkb_keysym_t *syms;
+ xkb_keysym_t sym;
+
+ code = key + 8;
+ numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms);
+
+ if (numSyms == 1)
+ {
+ sym = composeSymbol(syms[0]);
+ cp = _glfwKeySym2Unicode(sym);
+ if (cp != -1)
+ {
+ const int mods = _glfw.wl.xkb.modifiers;
+ const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
+ _glfwInputChar(window, cp, mods, plain);
+ }
+ }
+}
+
+static void keyboardHandleKey(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t key,
+ uint32_t state)
+{
+ int keyCode;
+ int action;
+ _GLFWwindow* window = _glfw.wl.keyboardFocus;
+
+ if (!window)
+ return;
+
+ keyCode = toGLFWKeyCode(key);
+ action = state == WL_KEYBOARD_KEY_STATE_PRESSED
+ ? GLFW_PRESS : GLFW_RELEASE;
+
+ _glfwInputKey(window, keyCode, key, action,
+ _glfw.wl.xkb.modifiers);
+
+ if (action == GLFW_PRESS)
+ inputChar(window, key);
+}
+
+static void keyboardHandleModifiers(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t modsDepressed,
+ uint32_t modsLatched,
+ uint32_t modsLocked,
+ uint32_t group)
+{
+ xkb_mod_mask_t mask;
+ unsigned int modifiers = 0;
+
+ if (!_glfw.wl.xkb.keymap)
+ return;
+
+ xkb_state_update_mask(_glfw.wl.xkb.state,
+ modsDepressed,
+ modsLatched,
+ modsLocked,
+ 0,
+ 0,
+ group);
+
+ mask = xkb_state_serialize_mods(_glfw.wl.xkb.state,
+ XKB_STATE_MODS_DEPRESSED |
+ XKB_STATE_LAYOUT_DEPRESSED |
+ XKB_STATE_MODS_LATCHED |
+ XKB_STATE_LAYOUT_LATCHED);
+ if (mask & _glfw.wl.xkb.controlMask)
+ modifiers |= GLFW_MOD_CONTROL;
+ if (mask & _glfw.wl.xkb.altMask)
+ modifiers |= GLFW_MOD_ALT;
+ if (mask & _glfw.wl.xkb.shiftMask)
+ modifiers |= GLFW_MOD_SHIFT;
+ if (mask & _glfw.wl.xkb.superMask)
+ modifiers |= GLFW_MOD_SUPER;
+ _glfw.wl.xkb.modifiers = modifiers;
+}
+
+static const struct wl_keyboard_listener keyboardListener = {
+ keyboardHandleKeymap,
+ keyboardHandleEnter,
+ keyboardHandleLeave,
+ keyboardHandleKey,
+ keyboardHandleModifiers,
+};
+
+static void seatHandleCapabilities(void* data,
+ struct wl_seat* seat,
+ enum wl_seat_capability caps)
+{
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)
+ {
+ _glfw.wl.pointer = wl_seat_get_pointer(seat);
+ wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);
+ }
+ else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
+ {
+ wl_pointer_destroy(_glfw.wl.pointer);
+ _glfw.wl.pointer = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)
+ {
+ _glfw.wl.keyboard = wl_seat_get_keyboard(seat);
+ wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
+ }
+ else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
+ {
+ wl_keyboard_destroy(_glfw.wl.keyboard);
+ _glfw.wl.keyboard = NULL;
+ }
+}
+
+static const struct wl_seat_listener seatListener = {
+ seatHandleCapabilities
+};
+
+static void registryHandleGlobal(void* data,
+ struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version)
+{
+ if (strcmp(interface, "wl_compositor") == 0)
+ {
+ _glfw.wl.compositorVersion = min(3, version);
+ _glfw.wl.compositor =
+ wl_registry_bind(registry, name, &wl_compositor_interface,
+ _glfw.wl.compositorVersion);
+ }
+ else if (strcmp(interface, "wl_shm") == 0)
+ {
+ _glfw.wl.shm =
+ wl_registry_bind(registry, name, &wl_shm_interface, 1);
+ }
+ else if (strcmp(interface, "wl_shell") == 0)
+ {
+ _glfw.wl.shell =
+ wl_registry_bind(registry, name, &wl_shell_interface, 1);
+ }
+ else if (strcmp(interface, "wl_output") == 0)
+ {
+ _glfwAddOutputWayland(name, version);
+ }
+ else if (strcmp(interface, "wl_seat") == 0)
+ {
+ if (!_glfw.wl.seat)
+ {
+ _glfw.wl.seat =
+ wl_registry_bind(registry, name, &wl_seat_interface, 1);
+ wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
+ }
+ }
+ else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
+ {
+ _glfw.wl.relativePointerManager =
+ wl_registry_bind(registry, name,
+ &zwp_relative_pointer_manager_v1_interface,
+ 1);
+ }
+ else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0)
+ {
+ _glfw.wl.pointerConstraints =
+ wl_registry_bind(registry, name,
+ &zwp_pointer_constraints_v1_interface,
+ 1);
+ }
+}
+
+static void registryHandleGlobalRemove(void *data,
+ struct wl_registry *registry,
+ uint32_t name)
+{
+}
+
+
+static const struct wl_registry_listener registryListener = {
+ registryHandleGlobal,
+ registryHandleGlobalRemove
+};
+
+// Create key code translation tables
+//
+static void createKeyTables(void)
+{
+ int scancode;
+
+ memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes));
+ memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));
+
+ _glfw.wl.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT;
+ _glfw.wl.keycodes[KEY_1] = GLFW_KEY_1;
+ _glfw.wl.keycodes[KEY_2] = GLFW_KEY_2;
+ _glfw.wl.keycodes[KEY_3] = GLFW_KEY_3;
+ _glfw.wl.keycodes[KEY_4] = GLFW_KEY_4;
+ _glfw.wl.keycodes[KEY_5] = GLFW_KEY_5;
+ _glfw.wl.keycodes[KEY_6] = GLFW_KEY_6;
+ _glfw.wl.keycodes[KEY_7] = GLFW_KEY_7;
+ _glfw.wl.keycodes[KEY_8] = GLFW_KEY_8;
+ _glfw.wl.keycodes[KEY_9] = GLFW_KEY_9;
+ _glfw.wl.keycodes[KEY_0] = GLFW_KEY_0;
+ _glfw.wl.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
+ _glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
+ _glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
+ _glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q;
+ _glfw.wl.keycodes[KEY_W] = GLFW_KEY_W;
+ _glfw.wl.keycodes[KEY_E] = GLFW_KEY_E;
+ _glfw.wl.keycodes[KEY_R] = GLFW_KEY_R;
+ _glfw.wl.keycodes[KEY_T] = GLFW_KEY_T;
+ _glfw.wl.keycodes[KEY_Y] = GLFW_KEY_Y;
+ _glfw.wl.keycodes[KEY_U] = GLFW_KEY_U;
+ _glfw.wl.keycodes[KEY_I] = GLFW_KEY_I;
+ _glfw.wl.keycodes[KEY_O] = GLFW_KEY_O;
+ _glfw.wl.keycodes[KEY_P] = GLFW_KEY_P;
+ _glfw.wl.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET;
+ _glfw.wl.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
+ _glfw.wl.keycodes[KEY_A] = GLFW_KEY_A;
+ _glfw.wl.keycodes[KEY_S] = GLFW_KEY_S;
+ _glfw.wl.keycodes[KEY_D] = GLFW_KEY_D;
+ _glfw.wl.keycodes[KEY_F] = GLFW_KEY_F;
+ _glfw.wl.keycodes[KEY_G] = GLFW_KEY_G;
+ _glfw.wl.keycodes[KEY_H] = GLFW_KEY_H;
+ _glfw.wl.keycodes[KEY_J] = GLFW_KEY_J;
+ _glfw.wl.keycodes[KEY_K] = GLFW_KEY_K;
+ _glfw.wl.keycodes[KEY_L] = GLFW_KEY_L;
+ _glfw.wl.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON;
+ _glfw.wl.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
+ _glfw.wl.keycodes[KEY_Z] = GLFW_KEY_Z;
+ _glfw.wl.keycodes[KEY_X] = GLFW_KEY_X;
+ _glfw.wl.keycodes[KEY_C] = GLFW_KEY_C;
+ _glfw.wl.keycodes[KEY_V] = GLFW_KEY_V;
+ _glfw.wl.keycodes[KEY_B] = GLFW_KEY_B;
+ _glfw.wl.keycodes[KEY_N] = GLFW_KEY_N;
+ _glfw.wl.keycodes[KEY_M] = GLFW_KEY_M;
+ _glfw.wl.keycodes[KEY_COMMA] = GLFW_KEY_COMMA;
+ _glfw.wl.keycodes[KEY_DOT] = GLFW_KEY_PERIOD;
+ _glfw.wl.keycodes[KEY_SLASH] = GLFW_KEY_SLASH;
+ _glfw.wl.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH;
+ _glfw.wl.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE;
+ _glfw.wl.keycodes[KEY_TAB] = GLFW_KEY_TAB;
+ _glfw.wl.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT;
+ _glfw.wl.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
+ _glfw.wl.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL;
+ _glfw.wl.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL;
+ _glfw.wl.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT;
+ _glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
+ _glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
+ _glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
+ _glfw.wl.keycodes[KEY_MENU] = GLFW_KEY_MENU;
+ _glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
+ _glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
+ _glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
+ _glfw.wl.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
+ _glfw.wl.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE;
+ _glfw.wl.keycodes[KEY_DELETE] = GLFW_KEY_DELETE;
+ _glfw.wl.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE;
+ _glfw.wl.keycodes[KEY_ENTER] = GLFW_KEY_ENTER;
+ _glfw.wl.keycodes[KEY_HOME] = GLFW_KEY_HOME;
+ _glfw.wl.keycodes[KEY_END] = GLFW_KEY_END;
+ _glfw.wl.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP;
+ _glfw.wl.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN;
+ _glfw.wl.keycodes[KEY_INSERT] = GLFW_KEY_INSERT;
+ _glfw.wl.keycodes[KEY_LEFT] = GLFW_KEY_LEFT;
+ _glfw.wl.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT;
+ _glfw.wl.keycodes[KEY_DOWN] = GLFW_KEY_DOWN;
+ _glfw.wl.keycodes[KEY_UP] = GLFW_KEY_UP;
+ _glfw.wl.keycodes[KEY_F1] = GLFW_KEY_F1;
+ _glfw.wl.keycodes[KEY_F2] = GLFW_KEY_F2;
+ _glfw.wl.keycodes[KEY_F3] = GLFW_KEY_F3;
+ _glfw.wl.keycodes[KEY_F4] = GLFW_KEY_F4;
+ _glfw.wl.keycodes[KEY_F5] = GLFW_KEY_F5;
+ _glfw.wl.keycodes[KEY_F6] = GLFW_KEY_F6;
+ _glfw.wl.keycodes[KEY_F7] = GLFW_KEY_F7;
+ _glfw.wl.keycodes[KEY_F8] = GLFW_KEY_F8;
+ _glfw.wl.keycodes[KEY_F9] = GLFW_KEY_F9;
+ _glfw.wl.keycodes[KEY_F10] = GLFW_KEY_F10;
+ _glfw.wl.keycodes[KEY_F11] = GLFW_KEY_F11;
+ _glfw.wl.keycodes[KEY_F12] = GLFW_KEY_F12;
+ _glfw.wl.keycodes[KEY_F13] = GLFW_KEY_F13;
+ _glfw.wl.keycodes[KEY_F14] = GLFW_KEY_F14;
+ _glfw.wl.keycodes[KEY_F15] = GLFW_KEY_F15;
+ _glfw.wl.keycodes[KEY_F16] = GLFW_KEY_F16;
+ _glfw.wl.keycodes[KEY_F17] = GLFW_KEY_F17;
+ _glfw.wl.keycodes[KEY_F18] = GLFW_KEY_F18;
+ _glfw.wl.keycodes[KEY_F19] = GLFW_KEY_F19;
+ _glfw.wl.keycodes[KEY_F20] = GLFW_KEY_F20;
+ _glfw.wl.keycodes[KEY_F21] = GLFW_KEY_F21;
+ _glfw.wl.keycodes[KEY_F22] = GLFW_KEY_F22;
+ _glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23;
+ _glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24;
+ _glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
+ _glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY;
+ _glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
+ _glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
+ _glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
+ _glfw.wl.keycodes[KEY_KP1] = GLFW_KEY_KP_1;
+ _glfw.wl.keycodes[KEY_KP2] = GLFW_KEY_KP_2;
+ _glfw.wl.keycodes[KEY_KP3] = GLFW_KEY_KP_3;
+ _glfw.wl.keycodes[KEY_KP4] = GLFW_KEY_KP_4;
+ _glfw.wl.keycodes[KEY_KP5] = GLFW_KEY_KP_5;
+ _glfw.wl.keycodes[KEY_KP6] = GLFW_KEY_KP_6;
+ _glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
+ _glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
+ _glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
+ _glfw.wl.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL;
+ _glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
+ _glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
+
+ for (scancode = 0; scancode < 256; scancode++)
+ {
+ if (_glfw.wl.keycodes[scancode] > 0)
+ _glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformInit(void)
+{
+ _glfw.wl.xkb.handle = dlopen("libxkbcommon.so.0", RTLD_LAZY | RTLD_GLOBAL);
+ if (!_glfw.wl.xkb.handle)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to open libxkbcommon.");
+ return GLFW_FALSE;
+ }
+
+ _glfw.wl.xkb.context_new = (PFN_xkb_context_new)
+ dlsym(_glfw.wl.xkb.handle, "xkb_context_new");
+ _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
+ dlsym(_glfw.wl.xkb.handle, "xkb_context_unref");
+ _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
+ dlsym(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
+ _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
+ dlsym(_glfw.wl.xkb.handle, "xkb_keymap_unref");
+ _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
+ dlsym(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
+ _glfw.wl.xkb.state_new = (PFN_xkb_state_new)
+ dlsym(_glfw.wl.xkb.handle, "xkb_state_new");
+ _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
+ dlsym(_glfw.wl.xkb.handle, "xkb_state_unref");
+ _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
+ dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
+ _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
+ dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask");
+ _glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
+ dlsym(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");
+ _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
+ _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
+ _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_new");
+ _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
+ _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
+ _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
+ _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
+ dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
+
+ _glfw.wl.display = wl_display_connect(NULL);
+ if (!_glfw.wl.display)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to connect to display");
+ return GLFW_FALSE;
+ }
+
+ _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
+ wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
+
+ createKeyTables();
+
+ _glfw.wl.xkb.context = xkb_context_new(0);
+ if (!_glfw.wl.xkb.context)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to initialize xkb context");
+ return GLFW_FALSE;
+ }
+
+ // Sync so we got all registry objects
+ wl_display_roundtrip(_glfw.wl.display);
+
+ // Sync so we got all initial output events
+ wl_display_roundtrip(_glfw.wl.display);
+
+ if (!_glfwInitJoysticksLinux())
+ return GLFW_FALSE;
+
+ _glfwInitTimerPOSIX();
+
+ if (_glfw.wl.pointer && _glfw.wl.shm)
+ {
+ _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
+ if (!_glfw.wl.cursorTheme)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Unable to load default cursor theme\n");
+ return GLFW_FALSE;
+ }
+ _glfw.wl.cursorSurface =
+ wl_compositor_create_surface(_glfw.wl.compositor);
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformTerminate(void)
+{
+ _glfwTerminateEGL();
+ _glfwTerminateJoysticksLinux();
+
+ xkb_compose_state_unref(_glfw.wl.xkb.composeState);
+ xkb_keymap_unref(_glfw.wl.xkb.keymap);
+ xkb_state_unref(_glfw.wl.xkb.state);
+ xkb_context_unref(_glfw.wl.xkb.context);
+
+ dlclose(_glfw.wl.xkb.handle);
+ _glfw.wl.xkb.handle = NULL;
+
+ if (_glfw.wl.cursorTheme)
+ wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
+ if (_glfw.wl.cursorSurface)
+ wl_surface_destroy(_glfw.wl.cursorSurface);
+ if (_glfw.wl.compositor)
+ wl_compositor_destroy(_glfw.wl.compositor);
+ if (_glfw.wl.shm)
+ wl_shm_destroy(_glfw.wl.shm);
+ if (_glfw.wl.shell)
+ wl_shell_destroy(_glfw.wl.shell);
+ if (_glfw.wl.pointer)
+ wl_pointer_destroy(_glfw.wl.pointer);
+ if (_glfw.wl.keyboard)
+ wl_keyboard_destroy(_glfw.wl.keyboard);
+ if (_glfw.wl.seat)
+ wl_seat_destroy(_glfw.wl.seat);
+ if (_glfw.wl.relativePointerManager)
+ zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
+ if (_glfw.wl.pointerConstraints)
+ zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints);
+ if (_glfw.wl.registry)
+ wl_registry_destroy(_glfw.wl.registry);
+ if (_glfw.wl.display)
+ {
+ wl_display_flush(_glfw.wl.display);
+ wl_display_disconnect(_glfw.wl.display);
+ }
+}
+
+const char* _glfwPlatformGetVersionString(void)
+{
+ return _GLFW_VERSION_NUMBER " Wayland EGL"
+#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
+ " clock_gettime"
+#else
+ " gettimeofday"
+#endif
+ " evdev"
+#if defined(_GLFW_BUILD_DLL)
+ " shared"
+#endif
+ ;
+}
+
diff --git a/src/external/glfw/src/wl_monitor.c b/src/external/glfw/src/wl_monitor.c
new file mode 100644
index 00000000..10ef0e12
--- /dev/null
+++ b/src/external/glfw/src/wl_monitor.c
@@ -0,0 +1,201 @@
+//========================================================================
+// GLFW 3.3 Wayland - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014 Jonas Ã…dahl <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+
+static void geometry(void* data,
+ struct wl_output* output,
+ int32_t x,
+ int32_t y,
+ int32_t physicalWidth,
+ int32_t physicalHeight,
+ int32_t subpixel,
+ const char* make,
+ const char* model,
+ int32_t transform)
+{
+ struct _GLFWmonitor *monitor = data;
+ char name[1024];
+
+ monitor->wl.x = x;
+ monitor->wl.y = y;
+ monitor->widthMM = physicalWidth;
+ monitor->heightMM = physicalHeight;
+
+ snprintf(name, sizeof(name), "%s %s", make, model);
+ monitor->name = strdup(name);
+}
+
+static void mode(void* data,
+ struct wl_output* output,
+ uint32_t flags,
+ int32_t width,
+ int32_t height,
+ int32_t refresh)
+{
+ struct _GLFWmonitor *monitor = data;
+ GLFWvidmode mode;
+
+ mode.width = width;
+ mode.height = height;
+ mode.redBits = 8;
+ mode.greenBits = 8;
+ mode.blueBits = 8;
+ mode.refreshRate = refresh / 1000;
+
+ monitor->modeCount++;
+ monitor->modes =
+ realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
+ monitor->modes[monitor->modeCount - 1] = mode;
+
+ if (flags & WL_OUTPUT_MODE_CURRENT)
+ monitor->wl.currentMode = monitor->modeCount - 1;
+}
+
+static void done(void* data, struct wl_output* output)
+{
+ struct _GLFWmonitor *monitor = data;
+
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
+}
+
+static void scale(void* data,
+ struct wl_output* output,
+ int32_t factor)
+{
+ struct _GLFWmonitor *monitor = data;
+
+ monitor->wl.scale = factor;
+}
+
+static const struct wl_output_listener outputListener = {
+ geometry,
+ mode,
+ done,
+ scale,
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwAddOutputWayland(uint32_t name, uint32_t version)
+{
+ _GLFWmonitor *monitor;
+ struct wl_output *output;
+
+ if (version < 2)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Unsupported output interface version");
+ return;
+ }
+
+ // The actual name of this output will be set in the geometry handler.
+ monitor = _glfwAllocMonitor(NULL, 0, 0);
+
+ output = wl_registry_bind(_glfw.wl.registry,
+ name,
+ &wl_output_interface,
+ 2);
+ if (!output)
+ {
+ _glfwFreeMonitor(monitor);
+ return;
+ }
+
+ monitor->wl.scale = 1;
+ monitor->wl.output = output;
+
+ wl_output_add_listener(output, &outputListener, monitor);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
+{
+ if (xpos)
+ *xpos = monitor->wl.x;
+ if (ypos)
+ *ypos = monitor->wl.y;
+}
+
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = (float) monitor->wl.scale;
+ if (yscale)
+ *yscale = (float) monitor->wl.scale;
+}
+
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
+{
+ *found = monitor->modeCount;
+ return monitor->modes;
+}
+
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
+{
+ *mode = monitor->modes[monitor->wl.currentMode];
+}
+
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Gamma ramp getting not supported yet");
+}
+
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Gamma ramp setting not supported yet");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return monitor->wl.output;
+}
+
diff --git a/src/external/glfw/src/wl_platform.h b/src/external/glfw/src/wl_platform.h
new file mode 100644
index 00000000..059ea2ee
--- /dev/null
+++ b/src/external/glfw/src/wl_platform.h
@@ -0,0 +1,223 @@
+//========================================================================
+// GLFW 3.3 Wayland - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014 Jonas Ã…dahl <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <wayland-client.h>
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-compose.h>
+#include <dlfcn.h>
+
+typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
+
+typedef struct VkWaylandSurfaceCreateInfoKHR
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkWaylandSurfaceCreateFlagsKHR flags;
+ struct wl_display* display;
+ struct wl_surface* surface;
+} VkWaylandSurfaceCreateInfoKHR;
+
+typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
+
+#include "posix_thread.h"
+#include "posix_time.h"
+#include "linux_joystick.h"
+#include "xkb_unicode.h"
+#include "egl_context.h"
+#include "osmesa_context.h"
+
+#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
+#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
+
+#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
+#define _glfw_dlclose(handle) dlclose(handle)
+#define _glfw_dlsym(handle, name) dlsym(handle, name)
+
+#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native)
+#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
+
+#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl
+#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl
+#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl
+
+#define _GLFW_PLATFORM_CONTEXT_STATE
+#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
+
+typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags);
+typedef void (* PFN_xkb_context_unref)(struct xkb_context*);
+typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
+typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
+typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
+typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
+typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
+typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
+typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
+typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component);
+typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
+typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
+typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
+typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*);
+typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t);
+typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*);
+typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*);
+#define xkb_context_new _glfw.wl.xkb.context_new
+#define xkb_context_unref _glfw.wl.xkb.context_unref
+#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
+#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
+#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
+#define xkb_state_new _glfw.wl.xkb.state_new
+#define xkb_state_unref _glfw.wl.xkb.state_unref
+#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
+#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
+#define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods
+#define xkb_compose_table_new_from_locale _glfw.wl.xkb.compose_table_new_from_locale
+#define xkb_compose_table_unref _glfw.wl.xkb.compose_table_unref
+#define xkb_compose_state_new _glfw.wl.xkb.compose_state_new
+#define xkb_compose_state_unref _glfw.wl.xkb.compose_state_unref
+#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
+#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
+#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
+
+
+// Wayland-specific per-window data
+//
+typedef struct _GLFWwindowWayland
+{
+ int width, height;
+ GLFWbool visible;
+ GLFWbool maximized;
+ GLFWbool transparent;
+ struct wl_surface* surface;
+ struct wl_egl_window* native;
+ struct wl_shell_surface* shellSurface;
+ struct wl_callback* callback;
+
+ _GLFWcursor* currentCursor;
+ double cursorPosX, cursorPosY;
+
+ char* title;
+
+ // We need to track the monitors the window spans on to calculate the
+ // optimal scaling factor.
+ int scale;
+ _GLFWmonitor** monitors;
+ int monitorsCount;
+ int monitorsSize;
+
+ struct {
+ struct zwp_relative_pointer_v1* relativePointer;
+ struct zwp_locked_pointer_v1* lockedPointer;
+ } pointerLock;
+} _GLFWwindowWayland;
+
+// Wayland-specific global data
+//
+typedef struct _GLFWlibraryWayland
+{
+ struct wl_display* display;
+ struct wl_registry* registry;
+ struct wl_compositor* compositor;
+ struct wl_shell* shell;
+ struct wl_shm* shm;
+ struct wl_seat* seat;
+ struct wl_pointer* pointer;
+ struct wl_keyboard* keyboard;
+ struct zwp_relative_pointer_manager_v1* relativePointerManager;
+ struct zwp_pointer_constraints_v1* pointerConstraints;
+
+ int compositorVersion;
+
+ struct wl_cursor_theme* cursorTheme;
+ struct wl_surface* cursorSurface;
+ uint32_t pointerSerial;
+
+ short int keycodes[256];
+ short int scancodes[GLFW_KEY_LAST + 1];
+
+ struct {
+ void* handle;
+ struct xkb_context* context;
+ struct xkb_keymap* keymap;
+ struct xkb_state* state;
+ struct xkb_compose_state* composeState;
+ xkb_mod_mask_t controlMask;
+ xkb_mod_mask_t altMask;
+ xkb_mod_mask_t shiftMask;
+ xkb_mod_mask_t superMask;
+ unsigned int modifiers;
+
+ PFN_xkb_context_new context_new;
+ PFN_xkb_context_unref context_unref;
+ PFN_xkb_keymap_new_from_string keymap_new_from_string;
+ PFN_xkb_keymap_unref keymap_unref;
+ PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
+ PFN_xkb_state_new state_new;
+ PFN_xkb_state_unref state_unref;
+ PFN_xkb_state_key_get_syms state_key_get_syms;
+ PFN_xkb_state_update_mask state_update_mask;
+ PFN_xkb_state_serialize_mods state_serialize_mods;
+ PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
+ PFN_xkb_compose_table_unref compose_table_unref;
+ PFN_xkb_compose_state_new compose_state_new;
+ PFN_xkb_compose_state_unref compose_state_unref;
+ PFN_xkb_compose_state_feed compose_state_feed;
+ PFN_xkb_compose_state_get_status compose_state_get_status;
+ PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
+ } xkb;
+
+ _GLFWwindow* pointerFocus;
+ _GLFWwindow* keyboardFocus;
+
+} _GLFWlibraryWayland;
+
+// Wayland-specific per-monitor data
+//
+typedef struct _GLFWmonitorWayland
+{
+ struct wl_output* output;
+ int currentMode;
+
+ int x;
+ int y;
+ int scale;
+
+} _GLFWmonitorWayland;
+
+// Wayland-specific per-cursor data
+//
+typedef struct _GLFWcursorWayland
+{
+ struct wl_cursor_image* image;
+ struct wl_buffer* buffer;
+ int width, height;
+ int xhot, yhot;
+} _GLFWcursorWayland;
+
+
+void _glfwAddOutputWayland(uint32_t name, uint32_t version);
+
diff --git a/src/external/glfw/src/wl_window.c b/src/external/glfw/src/wl_window.c
new file mode 100644
index 00000000..f0f2637e
--- /dev/null
+++ b/src/external/glfw/src/wl_window.c
@@ -0,0 +1,1106 @@
+//========================================================================
+// GLFW 3.3 Wayland - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014 Jonas Ã…dahl <[email protected]>
+//
+// 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 _GNU_SOURCE
+
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <poll.h>
+
+#include <wayland-egl.h>
+#include <wayland-cursor.h>
+
+
+static void handlePing(void* data,
+ struct wl_shell_surface* shellSurface,
+ uint32_t serial)
+{
+ wl_shell_surface_pong(shellSurface, serial);
+}
+
+static void handleConfigure(void* data,
+ struct wl_shell_surface* shellSurface,
+ uint32_t edges,
+ int32_t width,
+ int32_t height)
+{
+ _GLFWwindow* window = data;
+ float aspectRatio;
+ float targetRatio;
+
+ if (!window->monitor)
+ {
+ if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
+ {
+ aspectRatio = (float)width / (float)height;
+ targetRatio = (float)window->numer / (float)window->denom;
+ if (aspectRatio < targetRatio)
+ height = width / targetRatio;
+ else if (aspectRatio > targetRatio)
+ width = height * targetRatio;
+ }
+
+ if (window->minwidth != GLFW_DONT_CARE && width < window->minwidth)
+ width = window->minwidth;
+ else if (window->maxwidth != GLFW_DONT_CARE && width > window->maxwidth)
+ width = window->maxwidth;
+
+ if (window->minheight != GLFW_DONT_CARE && height < window->minheight)
+ height = window->minheight;
+ else if (window->maxheight != GLFW_DONT_CARE && height > window->maxheight)
+ height = window->maxheight;
+ }
+
+ _glfwInputWindowSize(window, width, height);
+ _glfwPlatformSetWindowSize(window, width, height);
+ _glfwInputWindowDamage(window);
+}
+
+static void handlePopupDone(void* data,
+ struct wl_shell_surface* shellSurface)
+{
+}
+
+static const struct wl_shell_surface_listener shellSurfaceListener = {
+ handlePing,
+ handleConfigure,
+ handlePopupDone
+};
+
+static void checkScaleChange(_GLFWwindow* window)
+{
+ int scaledWidth, scaledHeight;
+ int scale = 1;
+ int i;
+ int monitorScale;
+
+ // Check if we will be able to set the buffer scale or not.
+ if (_glfw.wl.compositorVersion < 3)
+ return;
+
+ // Get the scale factor from the highest scale monitor.
+ for (i = 0; i < window->wl.monitorsCount; ++i)
+ {
+ monitorScale = window->wl.monitors[i]->wl.scale;
+ if (scale < monitorScale)
+ scale = monitorScale;
+ }
+
+ // Only change the framebuffer size if the scale changed.
+ if (scale != window->wl.scale)
+ {
+ window->wl.scale = scale;
+ scaledWidth = window->wl.width * scale;
+ scaledHeight = window->wl.height * scale;
+ wl_surface_set_buffer_scale(window->wl.surface, scale);
+ wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
+ _glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
+ }
+}
+
+static void handleEnter(void *data,
+ struct wl_surface *surface,
+ struct wl_output *output)
+{
+ _GLFWwindow* window = data;
+ _GLFWmonitor* monitor = wl_output_get_user_data(output);
+
+ if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
+ {
+ ++window->wl.monitorsSize;
+ window->wl.monitors =
+ realloc(window->wl.monitors,
+ window->wl.monitorsSize * sizeof(_GLFWmonitor*));
+ }
+
+ window->wl.monitors[window->wl.monitorsCount++] = monitor;
+
+ checkScaleChange(window);
+}
+
+static void handleLeave(void *data,
+ struct wl_surface *surface,
+ struct wl_output *output)
+{
+ _GLFWwindow* window = data;
+ _GLFWmonitor* monitor = wl_output_get_user_data(output);
+ GLFWbool found;
+ int i;
+
+ for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i)
+ {
+ if (monitor == window->wl.monitors[i])
+ found = GLFW_TRUE;
+ if (found)
+ window->wl.monitors[i] = window->wl.monitors[i + 1];
+ }
+ window->wl.monitors[--window->wl.monitorsCount] = NULL;
+
+ checkScaleChange(window);
+}
+
+static const struct wl_surface_listener surfaceListener = {
+ handleEnter,
+ handleLeave
+};
+
+// Makes the surface considered as XRGB instead of ARGB.
+static void setOpaqueRegion(_GLFWwindow* window)
+{
+ struct wl_region* region;
+
+ region = wl_compositor_create_region(_glfw.wl.compositor);
+ if (!region)
+ return;
+
+ wl_region_add(region, 0, 0, window->wl.width, window->wl.height);
+ wl_surface_set_opaque_region(window->wl.surface, region);
+ wl_surface_commit(window->wl.surface);
+ wl_region_destroy(region);
+}
+
+static GLFWbool createSurface(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig)
+{
+ window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
+ if (!window->wl.surface)
+ return GLFW_FALSE;
+
+ wl_surface_add_listener(window->wl.surface,
+ &surfaceListener,
+ window);
+
+ wl_surface_set_user_data(window->wl.surface, window);
+
+ window->wl.native = wl_egl_window_create(window->wl.surface,
+ wndconfig->width,
+ wndconfig->height);
+ if (!window->wl.native)
+ return GLFW_FALSE;
+
+ window->wl.width = wndconfig->width;
+ window->wl.height = wndconfig->height;
+ window->wl.scale = 1;
+
+ if (!window->wl.transparent)
+ setOpaqueRegion(window);
+
+ return GLFW_TRUE;
+}
+
+static GLFWbool createShellSurface(_GLFWwindow* window)
+{
+ window->wl.shellSurface = wl_shell_get_shell_surface(_glfw.wl.shell,
+ window->wl.surface);
+ if (!window->wl.shellSurface)
+ return GLFW_FALSE;
+
+ wl_shell_surface_add_listener(window->wl.shellSurface,
+ &shellSurfaceListener,
+ window);
+
+ if (window->wl.title)
+ wl_shell_surface_set_title(window->wl.shellSurface, window->wl.title);
+
+ if (window->monitor)
+ {
+ wl_shell_surface_set_fullscreen(
+ window->wl.shellSurface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0,
+ window->monitor->wl.output);
+ }
+ else if (window->wl.maximized)
+ {
+ wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
+ }
+ else
+ {
+ wl_shell_surface_set_toplevel(window->wl.shellSurface);
+ }
+
+ wl_surface_commit(window->wl.surface);
+
+ return GLFW_TRUE;
+}
+
+static int
+createTmpfileCloexec(char* tmpname)
+{
+ int fd;
+
+ fd = mkostemp(tmpname, O_CLOEXEC);
+ if (fd >= 0)
+ unlink(tmpname);
+
+ return fd;
+}
+
+static void
+handleEvents(int timeout)
+{
+ struct wl_display* display = _glfw.wl.display;
+ struct pollfd fds[] = {
+ { wl_display_get_fd(display), POLLIN },
+ };
+
+ while (wl_display_prepare_read(display) != 0)
+ wl_display_dispatch_pending(display);
+
+ // If an error different from EAGAIN happens, we have likely been
+ // disconnected from the Wayland session, try to handle that the best we
+ // can.
+ if (wl_display_flush(display) < 0 && errno != EAGAIN)
+ {
+ _GLFWwindow* window = _glfw.windowListHead;
+ while (window)
+ {
+ _glfwInputWindowCloseRequest(window);
+ window = window->next;
+ }
+ wl_display_cancel_read(display);
+ return;
+ }
+
+ if (poll(fds, 1, timeout) > 0)
+ {
+ wl_display_read_events(display);
+ wl_display_dispatch_pending(display);
+ }
+ else
+ {
+ wl_display_cancel_read(display);
+ }
+}
+
+/*
+ * Create a new, unique, anonymous file of the given size, and
+ * return the file descriptor for it. The file descriptor is set
+ * CLOEXEC. The file is immediately suitable for mmap()'ing
+ * the given size at offset zero.
+ *
+ * The file should not have a permanent backing store like a disk,
+ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
+ *
+ * The file name is deleted from the file system.
+ *
+ * The file is suitable for buffer sharing between processes by
+ * transmitting the file descriptor over Unix sockets using the
+ * SCM_RIGHTS methods.
+ *
+ * posix_fallocate() is used to guarantee that disk space is available
+ * for the file at the given size. If disk space is insufficent, errno
+ * is set to ENOSPC. If posix_fallocate() is not supported, program may
+ * receive SIGBUS on accessing mmap()'ed file contents instead.
+ */
+int
+createAnonymousFile(off_t size)
+{
+ static const char template[] = "/glfw-shared-XXXXXX";
+ const char* path;
+ char* name;
+ int fd;
+ int ret;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ name = calloc(strlen(path) + sizeof(template), 1);
+ strcpy(name, path);
+ strcat(name, template);
+
+ fd = createTmpfileCloexec(name);
+
+ free(name);
+
+ if (fd < 0)
+ return -1;
+ ret = posix_fallocate(fd, 0, size);
+ if (ret != 0)
+ {
+ close(fd);
+ errno = ret;
+ return -1;
+ }
+ return fd;
+}
+
+// Translates a GLFW standard cursor to a theme cursor name
+//
+static char *translateCursorShape(int shape)
+{
+ switch (shape)
+ {
+ case GLFW_ARROW_CURSOR:
+ return "left_ptr";
+ case GLFW_IBEAM_CURSOR:
+ return "xterm";
+ case GLFW_CROSSHAIR_CURSOR:
+ return "crosshair";
+ case GLFW_HAND_CURSOR:
+ return "grabbing";
+ case GLFW_HRESIZE_CURSOR:
+ return "sb_h_double_arrow";
+ case GLFW_VRESIZE_CURSOR:
+ return "sb_v_double_arrow";
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ window->wl.transparent = fbconfig->transparent;
+
+ if (!createSurface(window, wndconfig))
+ return GLFW_FALSE;
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
+ ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
+ {
+ if (!_glfwInitEGL())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwInitOSMesa())
+ return GLFW_FALSE;
+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ }
+
+ if (wndconfig->title)
+ window->wl.title = strdup(wndconfig->title);
+
+ if (wndconfig->visible)
+ {
+ if (!createShellSurface(window))
+ return GLFW_FALSE;
+
+ window->wl.visible = GLFW_TRUE;
+ }
+ else
+ {
+ window->wl.shellSurface = NULL;
+ window->wl.visible = GLFW_FALSE;
+ }
+
+ window->wl.currentCursor = NULL;
+
+ window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
+ window->wl.monitorsCount = 0;
+ window->wl.monitorsSize = 1;
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+{
+ if (window == _glfw.wl.pointerFocus)
+ {
+ _glfw.wl.pointerFocus = NULL;
+ _glfwInputCursorEnter(window, GLFW_FALSE);
+ }
+ if (window == _glfw.wl.keyboardFocus)
+ {
+ _glfw.wl.keyboardFocus = NULL;
+ _glfwInputWindowFocus(window, GLFW_FALSE);
+ }
+
+ if (window->context.destroy)
+ window->context.destroy(window);
+
+ if (window->wl.native)
+ wl_egl_window_destroy(window->wl.native);
+
+ if (window->wl.shellSurface)
+ wl_shell_surface_destroy(window->wl.shellSurface);
+
+ if (window->wl.surface)
+ wl_surface_destroy(window->wl.surface);
+
+ free(window->wl.title);
+ free(window->wl.monitors);
+}
+
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
+{
+ if (window->wl.title)
+ free(window->wl.title);
+ window->wl.title = strdup(title);
+ if (window->wl.shellSurface)
+ wl_shell_surface_set_title(window->wl.shellSurface, title);
+}
+
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
+ int count, const GLFWimage* images)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Setting window icon not supported");
+}
+
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+{
+ // A Wayland client is not aware of its position, so just warn and leave it
+ // as (0, 0)
+
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Window position retrieval not supported");
+}
+
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
+{
+ // A Wayland client can not set its position, so just warn
+
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Window position setting not supported");
+}
+
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
+{
+ if (width)
+ *width = window->wl.width;
+ if (height)
+ *height = window->wl.height;
+}
+
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
+{
+ int scaledWidth = width * window->wl.scale;
+ int scaledHeight = height * window->wl.scale;
+ window->wl.width = width;
+ window->wl.height = height;
+ wl_egl_window_resize(window->wl.native, scaledWidth, scaledHeight, 0, 0);
+ if (!window->wl.transparent)
+ setOpaqueRegion(window);
+ _glfwInputFramebufferSize(window, scaledWidth, scaledHeight);
+}
+
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+ // TODO: find out how to trigger a resize.
+ // The actual limits are checked in the wl_shell_surface::configure handler.
+}
+
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
+{
+ // TODO: find out how to trigger a resize.
+ // The actual limits are checked in the wl_shell_surface::configure handler.
+}
+
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
+{
+ _glfwPlatformGetWindowSize(window, width, height);
+ *width *= window->wl.scale;
+ *height *= window->wl.scale;
+}
+
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+ // TODO: will need a proper implementation once decorations are
+ // implemented, but for now just leave everything as 0.
+}
+
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = (float) window->wl.scale;
+ if (yscale)
+ *yscale = (float) window->wl.scale;
+}
+
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
+{
+ // TODO: move to xdg_shell instead of wl_shell.
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Iconify window not supported");
+}
+
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
+{
+ // TODO: also do the same for iconified.
+ if (window->monitor || window->wl.maximized)
+ {
+ if (window->wl.shellSurface)
+ wl_shell_surface_set_toplevel(window->wl.shellSurface);
+
+ window->wl.maximized = GLFW_FALSE;
+ }
+}
+
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
+{
+ if (!window->monitor && !window->wl.maximized)
+ {
+ if (window->wl.shellSurface)
+ {
+ // Let the compositor select the best output.
+ wl_shell_surface_set_maximized(window->wl.shellSurface, NULL);
+ }
+ window->wl.maximized = GLFW_TRUE;
+ }
+}
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+ if (!window->monitor)
+ {
+ if (!window->wl.shellSurface)
+ createShellSurface(window);
+ window->wl.visible = GLFW_TRUE;
+ }
+}
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+ if (!window->monitor)
+ {
+ if (window->wl.shellSurface)
+ wl_shell_surface_destroy(window->wl.shellSurface);
+ window->wl.visible = GLFW_FALSE;
+ }
+}
+
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Window attention request not implemented yet");
+}
+
+void _glfwPlatformFocusWindow(_GLFWwindow* window)
+{
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Focusing a window requires user interaction");
+}
+
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+ _GLFWmonitor* monitor,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+ if (monitor)
+ {
+ wl_shell_surface_set_fullscreen(
+ window->wl.shellSurface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ refreshRate * 1000, // Convert Hz to mHz.
+ monitor->wl.output);
+ }
+ else
+ {
+ wl_shell_surface_set_toplevel(window->wl.shellSurface);
+ }
+ _glfwInputWindowMonitor(window, monitor);
+}
+
+int _glfwPlatformWindowFocused(_GLFWwindow* window)
+{
+ return _glfw.wl.keyboardFocus == window;
+}
+
+int _glfwPlatformWindowIconified(_GLFWwindow* window)
+{
+ // TODO: move to xdg_shell, wl_shell doesn't have any iconified concept.
+ return GLFW_FALSE;
+}
+
+int _glfwPlatformWindowVisible(_GLFWwindow* window)
+{
+ return window->wl.visible;
+}
+
+int _glfwPlatformWindowMaximized(_GLFWwindow* window)
+{
+ return window->wl.maximized;
+}
+
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
+{
+ return window->wl.transparent;
+}
+
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Window attribute setting not implemented yet");
+}
+
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Window attribute setting not implemented yet");
+}
+
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Window attribute setting not implemented yet");
+}
+
+void _glfwPlatformPollEvents(void)
+{
+ handleEvents(0);
+}
+
+void _glfwPlatformWaitEvents(void)
+{
+ handleEvents(-1);
+}
+
+void _glfwPlatformWaitEventsTimeout(double timeout)
+{
+ handleEvents((int) (timeout * 1e3));
+}
+
+void _glfwPlatformPostEmptyEvent(void)
+{
+ wl_display_sync(_glfw.wl.display);
+}
+
+void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
+{
+ if (xpos)
+ *xpos = window->wl.cursorPosX;
+ if (ypos)
+ *ypos = window->wl.cursorPosY;
+}
+
+static GLFWbool isPointerLocked(_GLFWwindow* window);
+
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
+{
+ if (isPointerLocked(window))
+ {
+ zwp_locked_pointer_v1_set_cursor_position_hint(
+ window->wl.pointerLock.lockedPointer,
+ wl_fixed_from_double(x), wl_fixed_from_double(y));
+ wl_surface_commit(window->wl.surface);
+ }
+}
+
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
+{
+ _glfwPlatformSetCursor(window, window->wl.currentCursor);
+}
+
+const char* _glfwPlatformGetScancodeName(int scancode)
+{
+ // TODO
+ return NULL;
+}
+
+int _glfwPlatformGetKeyScancode(int key)
+{
+ return _glfw.wl.scancodes[key];
+}
+
+int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
+ const GLFWimage* image,
+ int xhot, int yhot)
+{
+ struct wl_shm_pool* pool;
+ int stride = image->width * 4;
+ int length = image->width * image->height * 4;
+ void* data;
+ int fd, i;
+
+ fd = createAnonymousFile(length);
+ if (fd < 0)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Creating a buffer file for %d B failed: %m",
+ length);
+ return GLFW_FALSE;
+ }
+
+ data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Cursor mmap failed: %m");
+ close(fd);
+ return GLFW_FALSE;
+ }
+
+ pool = wl_shm_create_pool(_glfw.wl.shm, fd, length);
+
+ close(fd);
+ unsigned char* source = (unsigned char*) image->pixels;
+ unsigned char* target = data;
+ for (i = 0; i < image->width * image->height; i++, source += 4)
+ {
+ unsigned int alpha = source[3];
+
+ *target++ = (unsigned char) ((source[2] * alpha) / 255);
+ *target++ = (unsigned char) ((source[1] * alpha) / 255);
+ *target++ = (unsigned char) ((source[0] * alpha) / 255);
+ *target++ = (unsigned char) alpha;
+ }
+
+ cursor->wl.buffer =
+ wl_shm_pool_create_buffer(pool, 0,
+ image->width,
+ image->height,
+ stride, WL_SHM_FORMAT_ARGB8888);
+ munmap(data, length);
+ wl_shm_pool_destroy(pool);
+
+ cursor->wl.width = image->width;
+ cursor->wl.height = image->height;
+ cursor->wl.xhot = xhot;
+ cursor->wl.yhot = yhot;
+ return GLFW_TRUE;
+}
+
+int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
+{
+ struct wl_cursor* standardCursor;
+
+ standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
+ translateCursorShape(shape));
+ if (!standardCursor)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Standard cursor \"%s\" not found",
+ translateCursorShape(shape));
+ return GLFW_FALSE;
+ }
+
+ cursor->wl.image = standardCursor->images[0];
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
+{
+ // If it's a standard cursor we don't need to do anything here
+ if (cursor->wl.image)
+ return;
+
+ if (cursor->wl.buffer)
+ wl_buffer_destroy(cursor->wl.buffer);
+}
+
+static void handleRelativeMotion(void* data,
+ struct zwp_relative_pointer_v1* pointer,
+ uint32_t timeHi,
+ uint32_t timeLo,
+ wl_fixed_t dx,
+ wl_fixed_t dy,
+ wl_fixed_t dxUnaccel,
+ wl_fixed_t dyUnaccel)
+{
+ _GLFWwindow* window = data;
+
+ if (window->cursorMode != GLFW_CURSOR_DISABLED)
+ return;
+
+ _glfwInputCursorPos(window,
+ window->virtualCursorPosX + wl_fixed_to_double(dxUnaccel),
+ window->virtualCursorPosY + wl_fixed_to_double(dyUnaccel));
+}
+
+static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
+ handleRelativeMotion
+};
+
+static void handleLocked(void* data,
+ struct zwp_locked_pointer_v1* lockedPointer)
+{
+}
+
+static void unlockPointer(_GLFWwindow* window)
+{
+ struct zwp_relative_pointer_v1* relativePointer =
+ window->wl.pointerLock.relativePointer;
+ struct zwp_locked_pointer_v1* lockedPointer =
+ window->wl.pointerLock.lockedPointer;
+
+ zwp_relative_pointer_v1_destroy(relativePointer);
+ zwp_locked_pointer_v1_destroy(lockedPointer);
+
+ window->wl.pointerLock.relativePointer = NULL;
+ window->wl.pointerLock.lockedPointer = NULL;
+}
+
+static void lockPointer(_GLFWwindow* window);
+
+static void handleUnlocked(void* data,
+ struct zwp_locked_pointer_v1* lockedPointer)
+{
+}
+
+static const struct zwp_locked_pointer_v1_listener lockedPointerListener = {
+ handleLocked,
+ handleUnlocked
+};
+
+static void lockPointer(_GLFWwindow* window)
+{
+ struct zwp_relative_pointer_v1* relativePointer;
+ struct zwp_locked_pointer_v1* lockedPointer;
+
+ if (!_glfw.wl.relativePointerManager)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: no relative pointer manager");
+ return;
+ }
+
+ relativePointer =
+ zwp_relative_pointer_manager_v1_get_relative_pointer(
+ _glfw.wl.relativePointerManager,
+ _glfw.wl.pointer);
+ zwp_relative_pointer_v1_add_listener(relativePointer,
+ &relativePointerListener,
+ window);
+
+ lockedPointer =
+ zwp_pointer_constraints_v1_lock_pointer(
+ _glfw.wl.pointerConstraints,
+ window->wl.surface,
+ _glfw.wl.pointer,
+ NULL,
+ ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
+ zwp_locked_pointer_v1_add_listener(lockedPointer,
+ &lockedPointerListener,
+ window);
+
+ window->wl.pointerLock.relativePointer = relativePointer;
+ window->wl.pointerLock.lockedPointer = lockedPointer;
+
+ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
+ NULL, 0, 0);
+}
+
+static GLFWbool isPointerLocked(_GLFWwindow* window)
+{
+ return window->wl.pointerLock.lockedPointer != NULL;
+}
+
+void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+{
+ struct wl_buffer* buffer;
+ struct wl_cursor* defaultCursor;
+ struct wl_cursor_image* image;
+ struct wl_surface* surface = _glfw.wl.cursorSurface;
+
+ if (!_glfw.wl.pointer)
+ return;
+
+ window->wl.currentCursor = cursor;
+
+ // If we're not in the correct window just save the cursor
+ // the next time the pointer enters the window the cursor will change
+ if (window != _glfw.wl.pointerFocus)
+ return;
+
+ // Unlock possible pointer lock if no longer disabled.
+ if (window->cursorMode != GLFW_CURSOR_DISABLED && isPointerLocked(window))
+ unlockPointer(window);
+
+ if (window->cursorMode == GLFW_CURSOR_NORMAL)
+ {
+ if (cursor)
+ image = cursor->wl.image;
+ else
+ {
+ defaultCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
+ "left_ptr");
+ if (!defaultCursor)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Standard cursor not found");
+ return;
+ }
+ image = defaultCursor->images[0];
+ }
+
+ if (image)
+ {
+ buffer = wl_cursor_image_get_buffer(image);
+ if (!buffer)
+ return;
+ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
+ surface,
+ image->hotspot_x,
+ image->hotspot_y);
+ wl_surface_attach(surface, buffer, 0, 0);
+ wl_surface_damage(surface, 0, 0,
+ image->width, image->height);
+ wl_surface_commit(surface);
+ }
+ else
+ {
+ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
+ surface,
+ cursor->wl.xhot,
+ cursor->wl.yhot);
+ wl_surface_attach(surface, cursor->wl.buffer, 0, 0);
+ wl_surface_damage(surface, 0, 0,
+ cursor->wl.width, cursor->wl.height);
+ wl_surface_commit(surface);
+ }
+ }
+ else if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ {
+ if (!isPointerLocked(window))
+ lockPointer(window);
+ }
+ else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ {
+ wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial,
+ NULL, 0, 0);
+ }
+}
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Clipboard setting not implemented yet");
+}
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ // TODO
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Clipboard getting not implemented yet");
+ return NULL;
+}
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
+{
+ if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
+ return;
+
+ extensions[0] = "VK_KHR_surface";
+ extensions[1] = "VK_KHR_wayland_surface";
+}
+
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
+ vkGetPhysicalDeviceWaylandPresentationSupportKHR =
+ (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
+ if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
+ return VK_NULL_HANDLE;
+ }
+
+ return vkGetPhysicalDeviceWaylandPresentationSupportKHR(device,
+ queuefamily,
+ _glfw.wl.display);
+}
+
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
+ _GLFWwindow* window,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+ VkResult err;
+ VkWaylandSurfaceCreateInfoKHR sci;
+ PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
+
+ vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)
+ vkGetInstanceProcAddr(instance, "vkCreateWaylandSurfaceKHR");
+ if (!vkCreateWaylandSurfaceKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "Wayland: Vulkan instance missing VK_KHR_wayland_surface extension");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ memset(&sci, 0, sizeof(sci));
+ sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+ sci.display = _glfw.wl.display;
+ sci.surface = window->wl.surface;
+
+ err = vkCreateWaylandSurfaceKHR(instance, &sci, allocator, surface);
+ if (err)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Failed to create Vulkan surface: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ return err;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI struct wl_display* glfwGetWaylandDisplay(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return _glfw.wl.display;
+}
+
+GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return window->wl.surface;
+}
+
diff --git a/src/external/glfw/src/x11_init.c b/src/external/glfw/src/x11_init.c
new file mode 100644
index 00000000..b603a15f
--- /dev/null
+++ b/src/external/glfw/src/x11_init.c
@@ -0,0 +1,1045 @@
+//========================================================================
+// GLFW 3.3 X11 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <X11/Xresource.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+#include <locale.h>
+
+
+// Translate an X11 key code to a GLFW key code.
+//
+static int translateKeyCode(int scancode)
+{
+ int keySym;
+
+ // Valid key code range is [8,255], according to the Xlib manual
+ if (scancode < 8 || scancode > 255)
+ return GLFW_KEY_UNKNOWN;
+
+ if (_glfw.x11.xkb.available)
+ {
+ // Try secondary keysym, for numeric keypad keys
+ // Note: This way we always force "NumLock = ON", which is intentional
+ // since the returned key code should correspond to a physical
+ // location.
+ keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1);
+ switch (keySym)
+ {
+ case XK_KP_0: return GLFW_KEY_KP_0;
+ case XK_KP_1: return GLFW_KEY_KP_1;
+ case XK_KP_2: return GLFW_KEY_KP_2;
+ case XK_KP_3: return GLFW_KEY_KP_3;
+ case XK_KP_4: return GLFW_KEY_KP_4;
+ case XK_KP_5: return GLFW_KEY_KP_5;
+ case XK_KP_6: return GLFW_KEY_KP_6;
+ case XK_KP_7: return GLFW_KEY_KP_7;
+ case XK_KP_8: return GLFW_KEY_KP_8;
+ case XK_KP_9: return GLFW_KEY_KP_9;
+ case XK_KP_Separator:
+ case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL;
+ case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
+ case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
+ default: break;
+ }
+
+ // Now try primary keysym for function keys (non-printable keys)
+ // These should not depend on the current keyboard layout
+ keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
+ }
+ else
+ {
+ int dummy;
+ KeySym* keySyms;
+
+ keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy);
+ keySym = keySyms[0];
+ XFree(keySyms);
+ }
+
+ switch (keySym)
+ {
+ case XK_Escape: return GLFW_KEY_ESCAPE;
+ case XK_Tab: return GLFW_KEY_TAB;
+ case XK_Shift_L: return GLFW_KEY_LEFT_SHIFT;
+ case XK_Shift_R: return GLFW_KEY_RIGHT_SHIFT;
+ case XK_Control_L: return GLFW_KEY_LEFT_CONTROL;
+ case XK_Control_R: return GLFW_KEY_RIGHT_CONTROL;
+ case XK_Meta_L:
+ case XK_Alt_L: return GLFW_KEY_LEFT_ALT;
+ case XK_Mode_switch: // Mapped to Alt_R on many keyboards
+ case XK_ISO_Level3_Shift: // AltGr on at least some machines
+ case XK_Meta_R:
+ case XK_Alt_R: return GLFW_KEY_RIGHT_ALT;
+ case XK_Super_L: return GLFW_KEY_LEFT_SUPER;
+ case XK_Super_R: return GLFW_KEY_RIGHT_SUPER;
+ case XK_Menu: return GLFW_KEY_MENU;
+ case XK_Num_Lock: return GLFW_KEY_NUM_LOCK;
+ case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK;
+ case XK_Print: return GLFW_KEY_PRINT_SCREEN;
+ case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK;
+ case XK_Pause: return GLFW_KEY_PAUSE;
+ case XK_Delete: return GLFW_KEY_DELETE;
+ case XK_BackSpace: return GLFW_KEY_BACKSPACE;
+ case XK_Return: return GLFW_KEY_ENTER;
+ case XK_Home: return GLFW_KEY_HOME;
+ case XK_End: return GLFW_KEY_END;
+ case XK_Page_Up: return GLFW_KEY_PAGE_UP;
+ case XK_Page_Down: return GLFW_KEY_PAGE_DOWN;
+ case XK_Insert: return GLFW_KEY_INSERT;
+ case XK_Left: return GLFW_KEY_LEFT;
+ case XK_Right: return GLFW_KEY_RIGHT;
+ case XK_Down: return GLFW_KEY_DOWN;
+ case XK_Up: return GLFW_KEY_UP;
+ case XK_F1: return GLFW_KEY_F1;
+ case XK_F2: return GLFW_KEY_F2;
+ case XK_F3: return GLFW_KEY_F3;
+ case XK_F4: return GLFW_KEY_F4;
+ case XK_F5: return GLFW_KEY_F5;
+ case XK_F6: return GLFW_KEY_F6;
+ case XK_F7: return GLFW_KEY_F7;
+ case XK_F8: return GLFW_KEY_F8;
+ case XK_F9: return GLFW_KEY_F9;
+ case XK_F10: return GLFW_KEY_F10;
+ case XK_F11: return GLFW_KEY_F11;
+ case XK_F12: return GLFW_KEY_F12;
+ case XK_F13: return GLFW_KEY_F13;
+ case XK_F14: return GLFW_KEY_F14;
+ case XK_F15: return GLFW_KEY_F15;
+ case XK_F16: return GLFW_KEY_F16;
+ case XK_F17: return GLFW_KEY_F17;
+ case XK_F18: return GLFW_KEY_F18;
+ case XK_F19: return GLFW_KEY_F19;
+ case XK_F20: return GLFW_KEY_F20;
+ case XK_F21: return GLFW_KEY_F21;
+ case XK_F22: return GLFW_KEY_F22;
+ case XK_F23: return GLFW_KEY_F23;
+ case XK_F24: return GLFW_KEY_F24;
+ case XK_F25: return GLFW_KEY_F25;
+
+ // Numeric keypad
+ case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE;
+ case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY;
+ case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT;
+ case XK_KP_Add: return GLFW_KEY_KP_ADD;
+
+ // These should have been detected in secondary keysym test above!
+ case XK_KP_Insert: return GLFW_KEY_KP_0;
+ case XK_KP_End: return GLFW_KEY_KP_1;
+ case XK_KP_Down: return GLFW_KEY_KP_2;
+ case XK_KP_Page_Down: return GLFW_KEY_KP_3;
+ case XK_KP_Left: return GLFW_KEY_KP_4;
+ case XK_KP_Right: return GLFW_KEY_KP_6;
+ case XK_KP_Home: return GLFW_KEY_KP_7;
+ case XK_KP_Up: return GLFW_KEY_KP_8;
+ case XK_KP_Page_Up: return GLFW_KEY_KP_9;
+ case XK_KP_Delete: return GLFW_KEY_KP_DECIMAL;
+ case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
+ case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
+
+ // Last resort: Check for printable keys (should not happen if the XKB
+ // extension is available). This will give a layout dependent mapping
+ // (which is wrong, and we may miss some keys, especially on non-US
+ // keyboards), but it's better than nothing...
+ case XK_a: return GLFW_KEY_A;
+ case XK_b: return GLFW_KEY_B;
+ case XK_c: return GLFW_KEY_C;
+ case XK_d: return GLFW_KEY_D;
+ case XK_e: return GLFW_KEY_E;
+ case XK_f: return GLFW_KEY_F;
+ case XK_g: return GLFW_KEY_G;
+ case XK_h: return GLFW_KEY_H;
+ case XK_i: return GLFW_KEY_I;
+ case XK_j: return GLFW_KEY_J;
+ case XK_k: return GLFW_KEY_K;
+ case XK_l: return GLFW_KEY_L;
+ case XK_m: return GLFW_KEY_M;
+ case XK_n: return GLFW_KEY_N;
+ case XK_o: return GLFW_KEY_O;
+ case XK_p: return GLFW_KEY_P;
+ case XK_q: return GLFW_KEY_Q;
+ case XK_r: return GLFW_KEY_R;
+ case XK_s: return GLFW_KEY_S;
+ case XK_t: return GLFW_KEY_T;
+ case XK_u: return GLFW_KEY_U;
+ case XK_v: return GLFW_KEY_V;
+ case XK_w: return GLFW_KEY_W;
+ case XK_x: return GLFW_KEY_X;
+ case XK_y: return GLFW_KEY_Y;
+ case XK_z: return GLFW_KEY_Z;
+ case XK_1: return GLFW_KEY_1;
+ case XK_2: return GLFW_KEY_2;
+ case XK_3: return GLFW_KEY_3;
+ case XK_4: return GLFW_KEY_4;
+ case XK_5: return GLFW_KEY_5;
+ case XK_6: return GLFW_KEY_6;
+ case XK_7: return GLFW_KEY_7;
+ case XK_8: return GLFW_KEY_8;
+ case XK_9: return GLFW_KEY_9;
+ case XK_0: return GLFW_KEY_0;
+ case XK_space: return GLFW_KEY_SPACE;
+ case XK_minus: return GLFW_KEY_MINUS;
+ case XK_equal: return GLFW_KEY_EQUAL;
+ case XK_bracketleft: return GLFW_KEY_LEFT_BRACKET;
+ case XK_bracketright: return GLFW_KEY_RIGHT_BRACKET;
+ case XK_backslash: return GLFW_KEY_BACKSLASH;
+ case XK_semicolon: return GLFW_KEY_SEMICOLON;
+ case XK_apostrophe: return GLFW_KEY_APOSTROPHE;
+ case XK_grave: return GLFW_KEY_GRAVE_ACCENT;
+ case XK_comma: return GLFW_KEY_COMMA;
+ case XK_period: return GLFW_KEY_PERIOD;
+ case XK_slash: return GLFW_KEY_SLASH;
+ case XK_less: return GLFW_KEY_WORLD_1; // At least in some layouts...
+ default: break;
+ }
+
+ // No matching translation was found
+ return GLFW_KEY_UNKNOWN;
+}
+
+// Create key code translation tables
+//
+static void createKeyTables(void)
+{
+ int scancode, key;
+
+ memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
+ memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
+
+ if (_glfw.x11.xkb.available)
+ {
+ // Use XKB to determine physical key locations independently of the
+ // current keyboard layout
+
+ char name[XkbKeyNameLength + 1];
+ XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
+ XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc);
+
+ // Find the X11 key code -> GLFW key code mapping
+ for (scancode = desc->min_key_code; scancode <= desc->max_key_code; scancode++)
+ {
+ memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
+ name[XkbKeyNameLength] = '\0';
+
+ // Map the key name to a GLFW key code. Note: We only map printable
+ // keys here, and we use the US keyboard layout. The rest of the
+ // keys (function keys) are mapped using traditional KeySym
+ // translations.
+ if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT;
+ else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1;
+ else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2;
+ else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3;
+ else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4;
+ else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5;
+ else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6;
+ else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7;
+ else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8;
+ else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9;
+ else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0;
+ else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS;
+ else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL;
+ else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q;
+ else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W;
+ else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E;
+ else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R;
+ else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T;
+ else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y;
+ else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U;
+ else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I;
+ else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O;
+ else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P;
+ else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET;
+ else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET;
+ else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A;
+ else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S;
+ else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D;
+ else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F;
+ else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G;
+ else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H;
+ else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J;
+ else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K;
+ else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L;
+ else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON;
+ else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE;
+ else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z;
+ else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X;
+ else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C;
+ else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V;
+ else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B;
+ else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N;
+ else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M;
+ else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA;
+ else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD;
+ else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH;
+ else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH;
+ else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1;
+ else key = GLFW_KEY_UNKNOWN;
+
+ if ((scancode >= 0) && (scancode < 256))
+ _glfw.x11.keycodes[scancode] = key;
+ }
+
+ XkbFreeNames(desc, XkbKeyNamesMask, True);
+ XkbFreeKeyboard(desc, 0, True);
+ }
+
+ for (scancode = 0; scancode < 256; scancode++)
+ {
+ // Translate the un-translated key codes using traditional X11 KeySym
+ // lookups
+ if (_glfw.x11.keycodes[scancode] < 0)
+ _glfw.x11.keycodes[scancode] = translateKeyCode(scancode);
+
+ // Store the reverse translation for faster key name lookup
+ if (_glfw.x11.keycodes[scancode] > 0)
+ _glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode;
+ }
+}
+
+// Check whether the IM has a usable style
+//
+static GLFWbool hasUsableInputMethodStyle(void)
+{
+ unsigned int i;
+ GLFWbool found = GLFW_FALSE;
+ XIMStyles* styles = NULL;
+
+ if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL)
+ return GLFW_FALSE;
+
+ for (i = 0; i < styles->count_styles; i++)
+ {
+ if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
+ {
+ found = GLFW_TRUE;
+ break;
+ }
+ }
+
+ XFree(styles);
+ return found;
+}
+
+// Check whether the specified atom is supported
+//
+static Atom getSupportedAtom(Atom* supportedAtoms,
+ unsigned long atomCount,
+ const char* atomName)
+{
+ unsigned long i;
+ const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
+
+ for (i = 0; i < atomCount; i++)
+ {
+ if (supportedAtoms[i] == atom)
+ return atom;
+ }
+
+ return None;
+}
+
+// Check whether the running window manager is EWMH-compliant
+//
+static void detectEWMH(void)
+{
+ Window* windowFromRoot = NULL;
+ Window* windowFromChild = NULL;
+
+ // First we need a couple of atoms
+ const Atom supportingWmCheck =
+ XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
+ const Atom wmSupported =
+ XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
+
+ // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
+ if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
+ supportingWmCheck,
+ XA_WINDOW,
+ (unsigned char**) &windowFromRoot))
+ {
+ return;
+ }
+
+ _glfwGrabErrorHandlerX11();
+
+ // It should be the ID of a child window (of the root)
+ // Then we look for the same property on the child window
+ if (!_glfwGetWindowPropertyX11(*windowFromRoot,
+ supportingWmCheck,
+ XA_WINDOW,
+ (unsigned char**) &windowFromChild))
+ {
+ XFree(windowFromRoot);
+ return;
+ }
+
+ _glfwReleaseErrorHandlerX11();
+
+ // It should be the ID of that same child window
+ if (*windowFromRoot != *windowFromChild)
+ {
+ XFree(windowFromRoot);
+ XFree(windowFromChild);
+ return;
+ }
+
+ XFree(windowFromRoot);
+ XFree(windowFromChild);
+
+ // We are now fairly sure that an EWMH-compliant window manager is running
+
+ Atom* supportedAtoms;
+ unsigned long atomCount;
+
+ // Now we need to check the _NET_SUPPORTED property of the root window
+ // It should be a list of supported WM protocol and state atoms
+ atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
+ wmSupported,
+ XA_ATOM,
+ (unsigned char**) &supportedAtoms);
+
+ // See which of the atoms we support that are supported by the WM
+ _glfw.x11.NET_WM_STATE =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
+ _glfw.x11.NET_WM_STATE_ABOVE =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
+ _glfw.x11.NET_WM_STATE_FULLSCREEN =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
+ _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
+ _glfw.x11.NET_WM_FULLSCREEN_MONITORS =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
+ _glfw.x11.NET_WM_WINDOW_TYPE =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
+ _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
+ _glfw.x11.NET_ACTIVE_WINDOW =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
+ _glfw.x11.NET_FRAME_EXTENTS =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
+ _glfw.x11.NET_REQUEST_FRAME_EXTENTS =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
+
+ if (supportedAtoms)
+ XFree(supportedAtoms);
+}
+
+// Look for and initialize supported X11 extensions
+//
+static GLFWbool initExtensions(void)
+{
+ _glfw.x11.vidmode.handle = dlopen("libXxf86vm.so.1", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.vidmode.handle)
+ {
+ _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
+ dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
+ _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
+ dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
+ _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
+ dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
+ _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
+ dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
+
+ _glfw.x11.vidmode.available =
+ XF86VidModeQueryExtension(_glfw.x11.display,
+ &_glfw.x11.vidmode.eventBase,
+ &_glfw.x11.vidmode.errorBase);
+ }
+
+ _glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.xi.handle)
+ {
+ _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
+ dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
+ _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
+ dlsym(_glfw.x11.xi.handle, "XISelectEvents");
+
+ if (XQueryExtension(_glfw.x11.display,
+ "XInputExtension",
+ &_glfw.x11.xi.majorOpcode,
+ &_glfw.x11.xi.eventBase,
+ &_glfw.x11.xi.errorBase))
+ {
+ _glfw.x11.xi.major = 2;
+ _glfw.x11.xi.minor = 0;
+
+ if (XIQueryVersion(_glfw.x11.display,
+ &_glfw.x11.xi.major,
+ &_glfw.x11.xi.minor) == Success)
+ {
+ _glfw.x11.xi.available = GLFW_TRUE;
+ }
+ }
+ }
+
+ _glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.randr.handle)
+ {
+ _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
+ dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
+ _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
+ dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
+ _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
+ dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
+ _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
+ dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
+ _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
+ dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
+ _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
+ dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
+ _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
+ dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
+ _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
+ dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
+ _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
+ dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
+ _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
+ dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
+ _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
+ dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
+ _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
+ dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
+ _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
+ dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
+ _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
+ dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
+ _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
+ dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
+ _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
+ dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
+ _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
+ dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
+ _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
+ dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
+
+ if (XRRQueryExtension(_glfw.x11.display,
+ &_glfw.x11.randr.eventBase,
+ &_glfw.x11.randr.errorBase))
+ {
+ if (XRRQueryVersion(_glfw.x11.display,
+ &_glfw.x11.randr.major,
+ &_glfw.x11.randr.minor))
+ {
+ // The GLFW RandR path requires at least version 1.3
+ if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
+ _glfw.x11.randr.available = GLFW_TRUE;
+ }
+ else
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to query RandR version");
+ }
+ }
+ }
+
+ if (_glfw.x11.randr.available)
+ {
+ XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
+ _glfw.x11.root);
+
+ if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
+ {
+ // This is likely an older Nvidia driver with broken gamma support
+ // Flag it as useless and fall back to xf86vm gamma, if available
+ _glfw.x11.randr.gammaBroken = GLFW_TRUE;
+ }
+
+ if (!sr->ncrtc)
+ {
+ // A system without CRTCs is likely a system with broken RandR
+ // Disable the RandR monitor path and fall back to core functions
+ _glfw.x11.randr.monitorBroken = GLFW_TRUE;
+ }
+
+ XRRFreeScreenResources(sr);
+ }
+
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
+ RROutputChangeNotifyMask);
+ }
+
+ _glfw.x11.xcursor.handle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.xcursor.handle)
+ {
+ _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
+ dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
+ _glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
+ dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
+ _glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
+ dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
+ }
+
+ _glfw.x11.xinerama.handle = dlopen("libXinerama.so.1", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.xinerama.handle)
+ {
+ _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
+ dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
+ _glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
+ dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
+ _glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
+ dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
+
+ if (XineramaQueryExtension(_glfw.x11.display,
+ &_glfw.x11.xinerama.major,
+ &_glfw.x11.xinerama.minor))
+ {
+ if (XineramaIsActive(_glfw.x11.display))
+ _glfw.x11.xinerama.available = GLFW_TRUE;
+ }
+ }
+
+ _glfw.x11.xkb.major = 1;
+ _glfw.x11.xkb.minor = 0;
+ _glfw.x11.xkb.available =
+ XkbQueryExtension(_glfw.x11.display,
+ &_glfw.x11.xkb.majorOpcode,
+ &_glfw.x11.xkb.eventBase,
+ &_glfw.x11.xkb.errorBase,
+ &_glfw.x11.xkb.major,
+ &_glfw.x11.xkb.minor);
+
+ if (_glfw.x11.xkb.available)
+ {
+ Bool supported;
+
+ if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
+ {
+ if (supported)
+ _glfw.x11.xkb.detectable = GLFW_TRUE;
+ }
+ }
+
+ _glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so.1", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.x11xcb.handle)
+ {
+ _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
+ dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
+ }
+
+ _glfw.x11.xrender.handle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfw.x11.xrender.handle)
+ {
+ _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
+ dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
+ _glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
+ dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
+ _glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
+ dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");
+
+ if (XRenderQueryExtension(_glfw.x11.display,
+ &_glfw.x11.xrender.errorBase,
+ &_glfw.x11.xrender.eventBase))
+ {
+ if (XRenderQueryVersion(_glfw.x11.display,
+ &_glfw.x11.xrender.major,
+ &_glfw.x11.xrender.minor))
+ {
+ _glfw.x11.xrender.available = GLFW_TRUE;
+ }
+ }
+ }
+
+ // Update the key code LUT
+ // FIXME: We should listen to XkbMapNotify events to track changes to
+ // the keyboard mapping.
+ createKeyTables();
+
+ // Detect whether an EWMH-conformant window manager is running
+ detectEWMH();
+
+ // String format atoms
+ _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
+ _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
+ _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
+
+ // Custom selection property atom
+ _glfw.x11.GLFW_SELECTION =
+ XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);
+
+ // ICCCM standard clipboard atoms
+ _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
+ _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
+ _glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
+ _glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False);
+ _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
+
+ // Clipboard manager atoms
+ _glfw.x11.CLIPBOARD_MANAGER =
+ XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
+ _glfw.x11.SAVE_TARGETS =
+ XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
+
+ // Xdnd (drag and drop) atoms
+ _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False);
+ _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False);
+ _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False);
+ _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
+ _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);
+ _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);
+ _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);
+ _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False);
+ _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False);
+ _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False);
+
+ // ICCCM, EWMH and Motif window property atoms
+ // These can be set safely even without WM support
+ // The EWMH atoms that require WM support are handled in detectEWMH
+ _glfw.x11.WM_PROTOCOLS =
+ XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False);
+ _glfw.x11.WM_STATE =
+ XInternAtom(_glfw.x11.display, "WM_STATE", False);
+ _glfw.x11.WM_DELETE_WINDOW =
+ XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
+ _glfw.x11.NET_WM_ICON =
+ XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
+ _glfw.x11.NET_WM_PING =
+ XInternAtom(_glfw.x11.display, "_NET_WM_PING", False);
+ _glfw.x11.NET_WM_PID =
+ XInternAtom(_glfw.x11.display, "_NET_WM_PID", False);
+ _glfw.x11.NET_WM_NAME =
+ XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False);
+ _glfw.x11.NET_WM_ICON_NAME =
+ XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False);
+ _glfw.x11.NET_WM_BYPASS_COMPOSITOR =
+ XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False);
+ _glfw.x11.MOTIF_WM_HINTS =
+ XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
+
+ return GLFW_TRUE;
+}
+
+// Retrieve system content scale via folklore heuristics
+//
+static void getSystemContentScale(float* xscale, float* yscale)
+{
+ // NOTE: Default to the display-wide DPI as we don't currently have a policy
+ // for which monitor a window is considered to be on
+ float xdpi = DisplayWidth(_glfw.x11.display, _glfw.x11.screen) *
+ 25.4f / DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
+ float ydpi = DisplayHeight(_glfw.x11.display, _glfw.x11.screen) *
+ 25.4f / DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
+
+ // NOTE: Basing the scale on Xft.dpi where available should provide the most
+ // consistent user experience (matches Qt, Gtk, etc), although not
+ // always the most accurate one
+ char* rms = XResourceManagerString(_glfw.x11.display);
+ if (rms)
+ {
+ XrmDatabase db = XrmGetStringDatabase(rms);
+ if (db)
+ {
+ XrmValue value;
+ char* type = NULL;
+
+ if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value))
+ {
+ if (type && strcmp(type, "String") == 0)
+ xdpi = ydpi = atof(value.addr);
+ }
+
+ XrmDestroyDatabase(db);
+ }
+ }
+
+ *xscale = xdpi / 96.f;
+ *yscale = ydpi / 96.f;
+}
+
+// Create a blank cursor for hidden and disabled cursor modes
+//
+static Cursor createHiddenCursor(void)
+{
+ unsigned char pixels[16 * 16 * 4] = { 0 };
+ GLFWimage image = { 16, 16, pixels };
+ return _glfwCreateCursorX11(&image, 0, 0);
+}
+
+// Create a helper window for IPC
+//
+static Window createHelperWindow(void)
+{
+ XSetWindowAttributes wa;
+ wa.event_mask = PropertyChangeMask;
+
+ return XCreateWindow(_glfw.x11.display, _glfw.x11.root,
+ 0, 0, 1, 1, 0, 0,
+ InputOnly,
+ DefaultVisual(_glfw.x11.display, _glfw.x11.screen),
+ CWEventMask, &wa);
+}
+
+// X error handler
+//
+static int errorHandler(Display *display, XErrorEvent* event)
+{
+ _glfw.x11.errorCode = event->error_code;
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Sets the X error handler callback
+//
+void _glfwGrabErrorHandlerX11(void)
+{
+ _glfw.x11.errorCode = Success;
+ XSetErrorHandler(errorHandler);
+}
+
+// Clears the X error handler callback
+//
+void _glfwReleaseErrorHandlerX11(void)
+{
+ // Synchronize to make sure all commands are processed
+ XSync(_glfw.x11.display, False);
+ XSetErrorHandler(NULL);
+}
+
+// Reports the specified error, appending information about the last X error
+//
+void _glfwInputErrorX11(int error, const char* message)
+{
+ char buffer[_GLFW_MESSAGE_SIZE];
+ XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
+ buffer, sizeof(buffer));
+
+ _glfwInputError(error, "%s: %s", message, buffer);
+}
+
+// Creates a native cursor object from the specified image and hotspot
+//
+Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
+{
+ int i;
+ Cursor cursor;
+
+ if (!_glfw.x11.xcursor.handle)
+ return None;
+
+ XcursorImage* native = XcursorImageCreate(image->width, image->height);
+ if (native == NULL)
+ return None;
+
+ native->xhot = xhot;
+ native->yhot = yhot;
+
+ unsigned char* source = (unsigned char*) image->pixels;
+ XcursorPixel* target = native->pixels;
+
+ for (i = 0; i < image->width * image->height; i++, target++, source += 4)
+ {
+ unsigned int alpha = source[3];
+
+ *target = (alpha << 24) |
+ ((unsigned char) ((source[0] * alpha) / 255) << 16) |
+ ((unsigned char) ((source[1] * alpha) / 255) << 8) |
+ ((unsigned char) ((source[2] * alpha) / 255) << 0);
+ }
+
+ cursor = XcursorImageLoadCursor(_glfw.x11.display, native);
+ XcursorImageDestroy(native);
+
+ return cursor;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformInit(void)
+{
+#if !defined(X_HAVE_UTF8_STRING)
+ // HACK: If the current locale is "C" and the Xlib UTF-8 functions are
+ // unavailable, apply the environment's locale in the hope that it's
+ // both available and not "C"
+ // This is done because the "C" locale breaks wide character input,
+ // which is what we fall back on when UTF-8 support is missing
+ if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
+ setlocale(LC_CTYPE, "");
+#endif
+
+ XInitThreads();
+ XrmInitialize();
+
+ _glfw.x11.display = XOpenDisplay(NULL);
+ if (!_glfw.x11.display)
+ {
+ const char* display = getenv("DISPLAY");
+ if (display)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to open display %s", display);
+ }
+ else
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: The DISPLAY environment variable is missing");
+ }
+
+ return GLFW_FALSE;
+ }
+
+ _glfw.x11.screen = DefaultScreen(_glfw.x11.display);
+ _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
+ _glfw.x11.context = XUniqueContext();
+
+ getSystemContentScale(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY);
+
+ if (!initExtensions())
+ return GLFW_FALSE;
+
+ _glfw.x11.helperWindowHandle = createHelperWindow();
+ _glfw.x11.hiddenCursorHandle = createHiddenCursor();
+
+ if (XSupportsLocale())
+ {
+ XSetLocaleModifiers("");
+
+ _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL);
+ if (_glfw.x11.im)
+ {
+ if (!hasUsableInputMethodStyle())
+ {
+ XCloseIM(_glfw.x11.im);
+ _glfw.x11.im = NULL;
+ }
+ }
+ }
+
+#if defined(__linux__)
+ if (!_glfwInitJoysticksLinux())
+ return GLFW_FALSE;
+#endif
+
+ _glfwInitTimerPOSIX();
+
+ _glfwPollMonitorsX11();
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformTerminate(void)
+{
+ if (_glfw.x11.helperWindowHandle)
+ {
+ if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
+ _glfw.x11.helperWindowHandle)
+ {
+ _glfwPushSelectionToManagerX11();
+ }
+
+ XDestroyWindow(_glfw.x11.display, _glfw.x11.helperWindowHandle);
+ _glfw.x11.helperWindowHandle = None;
+ }
+
+ if (_glfw.x11.hiddenCursorHandle)
+ {
+ XFreeCursor(_glfw.x11.display, _glfw.x11.hiddenCursorHandle);
+ _glfw.x11.hiddenCursorHandle = (Cursor) 0;
+ }
+
+ free(_glfw.x11.primarySelectionString);
+ free(_glfw.x11.clipboardString);
+
+ if (_glfw.x11.im)
+ {
+ XCloseIM(_glfw.x11.im);
+ _glfw.x11.im = NULL;
+ }
+
+ _glfwTerminateEGL();
+
+ if (_glfw.x11.display)
+ {
+ XCloseDisplay(_glfw.x11.display);
+ _glfw.x11.display = NULL;
+ }
+
+ if (_glfw.x11.x11xcb.handle)
+ {
+ dlclose(_glfw.x11.x11xcb.handle);
+ _glfw.x11.x11xcb.handle = NULL;
+ }
+
+ if (_glfw.x11.xcursor.handle)
+ {
+ dlclose(_glfw.x11.xcursor.handle);
+ _glfw.x11.xcursor.handle = NULL;
+ }
+
+ if (_glfw.x11.randr.handle)
+ {
+ dlclose(_glfw.x11.randr.handle);
+ _glfw.x11.randr.handle = NULL;
+ }
+
+ if (_glfw.x11.xinerama.handle)
+ {
+ dlclose(_glfw.x11.xinerama.handle);
+ _glfw.x11.xinerama.handle = NULL;
+ }
+
+ // NOTE: This needs to be done after XCloseDisplay, as libGL registers
+ // cleanup callbacks that get called by it
+ _glfwTerminateGLX();
+
+#if defined(__linux__)
+ _glfwTerminateJoysticksLinux();
+#endif
+}
+
+const char* _glfwPlatformGetVersionString(void)
+{
+ return _GLFW_VERSION_NUMBER " X11 GLX EGL"
+#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
+ " clock_gettime"
+#else
+ " gettimeofday"
+#endif
+#if defined(__linux__)
+ " evdev"
+#endif
+#if defined(_GLFW_BUILD_DLL)
+ " shared"
+#endif
+ ;
+}
+
diff --git a/src/external/glfw/src/x11_monitor.c b/src/external/glfw/src/x11_monitor.c
new file mode 100644
index 00000000..d68c5888
--- /dev/null
+++ b/src/external/glfw/src/x11_monitor.c
@@ -0,0 +1,510 @@
+//========================================================================
+// GLFW 3.3 X11 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+// Check whether the display mode should be included in enumeration
+//
+static GLFWbool modeIsGood(const XRRModeInfo* mi)
+{
+ return (mi->modeFlags & RR_Interlace) == 0;
+}
+
+// Calculates the refresh rate, in Hz, from the specified RandR mode info
+//
+static int calculateRefreshRate(const XRRModeInfo* mi)
+{
+ if (mi->hTotal && mi->vTotal)
+ return (int) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
+ else
+ return 0;
+}
+
+// Returns the mode info for a RandR mode XID
+//
+static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
+{
+ int i;
+
+ for (i = 0; i < sr->nmode; i++)
+ {
+ if (sr->modes[i].id == id)
+ return sr->modes + i;
+ }
+
+ return NULL;
+}
+
+// Convert RandR mode info to GLFW video mode
+//
+static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
+ const XRRCrtcInfo* ci)
+{
+ GLFWvidmode mode;
+
+ if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
+ {
+ mode.width = mi->height;
+ mode.height = mi->width;
+ }
+ else
+ {
+ mode.width = mi->width;
+ mode.height = mi->height;
+ }
+
+ mode.refreshRate = calculateRefreshRate(mi);
+
+ _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen),
+ &mode.redBits, &mode.greenBits, &mode.blueBits);
+
+ return mode;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Poll for changes in the set of connected monitors
+//
+void _glfwPollMonitorsX11(void)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ int i, j, disconnectedCount, screenCount = 0;
+ _GLFWmonitor** disconnected = NULL;
+ XineramaScreenInfo* screens = NULL;
+ XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
+ _glfw.x11.root);
+ RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
+ _glfw.x11.root);
+
+ if (_glfw.x11.xinerama.available)
+ screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
+
+ disconnectedCount = _glfw.monitorCount;
+ if (disconnectedCount)
+ {
+ disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
+ memcpy(disconnected,
+ _glfw.monitors,
+ _glfw.monitorCount * sizeof(_GLFWmonitor*));
+ }
+
+ for (i = 0; i < sr->noutput; i++)
+ {
+ int type, widthMM, heightMM;
+ XRROutputInfo* oi;
+ XRRCrtcInfo* ci;
+ _GLFWmonitor* monitor;
+
+ oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
+ if (oi->connection != RR_Connected || oi->crtc == None)
+ {
+ XRRFreeOutputInfo(oi);
+ continue;
+ }
+
+ for (j = 0; j < disconnectedCount; j++)
+ {
+ if (disconnected[j] &&
+ disconnected[j]->x11.output == sr->outputs[i])
+ {
+ disconnected[j] = NULL;
+ break;
+ }
+ }
+
+ if (j < disconnectedCount)
+ {
+ XRRFreeOutputInfo(oi);
+ continue;
+ }
+
+ ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
+ if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
+ {
+ widthMM = oi->mm_height;
+ heightMM = oi->mm_width;
+ }
+ else
+ {
+ widthMM = oi->mm_width;
+ heightMM = oi->mm_height;
+ }
+
+ monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
+ monitor->x11.output = sr->outputs[i];
+ monitor->x11.crtc = oi->crtc;
+
+ for (j = 0; j < screenCount; j++)
+ {
+ if (screens[j].x_org == ci->x &&
+ screens[j].y_org == ci->y &&
+ screens[j].width == ci->width &&
+ screens[j].height == ci->height)
+ {
+ monitor->x11.index = j;
+ break;
+ }
+ }
+
+ if (monitor->x11.output == primary)
+ type = _GLFW_INSERT_FIRST;
+ else
+ type = _GLFW_INSERT_LAST;
+
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, type);
+
+ XRRFreeOutputInfo(oi);
+ XRRFreeCrtcInfo(ci);
+ }
+
+ XRRFreeScreenResources(sr);
+
+ if (screens)
+ XFree(screens);
+
+ for (i = 0; i < disconnectedCount; i++)
+ {
+ if (disconnected[i])
+ _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
+ }
+
+ free(disconnected);
+ }
+
+ if (!_glfw.monitorCount)
+ {
+ const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
+ const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
+
+ _glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM),
+ GLFW_CONNECTED,
+ _GLFW_INSERT_FIRST);
+ }
+}
+
+// Set the current video mode for the specified monitor
+//
+GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ XRRScreenResources* sr;
+ XRRCrtcInfo* ci;
+ XRROutputInfo* oi;
+ GLFWvidmode current;
+ const GLFWvidmode* best;
+ RRMode native = None;
+ int i;
+
+ best = _glfwChooseVideoMode(monitor, desired);
+ _glfwPlatformGetVideoMode(monitor, &current);
+ if (_glfwCompareVideoModes(&current, best) == 0)
+ return GLFW_TRUE;
+
+ sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
+ ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
+ oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
+
+ for (i = 0; i < oi->nmode; i++)
+ {
+ const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
+ if (!modeIsGood(mi))
+ continue;
+
+ const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
+ if (_glfwCompareVideoModes(best, &mode) == 0)
+ {
+ native = mi->id;
+ break;
+ }
+ }
+
+ if (native)
+ {
+ if (monitor->x11.oldMode == None)
+ monitor->x11.oldMode = ci->mode;
+
+ XRRSetCrtcConfig(_glfw.x11.display,
+ sr, monitor->x11.crtc,
+ CurrentTime,
+ ci->x, ci->y,
+ native,
+ ci->rotation,
+ ci->outputs,
+ ci->noutput);
+ }
+
+ XRRFreeOutputInfo(oi);
+ XRRFreeCrtcInfo(ci);
+ XRRFreeScreenResources(sr);
+
+ if (!native)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Monitor mode list changed");
+ return GLFW_FALSE;
+ }
+ }
+
+ return GLFW_TRUE;
+}
+
+// Restore the saved (original) video mode for the specified monitor
+//
+void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ XRRScreenResources* sr;
+ XRRCrtcInfo* ci;
+
+ if (monitor->x11.oldMode == None)
+ return;
+
+ sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
+ ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
+
+ XRRSetCrtcConfig(_glfw.x11.display,
+ sr, monitor->x11.crtc,
+ CurrentTime,
+ ci->x, ci->y,
+ monitor->x11.oldMode,
+ ci->rotation,
+ ci->outputs,
+ ci->noutput);
+
+ XRRFreeCrtcInfo(ci);
+ XRRFreeScreenResources(sr);
+
+ monitor->x11.oldMode = None;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ XRRScreenResources* sr;
+ XRRCrtcInfo* ci;
+
+ sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
+ ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
+
+ if (xpos)
+ *xpos = ci->x;
+ if (ypos)
+ *ypos = ci->y;
+
+ XRRFreeCrtcInfo(ci);
+ XRRFreeScreenResources(sr);
+ }
+}
+
+void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = _glfw.x11.contentScaleX;
+ if (yscale)
+ *yscale = _glfw.x11.contentScaleY;
+}
+
+GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
+{
+ GLFWvidmode* result;
+
+ *count = 0;
+
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ int i, j;
+ XRRScreenResources* sr;
+ XRRCrtcInfo* ci;
+ XRROutputInfo* oi;
+
+ sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
+ ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
+ oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
+
+ result = calloc(oi->nmode, sizeof(GLFWvidmode));
+
+ for (i = 0; i < oi->nmode; i++)
+ {
+ const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
+ if (!modeIsGood(mi))
+ continue;
+
+ const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
+
+ for (j = 0; j < *count; j++)
+ {
+ if (_glfwCompareVideoModes(result + j, &mode) == 0)
+ break;
+ }
+
+ // Skip duplicate modes
+ if (j < *count)
+ continue;
+
+ (*count)++;
+ result[*count - 1] = mode;
+ }
+
+ XRRFreeOutputInfo(oi);
+ XRRFreeCrtcInfo(ci);
+ XRRFreeScreenResources(sr);
+ }
+ else
+ {
+ *count = 1;
+ result = calloc(1, sizeof(GLFWvidmode));
+ _glfwPlatformGetVideoMode(monitor, result);
+ }
+
+ return result;
+}
+
+void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
+ {
+ XRRScreenResources* sr;
+ XRRCrtcInfo* ci;
+
+ sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
+ ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
+
+ *mode = vidmodeFromModeInfo(getModeInfo(sr, ci->mode), ci);
+
+ XRRFreeCrtcInfo(ci);
+ XRRFreeScreenResources(sr);
+ }
+ else
+ {
+ mode->width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
+ mode->height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
+ mode->refreshRate = 0;
+
+ _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen),
+ &mode->redBits, &mode->greenBits, &mode->blueBits);
+ }
+}
+
+void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
+ {
+ const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display,
+ monitor->x11.crtc);
+ XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display,
+ monitor->x11.crtc);
+
+ _glfwAllocGammaArrays(ramp, size);
+
+ memcpy(ramp->red, gamma->red, size * sizeof(unsigned short));
+ memcpy(ramp->green, gamma->green, size * sizeof(unsigned short));
+ memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
+
+ XRRFreeGamma(gamma);
+ }
+ else if (_glfw.x11.vidmode.available)
+ {
+ int size;
+ XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size);
+
+ _glfwAllocGammaArrays(ramp, size);
+
+ XF86VidModeGetGammaRamp(_glfw.x11.display,
+ _glfw.x11.screen,
+ ramp->size, ramp->red, ramp->green, ramp->blue);
+ }
+}
+
+void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
+{
+ if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
+ {
+ if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Gamma ramp size must match current ramp size");
+ return;
+ }
+
+ XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size);
+
+ memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short));
+ memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short));
+ memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short));
+
+ XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
+ XRRFreeGamma(gamma);
+ }
+ else if (_glfw.x11.vidmode.available)
+ {
+ XF86VidModeSetGammaRamp(_glfw.x11.display,
+ _glfw.x11.screen,
+ ramp->size,
+ (unsigned short*) ramp->red,
+ (unsigned short*) ramp->green,
+ (unsigned short*) ramp->blue);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(None);
+ return monitor->x11.crtc;
+}
+
+GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
+{
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(None);
+ return monitor->x11.output;
+}
+
diff --git a/src/external/glfw/src/x11_platform.h b/src/external/glfw/src/x11_platform.h
new file mode 100644
index 00000000..7eba441d
--- /dev/null
+++ b/src/external/glfw/src/x11_platform.h
@@ -0,0 +1,442 @@
+//========================================================================
+// GLFW 3.3 X11 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include <unistd.h>
+#include <signal.h>
+#include <stdint.h>
+#include <dlfcn.h>
+
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <X11/Xcursor/Xcursor.h>
+
+// The XRandR extension provides mode setting and gamma control
+#include <X11/extensions/Xrandr.h>
+
+// The Xkb extension provides improved keyboard support
+#include <X11/XKBlib.h>
+
+// The Xinerama extension provides legacy monitor indices
+#include <X11/extensions/Xinerama.h>
+
+// The XInput extension provides raw mouse motion input
+#include <X11/extensions/XInput2.h>
+
+typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
+typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
+typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
+typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*);
+typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*);
+typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc);
+typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc);
+typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc);
+typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput);
+typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window);
+typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window);
+typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*);
+typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*);
+typedef void (* PFN_XRRSelectInput)(Display*,Window,int);
+typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int);
+typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*);
+typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
+#define XRRAllocGamma _glfw.x11.randr.AllocGamma
+#define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo
+#define XRRFreeGamma _glfw.x11.randr.FreeGamma
+#define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo
+#define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources
+#define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma
+#define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize
+#define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo
+#define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo
+#define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary
+#define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
+#define XRRQueryExtension _glfw.x11.randr.QueryExtension
+#define XRRQueryVersion _glfw.x11.randr.QueryVersion
+#define XRRSelectInput _glfw.x11.randr.SelectInput
+#define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig
+#define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma
+#define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration
+
+typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
+typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
+typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
+#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
+#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
+#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
+
+typedef Bool (* PFN_XineramaIsActive)(Display*);
+typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
+typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*);
+#define XineramaIsActive _glfw.x11.xinerama.IsActive
+#define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension
+#define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens
+
+typedef XID xcb_window_t;
+typedef XID xcb_visualid_t;
+typedef struct xcb_connection_t xcb_connection_t;
+typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*);
+#define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection
+
+typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*);
+typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
+typedef Bool (* PFN_XF86VidModeSetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
+typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*);
+#define XF86VidModeQueryExtension _glfw.x11.vidmode.QueryExtension
+#define XF86VidModeGetGammaRamp _glfw.x11.vidmode.GetGammaRamp
+#define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp
+#define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize
+
+typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*);
+typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
+#define XIQueryVersion _glfw.x11.xi.QueryVersion
+#define XISelectEvents _glfw.x11.xi.SelectEvents
+
+typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*);
+typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*);
+typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*);
+#define XRenderQueryExtension _glfw.x11.xrender.QueryExtension
+#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
+#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
+
+typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
+typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
+
+typedef struct VkXlibSurfaceCreateInfoKHR
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkXlibSurfaceCreateFlagsKHR flags;
+ Display* dpy;
+ Window window;
+} VkXlibSurfaceCreateInfoKHR;
+
+typedef struct VkXcbSurfaceCreateInfoKHR
+{
+ VkStructureType sType;
+ const void* pNext;
+ VkXcbSurfaceCreateFlagsKHR flags;
+ xcb_connection_t* connection;
+ xcb_window_t window;
+} VkXcbSurfaceCreateInfoKHR;
+
+typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID);
+typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
+typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
+
+#include "posix_thread.h"
+#include "posix_time.h"
+#include "xkb_unicode.h"
+#include "glx_context.h"
+#include "egl_context.h"
+#include "osmesa_context.h"
+#if defined(__linux__)
+#include "linux_joystick.h"
+#else
+#include "null_joystick.h"
+#endif
+
+#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
+#define _glfw_dlclose(handle) dlclose(handle)
+#define _glfw_dlsym(handle, name) dlsym(handle, name)
+
+#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle)
+#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
+
+#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
+#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
+#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11
+
+
+// X11-specific per-window data
+//
+typedef struct _GLFWwindowX11
+{
+ Colormap colormap;
+ Window handle;
+ XIC ic;
+
+ GLFWbool overrideRedirect;
+ GLFWbool iconified;
+ GLFWbool maximized;
+
+ // Whether the visual supports framebuffer transparency
+ GLFWbool transparent;
+
+ // Cached position and size used to filter out duplicate events
+ int width, height;
+ int xpos, ypos;
+
+ // The last received cursor position, regardless of source
+ int lastCursorPosX, lastCursorPosY;
+ // The last position the cursor was warped to by GLFW
+ int warpCursorPosX, warpCursorPosY;
+
+ // The time of the last KeyPress event
+ Time lastKeyTime;
+
+} _GLFWwindowX11;
+
+// X11-specific global data
+//
+typedef struct _GLFWlibraryX11
+{
+ Display* display;
+ int screen;
+ Window root;
+
+ // System content scale
+ float contentScaleX, contentScaleY;
+ // Helper window for IPC
+ Window helperWindowHandle;
+ // Invisible cursor for hidden cursor mode
+ Cursor hiddenCursorHandle;
+ // Context for mapping window XIDs to _GLFWwindow pointers
+ XContext context;
+ // XIM input method
+ XIM im;
+ // Most recent error code received by X error handler
+ int errorCode;
+ // Primary selection string (while the primary selection is owned)
+ char* primarySelectionString;
+ // Clipboard string (while the selection is owned)
+ char* clipboardString;
+ // Key name string
+ char keyName[5];
+ // X11 keycode to GLFW key LUT
+ short int keycodes[256];
+ // GLFW key to X11 keycode LUT
+ short int scancodes[GLFW_KEY_LAST + 1];
+ // Where to place the cursor when re-enabled
+ double restoreCursorPosX, restoreCursorPosY;
+ // The window whose disabled cursor mode is active
+ _GLFWwindow* disabledCursorWindow;
+
+ // Window manager atoms
+ Atom WM_PROTOCOLS;
+ Atom WM_STATE;
+ Atom WM_DELETE_WINDOW;
+ Atom NET_WM_NAME;
+ Atom NET_WM_ICON_NAME;
+ Atom NET_WM_ICON;
+ Atom NET_WM_PID;
+ Atom NET_WM_PING;
+ Atom NET_WM_WINDOW_TYPE;
+ Atom NET_WM_WINDOW_TYPE_NORMAL;
+ Atom NET_WM_STATE;
+ Atom NET_WM_STATE_ABOVE;
+ Atom NET_WM_STATE_FULLSCREEN;
+ Atom NET_WM_STATE_MAXIMIZED_VERT;
+ Atom NET_WM_STATE_MAXIMIZED_HORZ;
+ Atom NET_WM_STATE_DEMANDS_ATTENTION;
+ Atom NET_WM_BYPASS_COMPOSITOR;
+ Atom NET_WM_FULLSCREEN_MONITORS;
+ Atom NET_ACTIVE_WINDOW;
+ Atom NET_FRAME_EXTENTS;
+ Atom NET_REQUEST_FRAME_EXTENTS;
+ Atom MOTIF_WM_HINTS;
+
+ // Xdnd (drag and drop) atoms
+ Atom XdndAware;
+ Atom XdndEnter;
+ Atom XdndPosition;
+ Atom XdndStatus;
+ Atom XdndActionCopy;
+ Atom XdndDrop;
+ Atom XdndFinished;
+ Atom XdndSelection;
+ Atom XdndTypeList;
+ Atom text_uri_list;
+
+ // Selection (clipboard) atoms
+ Atom TARGETS;
+ Atom MULTIPLE;
+ Atom INCR;
+ Atom CLIPBOARD;
+ Atom PRIMARY;
+ Atom CLIPBOARD_MANAGER;
+ Atom SAVE_TARGETS;
+ Atom NULL_;
+ Atom UTF8_STRING;
+ Atom COMPOUND_STRING;
+ Atom ATOM_PAIR;
+ Atom GLFW_SELECTION;
+
+ struct {
+ GLFWbool available;
+ void* handle;
+ int eventBase;
+ int errorBase;
+ int major;
+ int minor;
+ GLFWbool gammaBroken;
+ GLFWbool monitorBroken;
+ PFN_XRRAllocGamma AllocGamma;
+ PFN_XRRFreeCrtcInfo FreeCrtcInfo;
+ PFN_XRRFreeGamma FreeGamma;
+ PFN_XRRFreeOutputInfo FreeOutputInfo;
+ PFN_XRRFreeScreenResources FreeScreenResources;
+ PFN_XRRGetCrtcGamma GetCrtcGamma;
+ PFN_XRRGetCrtcGammaSize GetCrtcGammaSize;
+ PFN_XRRGetCrtcInfo GetCrtcInfo;
+ PFN_XRRGetOutputInfo GetOutputInfo;
+ PFN_XRRGetOutputPrimary GetOutputPrimary;
+ PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent;
+ PFN_XRRQueryExtension QueryExtension;
+ PFN_XRRQueryVersion QueryVersion;
+ PFN_XRRSelectInput SelectInput;
+ PFN_XRRSetCrtcConfig SetCrtcConfig;
+ PFN_XRRSetCrtcGamma SetCrtcGamma;
+ PFN_XRRUpdateConfiguration UpdateConfiguration;
+ } randr;
+
+ struct {
+ GLFWbool available;
+ GLFWbool detectable;
+ int majorOpcode;
+ int eventBase;
+ int errorBase;
+ int major;
+ int minor;
+ } xkb;
+
+ struct {
+ int count;
+ int timeout;
+ int interval;
+ int blanking;
+ int exposure;
+ } saver;
+
+ struct {
+ int version;
+ Window source;
+ Atom format;
+ } xdnd;
+
+ struct {
+ void* handle;
+ PFN_XcursorImageCreate ImageCreate;
+ PFN_XcursorImageDestroy ImageDestroy;
+ PFN_XcursorImageLoadCursor ImageLoadCursor;
+ } xcursor;
+
+ struct {
+ GLFWbool available;
+ void* handle;
+ int major;
+ int minor;
+ PFN_XineramaIsActive IsActive;
+ PFN_XineramaQueryExtension QueryExtension;
+ PFN_XineramaQueryScreens QueryScreens;
+ } xinerama;
+
+ struct {
+ void* handle;
+ PFN_XGetXCBConnection GetXCBConnection;
+ } x11xcb;
+
+ struct {
+ GLFWbool available;
+ void* handle;
+ int eventBase;
+ int errorBase;
+ PFN_XF86VidModeQueryExtension QueryExtension;
+ PFN_XF86VidModeGetGammaRamp GetGammaRamp;
+ PFN_XF86VidModeSetGammaRamp SetGammaRamp;
+ PFN_XF86VidModeGetGammaRampSize GetGammaRampSize;
+ } vidmode;
+
+ struct {
+ GLFWbool available;
+ void* handle;
+ int majorOpcode;
+ int eventBase;
+ int errorBase;
+ int major;
+ int minor;
+ PFN_XIQueryVersion QueryVersion;
+ PFN_XISelectEvents SelectEvents;
+ } xi;
+
+ struct {
+ GLFWbool available;
+ void* handle;
+ int major;
+ int minor;
+ int eventBase;
+ int errorBase;
+ PFN_XRenderQueryExtension QueryExtension;
+ PFN_XRenderQueryVersion QueryVersion;
+ PFN_XRenderFindVisualFormat FindVisualFormat;
+ } xrender;
+
+} _GLFWlibraryX11;
+
+// X11-specific per-monitor data
+//
+typedef struct _GLFWmonitorX11
+{
+ RROutput output;
+ RRCrtc crtc;
+ RRMode oldMode;
+
+ // Index of corresponding Xinerama screen,
+ // for EWMH full screen window placement
+ int index;
+
+} _GLFWmonitorX11;
+
+// X11-specific per-cursor data
+//
+typedef struct _GLFWcursorX11
+{
+ Cursor handle;
+
+} _GLFWcursorX11;
+
+
+void _glfwPollMonitorsX11(void);
+GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
+void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
+
+Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot);
+
+unsigned long _glfwGetWindowPropertyX11(Window window,
+ Atom property,
+ Atom type,
+ unsigned char** value);
+GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
+
+void _glfwGrabErrorHandlerX11(void);
+void _glfwReleaseErrorHandlerX11(void);
+void _glfwInputErrorX11(int error, const char* message);
+
+void _glfwPushSelectionToManagerX11(void);
+
diff --git a/src/external/glfw/src/x11_window.c b/src/external/glfw/src/x11_window.c
new file mode 100644
index 00000000..c89d2ec5
--- /dev/null
+++ b/src/external/glfw/src/x11_window.c
@@ -0,0 +1,2991 @@
+//========================================================================
+// GLFW 3.3 X11 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include <X11/cursorfont.h>
+#include <X11/Xmd.h>
+
+#include <sys/select.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <assert.h>
+
+// Action for EWMH client messages
+#define _NET_WM_STATE_REMOVE 0
+#define _NET_WM_STATE_ADD 1
+#define _NET_WM_STATE_TOGGLE 2
+
+// Additional mouse button names for XButtonEvent
+#define Button6 6
+#define Button7 7
+
+#define _GLFW_XDND_VERSION 5
+
+
+// Wait for data to arrive using select
+// This avoids blocking other threads via the per-display Xlib lock that also
+// covers GLX functions
+//
+static GLFWbool waitForEvent(double* timeout)
+{
+ fd_set fds;
+ const int fd = ConnectionNumber(_glfw.x11.display);
+ int count = fd + 1;
+
+#if defined(__linux__)
+ if (_glfw.linjs.inotify > fd)
+ count = _glfw.linjs.inotify + 1;
+#endif
+ for (;;)
+ {
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+#if defined(__linux__)
+ if (_glfw.linjs.inotify > 0)
+ FD_SET(_glfw.linjs.inotify, &fds);
+#endif
+
+ if (timeout)
+ {
+ const long seconds = (long) *timeout;
+ const long microseconds = (long) ((*timeout - seconds) * 1e6);
+ struct timeval tv = { seconds, microseconds };
+ const uint64_t base = _glfwPlatformGetTimerValue();
+
+ const int result = select(count, &fds, NULL, NULL, &tv);
+ const int error = errno;
+
+ *timeout -= (_glfwPlatformGetTimerValue() - base) /
+ (double) _glfwPlatformGetTimerFrequency();
+
+ if (result > 0)
+ return GLFW_TRUE;
+ if ((result == -1 && error == EINTR) || *timeout <= 0.0)
+ return GLFW_FALSE;
+ }
+ else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
+ return GLFW_TRUE;
+ }
+}
+
+// Waits until a VisibilityNotify event arrives for the specified window or the
+// timeout period elapses (ICCCM section 4.2.2)
+//
+static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
+{
+ XEvent dummy;
+ double timeout = 0.1;
+
+ while (!XCheckTypedWindowEvent(_glfw.x11.display,
+ window->x11.handle,
+ VisibilityNotify,
+ &dummy))
+ {
+ if (!waitForEvent(&timeout))
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+// Returns whether the window is iconified
+//
+static int getWindowState(_GLFWwindow* window)
+{
+ int result = WithdrawnState;
+ struct {
+ CARD32 state;
+ Window icon;
+ } *state = NULL;
+
+ if (_glfwGetWindowPropertyX11(window->x11.handle,
+ _glfw.x11.WM_STATE,
+ _glfw.x11.WM_STATE,
+ (unsigned char**) &state) >= 2)
+ {
+ result = state->state;
+ }
+
+ if (state)
+ XFree(state);
+
+ return result;
+}
+
+// Returns whether the event is a selection event
+//
+static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
+{
+ if (event->xany.window != _glfw.x11.helperWindowHandle)
+ return False;
+
+ return event->type == SelectionRequest ||
+ event->type == SelectionNotify ||
+ event->type == SelectionClear;
+}
+
+// Returns whether it is a _NET_FRAME_EXTENTS event for the specified window
+//
+static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
+{
+ _GLFWwindow* window = (_GLFWwindow*) pointer;
+ return event->type == PropertyNotify &&
+ event->xproperty.state == PropertyNewValue &&
+ event->xproperty.window == window->x11.handle &&
+ event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;
+}
+
+// Returns whether it is a property event for the specified selection transfer
+//
+static Bool isSelPropNewValueNotify(Display* display, XEvent* event, XPointer pointer)
+{
+ XEvent* notification = (XEvent*) pointer;
+ return event->type == PropertyNotify &&
+ event->xproperty.state == PropertyNewValue &&
+ event->xproperty.window == notification->xselection.requestor &&
+ event->xproperty.atom == notification->xselection.property;
+}
+
+// Translates a GLFW standard cursor to a font cursor shape
+//
+static int translateCursorShape(int shape)
+{
+ switch (shape)
+ {
+ case GLFW_ARROW_CURSOR:
+ return XC_left_ptr;
+ case GLFW_IBEAM_CURSOR:
+ return XC_xterm;
+ case GLFW_CROSSHAIR_CURSOR:
+ return XC_crosshair;
+ case GLFW_HAND_CURSOR:
+ return XC_hand1;
+ case GLFW_HRESIZE_CURSOR:
+ return XC_sb_h_double_arrow;
+ case GLFW_VRESIZE_CURSOR:
+ return XC_sb_v_double_arrow;
+ }
+
+ return 0;
+}
+
+// Translates an X event modifier state mask
+//
+static int translateState(int state)
+{
+ int mods = 0;
+
+ if (state & ShiftMask)
+ mods |= GLFW_MOD_SHIFT;
+ if (state & ControlMask)
+ mods |= GLFW_MOD_CONTROL;
+ if (state & Mod1Mask)
+ mods |= GLFW_MOD_ALT;
+ if (state & Mod4Mask)
+ mods |= GLFW_MOD_SUPER;
+
+ return mods;
+}
+
+// Translates an X11 key code to a GLFW key token
+//
+static int translateKey(int scancode)
+{
+ // Use the pre-filled LUT (see createKeyTables() in x11_init.c)
+ if (scancode < 0 || scancode > 255)
+ return GLFW_KEY_UNKNOWN;
+
+ return _glfw.x11.keycodes[scancode];
+}
+
+// Return the GLFW window corresponding to the specified X11 window
+//
+static _GLFWwindow* findWindowByHandle(Window handle)
+{
+ _GLFWwindow* window;
+
+ if (XFindContext(_glfw.x11.display,
+ handle,
+ _glfw.x11.context,
+ (XPointer*) &window) != 0)
+ {
+ return NULL;
+ }
+
+ return window;
+}
+
+// Sends an EWMH or ICCCM event to the window manager
+//
+static void sendEventToWM(_GLFWwindow* window, Atom type,
+ long a, long b, long c, long d, long e)
+{
+ XEvent event;
+ memset(&event, 0, sizeof(event));
+
+ event.type = ClientMessage;
+ event.xclient.window = window->x11.handle;
+ event.xclient.format = 32; // Data is 32-bit longs
+ event.xclient.message_type = type;
+ event.xclient.data.l[0] = a;
+ event.xclient.data.l[1] = b;
+ event.xclient.data.l[2] = c;
+ event.xclient.data.l[3] = d;
+ event.xclient.data.l[4] = e;
+
+ XSendEvent(_glfw.x11.display, _glfw.x11.root,
+ False,
+ SubstructureNotifyMask | SubstructureRedirectMask,
+ &event);
+}
+
+// Updates the normal hints according to the window settings
+//
+static void updateNormalHints(_GLFWwindow* window, int width, int height)
+{
+ XSizeHints* hints = XAllocSizeHints();
+
+ if (!window->monitor)
+ {
+ if (window->resizable)
+ {
+ if (window->minwidth != GLFW_DONT_CARE &&
+ window->minheight != GLFW_DONT_CARE)
+ {
+ hints->flags |= PMinSize;
+ hints->min_width = window->minwidth;
+ hints->min_height = window->minheight;
+ }
+
+ if (window->maxwidth != GLFW_DONT_CARE &&
+ window->maxheight != GLFW_DONT_CARE)
+ {
+ hints->flags |= PMaxSize;
+ hints->max_width = window->maxwidth;
+ hints->max_height = window->maxheight;
+ }
+
+ if (window->numer != GLFW_DONT_CARE &&
+ window->denom != GLFW_DONT_CARE)
+ {
+ hints->flags |= PAspect;
+ hints->min_aspect.x = hints->max_aspect.x = window->numer;
+ hints->min_aspect.y = hints->max_aspect.y = window->denom;
+ }
+ }
+ else
+ {
+ hints->flags |= (PMinSize | PMaxSize);
+ hints->min_width = hints->max_width = width;
+ hints->min_height = hints->max_height = height;
+ }
+ }
+
+ hints->flags |= PWinGravity;
+ hints->win_gravity = StaticGravity;
+
+ XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
+ XFree(hints);
+}
+
+// Updates the full screen status of the window
+//
+static void updateWindowMode(_GLFWwindow* window)
+{
+ if (window->monitor)
+ {
+ if (_glfw.x11.xinerama.available &&
+ _glfw.x11.NET_WM_FULLSCREEN_MONITORS)
+ {
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_FULLSCREEN_MONITORS,
+ window->monitor->x11.index,
+ window->monitor->x11.index,
+ window->monitor->x11.index,
+ window->monitor->x11.index,
+ 0);
+ }
+
+ if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
+ {
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_STATE,
+ _NET_WM_STATE_ADD,
+ _glfw.x11.NET_WM_STATE_FULLSCREEN,
+ 0, 1, 0);
+ }
+ else
+ {
+ // This is the butcher's way of removing window decorations
+ // Setting the override-redirect attribute on a window makes the
+ // window manager ignore the window completely (ICCCM, section 4)
+ // The good thing is that this makes undecorated full screen windows
+ // easy to do; the bad thing is that we have to do everything
+ // manually and some things (like iconify/restore) won't work at
+ // all, as those are tasks usually performed by the window manager
+
+ XSetWindowAttributes attributes;
+ attributes.override_redirect = True;
+ XChangeWindowAttributes(_glfw.x11.display,
+ window->x11.handle,
+ CWOverrideRedirect,
+ &attributes);
+
+ window->x11.overrideRedirect = GLFW_TRUE;
+ }
+
+ // Enable compositor bypass
+ if (!window->x11.transparent)
+ {
+ const unsigned long value = 1;
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char*) &value, 1);
+ }
+ }
+ else
+ {
+ if (_glfw.x11.xinerama.available &&
+ _glfw.x11.NET_WM_FULLSCREEN_MONITORS)
+ {
+ XDeleteProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_FULLSCREEN_MONITORS);
+ }
+
+ if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
+ {
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_STATE,
+ _NET_WM_STATE_REMOVE,
+ _glfw.x11.NET_WM_STATE_FULLSCREEN,
+ 0, 1, 0);
+ }
+ else
+ {
+ XSetWindowAttributes attributes;
+ attributes.override_redirect = False;
+ XChangeWindowAttributes(_glfw.x11.display,
+ window->x11.handle,
+ CWOverrideRedirect,
+ &attributes);
+
+ window->x11.overrideRedirect = GLFW_FALSE;
+ }
+
+ // Disable compositor bypass
+ if (!window->x11.transparent)
+ {
+ XDeleteProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_BYPASS_COMPOSITOR);
+ }
+ }
+}
+
+// Splits and translates a text/uri-list into separate file paths
+// NOTE: This function destroys the provided string
+//
+static char** parseUriList(char* text, int* count)
+{
+ const char* prefix = "file://";
+ char** paths = NULL;
+ char* line;
+
+ *count = 0;
+
+ while ((line = strtok(text, "\r\n")))
+ {
+ text = NULL;
+
+ if (line[0] == '#')
+ continue;
+
+ if (strncmp(line, prefix, strlen(prefix)) == 0)
+ {
+ line += strlen(prefix);
+ // TODO: Validate hostname
+ while (*line != '/')
+ line++;
+ }
+
+ (*count)++;
+
+ char* path = calloc(strlen(line) + 1, 1);
+ paths = realloc(paths, *count * sizeof(char*));
+ paths[*count - 1] = path;
+
+ while (*line)
+ {
+ if (line[0] == '%' && line[1] && line[2])
+ {
+ const char digits[3] = { line[1], line[2], '\0' };
+ *path = strtol(digits, NULL, 16);
+ line += 2;
+ }
+ else
+ *path = *line;
+
+ path++;
+ line++;
+ }
+ }
+
+ return paths;
+}
+
+// Encode a Unicode code point to a UTF-8 stream
+// Based on cutef8 by Jeff Bezanson (Public Domain)
+//
+static size_t encodeUTF8(char* s, unsigned int ch)
+{
+ size_t count = 0;
+
+ if (ch < 0x80)
+ s[count++] = (char) ch;
+ else if (ch < 0x800)
+ {
+ s[count++] = (ch >> 6) | 0xc0;
+ s[count++] = (ch & 0x3f) | 0x80;
+ }
+ else if (ch < 0x10000)
+ {
+ s[count++] = (ch >> 12) | 0xe0;
+ s[count++] = ((ch >> 6) & 0x3f) | 0x80;
+ s[count++] = (ch & 0x3f) | 0x80;
+ }
+ else if (ch < 0x110000)
+ {
+ s[count++] = (ch >> 18) | 0xf0;
+ s[count++] = ((ch >> 12) & 0x3f) | 0x80;
+ s[count++] = ((ch >> 6) & 0x3f) | 0x80;
+ s[count++] = (ch & 0x3f) | 0x80;
+ }
+
+ return count;
+}
+
+// Decode a Unicode code point from a UTF-8 stream
+// Based on cutef8 by Jeff Bezanson (Public Domain)
+//
+#if defined(X_HAVE_UTF8_STRING)
+static unsigned int decodeUTF8(const char** s)
+{
+ unsigned int ch = 0, count = 0;
+ static const unsigned int offsets[] =
+ {
+ 0x00000000u, 0x00003080u, 0x000e2080u,
+ 0x03c82080u, 0xfa082080u, 0x82082080u
+ };
+
+ do
+ {
+ ch = (ch << 6) + (unsigned char) **s;
+ (*s)++;
+ count++;
+ } while ((**s & 0xc0) == 0x80);
+
+ assert(count <= 6);
+ return ch - offsets[count - 1];
+}
+#endif /*X_HAVE_UTF8_STRING*/
+
+// Convert the specified Latin-1 string to UTF-8
+//
+static char* convertLatin1toUTF8(const char* source)
+{
+ size_t size = 1;
+ const char* sp;
+
+ for (sp = source; *sp; sp++)
+ size += (*sp & 0x80) ? 2 : 1;
+
+ char* target = calloc(size, 1);
+ char* tp = target;
+
+ for (sp = source; *sp; sp++)
+ tp += encodeUTF8(tp, *sp);
+
+ return target;
+}
+
+// Centers the cursor over the window client area
+//
+static void centerCursor(_GLFWwindow* window)
+{
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
+}
+
+// Updates the cursor image according to its cursor mode
+//
+static void updateCursorImage(_GLFWwindow* window)
+{
+ if (window->cursorMode == GLFW_CURSOR_NORMAL)
+ {
+ if (window->cursor)
+ {
+ XDefineCursor(_glfw.x11.display, window->x11.handle,
+ window->cursor->x11.handle);
+ }
+ else
+ XUndefineCursor(_glfw.x11.display, window->x11.handle);
+ }
+ else
+ {
+ XDefineCursor(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.hiddenCursorHandle);
+ }
+}
+
+// Create the X11 window (and its colormap)
+//
+static GLFWbool createNativeWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ Visual* visual, int depth)
+{
+ // Create a colormap based on the visual used by the current context
+ window->x11.colormap = XCreateColormap(_glfw.x11.display,
+ _glfw.x11.root,
+ visual,
+ AllocNone);
+
+ window->x11.transparent = _glfwIsVisualTransparentX11(visual);
+
+ // Create the actual window
+ {
+ XSetWindowAttributes wa;
+ const unsigned long wamask = CWBorderPixel | CWColormap | CWEventMask;
+
+ wa.colormap = window->x11.colormap;
+ wa.border_pixel = 0;
+ wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
+ ExposureMask | FocusChangeMask | VisibilityChangeMask |
+ EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
+
+ _glfwGrabErrorHandlerX11();
+
+ window->x11.handle = XCreateWindow(_glfw.x11.display,
+ _glfw.x11.root,
+ 0, 0,
+ wndconfig->width, wndconfig->height,
+ 0, // Border width
+ depth, // Color depth
+ InputOutput,
+ visual,
+ wamask,
+ &wa);
+
+ _glfwReleaseErrorHandlerX11();
+
+ if (!window->x11.handle)
+ {
+ _glfwInputErrorX11(GLFW_PLATFORM_ERROR,
+ "X11: Failed to create window");
+ return GLFW_FALSE;
+ }
+
+ XSaveContext(_glfw.x11.display,
+ window->x11.handle,
+ _glfw.x11.context,
+ (XPointer) window);
+ }
+
+ if (!wndconfig->decorated)
+ _glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
+
+ if (_glfw.x11.NET_WM_STATE && !window->monitor)
+ {
+ Atom states[3];
+ int count = 0;
+
+ if (wndconfig->floating)
+ {
+ if (_glfw.x11.NET_WM_STATE_ABOVE)
+ states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;
+ }
+
+ if (wndconfig->maximized)
+ {
+ if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
+ {
+ states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
+ states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
+ window->x11.maximized = GLFW_TRUE;
+ }
+ }
+
+ if (count)
+ {
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*) &states, count);
+ }
+ }
+
+ // Declare the WM protocols supported by GLFW
+ {
+ Atom protocols[] =
+ {
+ _glfw.x11.WM_DELETE_WINDOW,
+ _glfw.x11.NET_WM_PING
+ };
+
+ XSetWMProtocols(_glfw.x11.display, window->x11.handle,
+ protocols, sizeof(protocols) / sizeof(Atom));
+ }
+
+ // Declare our PID
+ {
+ const long pid = getpid();
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_PID, XA_CARDINAL, 32,
+ PropModeReplace,
+ (unsigned char*) &pid, 1);
+ }
+
+ if (_glfw.x11.NET_WM_WINDOW_TYPE && _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL)
+ {
+ Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*) &type, 1);
+ }
+
+ // Set ICCCM WM_HINTS property
+ {
+ XWMHints* hints = XAllocWMHints();
+ if (!hints)
+ {
+ _glfwInputError(GLFW_OUT_OF_MEMORY,
+ "X11: Failed to allocate WM hints");
+ return GLFW_FALSE;
+ }
+
+ hints->flags = StateHint;
+ hints->initial_state = NormalState;
+
+ XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
+ XFree(hints);
+ }
+
+ updateNormalHints(window, wndconfig->width, wndconfig->height);
+
+ // Set ICCCM WM_CLASS property
+ {
+ XClassHint* hint = XAllocClassHint();
+
+ if (strlen(_glfw.hints.init.x11.className) &&
+ strlen(_glfw.hints.init.x11.classClass))
+ {
+ hint->res_name = (char*) _glfw.hints.init.x11.className;
+ hint->res_class = (char*) _glfw.hints.init.x11.classClass;
+ }
+ else if (strlen(wndconfig->title))
+ {
+ hint->res_name = (char*) wndconfig->title;
+ hint->res_class = (char*) wndconfig->title;
+ }
+ else
+ {
+ hint->res_name = (char*) "glfw-application";
+ hint->res_class = (char*) "GLFW-Application";
+ }
+
+ XSetClassHint(_glfw.x11.display, window->x11.handle, hint);
+ XFree(hint);
+ }
+
+ // Announce support for Xdnd (drag and drop)
+ {
+ const Atom version = _GLFW_XDND_VERSION;
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.XdndAware, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*) &version, 1);
+ }
+
+ _glfwPlatformSetWindowTitle(window, wndconfig->title);
+
+ if (_glfw.x11.im)
+ {
+ window->x11.ic = XCreateIC(_glfw.x11.im,
+ XNInputStyle,
+ XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow,
+ window->x11.handle,
+ XNFocusWindow,
+ window->x11.handle,
+ NULL);
+ }
+
+ _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
+ _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
+
+ return GLFW_TRUE;
+}
+
+// Set the specified property to the selection converted to the requested target
+//
+static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
+{
+ int i;
+ char* selectionString = NULL;
+ const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
+ const int formatCount = sizeof(formats) / sizeof(formats[0]);
+
+ if (request->selection == _glfw.x11.PRIMARY)
+ selectionString = _glfw.x11.primarySelectionString;
+ else
+ selectionString = _glfw.x11.clipboardString;
+
+ if (request->property == None)
+ {
+ // The requester is a legacy client (ICCCM section 2.2)
+ // We don't support legacy clients, so fail here
+ return None;
+ }
+
+ if (request->target == _glfw.x11.TARGETS)
+ {
+ // The list of supported targets was requested
+
+ const Atom targets[] = { _glfw.x11.TARGETS,
+ _glfw.x11.MULTIPLE,
+ _glfw.x11.UTF8_STRING,
+ XA_STRING };
+
+ XChangeProperty(_glfw.x11.display,
+ request->requestor,
+ request->property,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char*) targets,
+ sizeof(targets) / sizeof(targets[0]));
+
+ return request->property;
+ }
+
+ if (request->target == _glfw.x11.MULTIPLE)
+ {
+ // Multiple conversions were requested
+
+ Atom* targets;
+ unsigned long i, count;
+
+ count = _glfwGetWindowPropertyX11(request->requestor,
+ request->property,
+ _glfw.x11.ATOM_PAIR,
+ (unsigned char**) &targets);
+
+ for (i = 0; i < count; i += 2)
+ {
+ int j;
+
+ for (j = 0; j < formatCount; j++)
+ {
+ if (targets[i] == formats[j])
+ break;
+ }
+
+ if (j < formatCount)
+ {
+ XChangeProperty(_glfw.x11.display,
+ request->requestor,
+ targets[i + 1],
+ targets[i],
+ 8,
+ PropModeReplace,
+ (unsigned char *) selectionString,
+ strlen(selectionString));
+ }
+ else
+ targets[i + 1] = None;
+ }
+
+ XChangeProperty(_glfw.x11.display,
+ request->requestor,
+ request->property,
+ _glfw.x11.ATOM_PAIR,
+ 32,
+ PropModeReplace,
+ (unsigned char*) targets,
+ count);
+
+ XFree(targets);
+
+ return request->property;
+ }
+
+ if (request->target == _glfw.x11.SAVE_TARGETS)
+ {
+ // The request is a check whether we support SAVE_TARGETS
+ // It should be handled as a no-op side effect target
+
+ XChangeProperty(_glfw.x11.display,
+ request->requestor,
+ request->property,
+ _glfw.x11.NULL_,
+ 32,
+ PropModeReplace,
+ NULL,
+ 0);
+
+ return request->property;
+ }
+
+ // Conversion to a data target was requested
+
+ for (i = 0; i < formatCount; i++)
+ {
+ if (request->target == formats[i])
+ {
+ // The requested target is one we support
+
+ XChangeProperty(_glfw.x11.display,
+ request->requestor,
+ request->property,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char *) selectionString,
+ strlen(selectionString));
+
+ return request->property;
+ }
+ }
+
+ // The requested target is not supported
+
+ return None;
+}
+
+static void handleSelectionClear(XEvent* event)
+{
+ if (event->xselectionclear.selection == _glfw.x11.PRIMARY)
+ {
+ free(_glfw.x11.primarySelectionString);
+ _glfw.x11.primarySelectionString = NULL;
+ }
+ else
+ {
+ free(_glfw.x11.clipboardString);
+ _glfw.x11.clipboardString = NULL;
+ }
+}
+
+static void handleSelectionRequest(XEvent* event)
+{
+ const XSelectionRequestEvent* request = &event->xselectionrequest;
+
+ XEvent reply;
+ memset(&reply, 0, sizeof(reply));
+
+ reply.xselection.property = writeTargetToProperty(request);
+ reply.xselection.type = SelectionNotify;
+ reply.xselection.display = request->display;
+ reply.xselection.requestor = request->requestor;
+ reply.xselection.selection = request->selection;
+ reply.xselection.target = request->target;
+ reply.xselection.time = request->time;
+
+ XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply);
+}
+
+static const char* getSelectionString(Atom selection)
+{
+ size_t i;
+ char** selectionString = NULL;
+ const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
+ const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
+
+ if (selection == _glfw.x11.PRIMARY)
+ selectionString = &_glfw.x11.primarySelectionString;
+ else
+ selectionString = &_glfw.x11.clipboardString;
+
+ if (XGetSelectionOwner(_glfw.x11.display, selection) ==
+ _glfw.x11.helperWindowHandle)
+ {
+ // Instead of doing a large number of X round-trips just to put this
+ // string into a window property and then read it back, just return it
+ return *selectionString;
+ }
+
+ free(*selectionString);
+ *selectionString = NULL;
+
+ for (i = 0; i < targetCount; i++)
+ {
+ char* data;
+ Atom actualType;
+ int actualFormat;
+ unsigned long itemCount, bytesAfter;
+ XEvent notification, dummy;
+
+ XConvertSelection(_glfw.x11.display,
+ selection,
+ targets[i],
+ _glfw.x11.GLFW_SELECTION,
+ _glfw.x11.helperWindowHandle,
+ CurrentTime);
+
+ while (!XCheckTypedWindowEvent(_glfw.x11.display,
+ _glfw.x11.helperWindowHandle,
+ SelectionNotify,
+ &notification))
+ {
+ waitForEvent(NULL);
+ }
+
+ if (notification.xselection.property == None)
+ continue;
+
+ XCheckIfEvent(_glfw.x11.display,
+ &dummy,
+ isSelPropNewValueNotify,
+ (XPointer) &notification);
+
+ XGetWindowProperty(_glfw.x11.display,
+ notification.xselection.requestor,
+ notification.xselection.property,
+ 0,
+ LONG_MAX,
+ True,
+ AnyPropertyType,
+ &actualType,
+ &actualFormat,
+ &itemCount,
+ &bytesAfter,
+ (unsigned char**) &data);
+
+ if (actualType == _glfw.x11.INCR)
+ {
+ size_t size = 1;
+ char* string = NULL;
+
+ for (;;)
+ {
+ while (!XCheckIfEvent(_glfw.x11.display,
+ &dummy,
+ isSelPropNewValueNotify,
+ (XPointer) &notification))
+ {
+ waitForEvent(NULL);
+ }
+
+ XFree(data);
+ XGetWindowProperty(_glfw.x11.display,
+ notification.xselection.requestor,
+ notification.xselection.property,
+ 0,
+ LONG_MAX,
+ True,
+ AnyPropertyType,
+ &actualType,
+ &actualFormat,
+ &itemCount,
+ &bytesAfter,
+ (unsigned char**) &data);
+
+ if (itemCount)
+ {
+ size += itemCount;
+ string = realloc(string, size);
+ string[size - itemCount - 1] = '\0';
+ strcat(string, data);
+ }
+
+ if (!itemCount)
+ {
+ if (targets[i] == XA_STRING)
+ {
+ *selectionString = convertLatin1toUTF8(string);
+ free(string);
+ }
+ else
+ *selectionString = string;
+
+ break;
+ }
+ }
+ }
+ else if (actualType == targets[i])
+ {
+ if (targets[i] == XA_STRING)
+ *selectionString = convertLatin1toUTF8(data);
+ else
+ *selectionString = strdup(data);
+ }
+
+ XFree(data);
+
+ if (*selectionString)
+ break;
+ }
+
+ if (!*selectionString)
+ {
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
+ "X11: Failed to convert selection to string");
+ }
+
+ return *selectionString;
+}
+
+// Make the specified window and its video mode active on its monitor
+//
+static GLFWbool acquireMonitor(_GLFWwindow* window)
+{
+ GLFWbool status;
+
+ if (_glfw.x11.saver.count == 0)
+ {
+ // Remember old screen saver settings
+ XGetScreenSaver(_glfw.x11.display,
+ &_glfw.x11.saver.timeout,
+ &_glfw.x11.saver.interval,
+ &_glfw.x11.saver.blanking,
+ &_glfw.x11.saver.exposure);
+
+ // Disable screen saver
+ XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking,
+ DefaultExposures);
+ }
+
+ if (!window->monitor->window)
+ _glfw.x11.saver.count++;
+
+ status = _glfwSetVideoModeX11(window->monitor, &window->videoMode);
+
+ if (window->x11.overrideRedirect)
+ {
+ int xpos, ypos;
+ GLFWvidmode mode;
+
+ // Manually position the window over its monitor
+ _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
+ _glfwPlatformGetVideoMode(window->monitor, &mode);
+
+ XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
+ xpos, ypos, mode.width, mode.height);
+ }
+
+ _glfwInputMonitorWindow(window->monitor, window);
+ return status;
+}
+
+// Remove the window and restore the original video mode
+//
+static void releaseMonitor(_GLFWwindow* window)
+{
+ if (window->monitor->window != window)
+ return;
+
+ _glfwInputMonitorWindow(window->monitor, NULL);
+ _glfwRestoreVideoModeX11(window->monitor);
+
+ _glfw.x11.saver.count--;
+
+ if (_glfw.x11.saver.count == 0)
+ {
+ // Restore old screen saver settings
+ XSetScreenSaver(_glfw.x11.display,
+ _glfw.x11.saver.timeout,
+ _glfw.x11.saver.interval,
+ _glfw.x11.saver.blanking,
+ _glfw.x11.saver.exposure);
+ }
+}
+
+// Process the specified X event
+//
+static void processEvent(XEvent *event)
+{
+ _GLFWwindow* window = NULL;
+ int keycode = 0;
+ Bool filtered = False;
+
+ // HACK: Save scancode as some IMs clear the field in XFilterEvent
+ if (event->type == KeyPress || event->type == KeyRelease)
+ keycode = event->xkey.keycode;
+
+ if (_glfw.x11.im)
+ filtered = XFilterEvent(event, None);
+
+ if (_glfw.x11.randr.available)
+ {
+ if (event->type == _glfw.x11.randr.eventBase + RRNotify)
+ {
+ XRRUpdateConfiguration(event);
+ _glfwPollMonitorsX11();
+ return;
+ }
+ }
+
+ if (event->type == GenericEvent)
+ {
+ if (_glfw.x11.xi.available)
+ {
+ _GLFWwindow* window = _glfw.x11.disabledCursorWindow;
+
+ if (window &&
+ event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
+ XGetEventData(_glfw.x11.display, &event->xcookie) &&
+ event->xcookie.evtype == XI_RawMotion)
+ {
+ XIRawEvent* re = event->xcookie.data;
+ if (re->valuators.mask_len)
+ {
+ const double* values = re->raw_values;
+ double xpos = window->virtualCursorPosX;
+ double ypos = window->virtualCursorPosY;
+
+ if (XIMaskIsSet(re->valuators.mask, 0))
+ {
+ xpos += *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(re->valuators.mask, 1))
+ ypos += *values;
+
+ _glfwInputCursorPos(window, xpos, ypos);
+ }
+ }
+
+ XFreeEventData(_glfw.x11.display, &event->xcookie);
+ }
+
+ return;
+ }
+
+ if (event->type == SelectionClear)
+ {
+ handleSelectionClear(event);
+ return;
+ }
+ else if (event->type == SelectionRequest)
+ {
+ handleSelectionRequest(event);
+ return;
+ }
+
+ window = findWindowByHandle(event->xany.window);
+ if (window == NULL)
+ {
+ // This is an event for a window that has already been destroyed
+ return;
+ }
+
+ switch (event->type)
+ {
+ case KeyPress:
+ {
+ const int key = translateKey(keycode);
+ const int mods = translateState(event->xkey.state);
+ const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
+
+ if (window->x11.ic)
+ {
+ // HACK: Ignore duplicate key press events generated by ibus
+ // These have the same timestamp as the original event
+ // Corresponding release events are filtered out
+ // implicitly by the GLFW key repeat logic
+ if (window->x11.lastKeyTime < event->xkey.time)
+ {
+ if (keycode)
+ _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
+
+ window->x11.lastKeyTime = event->xkey.time;
+ }
+
+ if (!filtered)
+ {
+ int count;
+ Status status;
+#if defined(X_HAVE_UTF8_STRING)
+ char buffer[100];
+ char* chars = buffer;
+
+ count = Xutf8LookupString(window->x11.ic,
+ &event->xkey,
+ buffer, sizeof(buffer) - 1,
+ NULL, &status);
+
+ if (status == XBufferOverflow)
+ {
+ chars = calloc(count + 1, 1);
+ count = Xutf8LookupString(window->x11.ic,
+ &event->xkey,
+ chars, count,
+ NULL, &status);
+ }
+
+ if (status == XLookupChars || status == XLookupBoth)
+ {
+ const char* c = chars;
+ chars[count] = '\0';
+ while (c - chars < count)
+ _glfwInputChar(window, decodeUTF8(&c), mods, plain);
+ }
+#else /*X_HAVE_UTF8_STRING*/
+ wchar_t buffer[16];
+ wchar_t* chars = buffer;
+
+ count = XwcLookupString(window->x11.ic,
+ &event->xkey,
+ buffer,
+ sizeof(buffer) / sizeof(wchar_t),
+ NULL,
+ &status);
+
+ if (status == XBufferOverflow)
+ {
+ chars = calloc(count, sizeof(wchar_t));
+ count = XwcLookupString(window->x11.ic,
+ &event->xkey,
+ chars, count,
+ NULL, &status);
+ }
+
+ if (status == XLookupChars || status == XLookupBoth)
+ {
+ int i;
+ for (i = 0; i < count; i++)
+ _glfwInputChar(window, chars[i], mods, plain);
+ }
+#endif /*X_HAVE_UTF8_STRING*/
+
+ if (chars != buffer)
+ free(chars);
+ }
+ }
+ else
+ {
+ KeySym keysym;
+ XLookupString(&event->xkey, NULL, 0, &keysym, NULL);
+
+ _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
+
+ const long character = _glfwKeySym2Unicode(keysym);
+ if (character != -1)
+ _glfwInputChar(window, character, mods, plain);
+ }
+
+ return;
+ }
+
+ case KeyRelease:
+ {
+ const int key = translateKey(keycode);
+ const int mods = translateState(event->xkey.state);
+
+ if (!_glfw.x11.xkb.detectable)
+ {
+ // HACK: Key repeat events will arrive as KeyRelease/KeyPress
+ // pairs with similar or identical time stamps
+ // The key repeat logic in _glfwInputKey expects only key
+ // presses to repeat, so detect and discard release events
+ if (XEventsQueued(_glfw.x11.display, QueuedAfterReading))
+ {
+ XEvent next;
+ XPeekEvent(_glfw.x11.display, &next);
+
+ if (next.type == KeyPress &&
+ next.xkey.window == event->xkey.window &&
+ next.xkey.keycode == keycode)
+ {
+ // HACK: The time of repeat events sometimes doesn't
+ // match that of the press event, so add an
+ // epsilon
+ // Toshiyuki Takahashi can press a button
+ // 16 times per second so it's fairly safe to
+ // assume that no human is pressing the key 50
+ // times per second (value is ms)
+ if ((next.xkey.time - event->xkey.time) < 20)
+ {
+ // This is very likely a server-generated key repeat
+ // event, so ignore it
+ return;
+ }
+ }
+ }
+ }
+
+ _glfwInputKey(window, key, keycode, GLFW_RELEASE, mods);
+ return;
+ }
+
+ case ButtonPress:
+ {
+ const int mods = translateState(event->xbutton.state);
+
+ if (event->xbutton.button == Button1)
+ _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
+ else if (event->xbutton.button == Button2)
+ _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods);
+ else if (event->xbutton.button == Button3)
+ _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods);
+
+ // Modern X provides scroll events as mouse button presses
+ else if (event->xbutton.button == Button4)
+ _glfwInputScroll(window, 0.0, 1.0);
+ else if (event->xbutton.button == Button5)
+ _glfwInputScroll(window, 0.0, -1.0);
+ else if (event->xbutton.button == Button6)
+ _glfwInputScroll(window, 1.0, 0.0);
+ else if (event->xbutton.button == Button7)
+ _glfwInputScroll(window, -1.0, 0.0);
+
+ else
+ {
+ // Additional buttons after 7 are treated as regular buttons
+ // We subtract 4 to fill the gap left by scroll input above
+ _glfwInputMouseClick(window,
+ event->xbutton.button - Button1 - 4,
+ GLFW_PRESS,
+ mods);
+ }
+
+ return;
+ }
+
+ case ButtonRelease:
+ {
+ const int mods = translateState(event->xbutton.state);
+
+ if (event->xbutton.button == Button1)
+ {
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_LEFT,
+ GLFW_RELEASE,
+ mods);
+ }
+ else if (event->xbutton.button == Button2)
+ {
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_MIDDLE,
+ GLFW_RELEASE,
+ mods);
+ }
+ else if (event->xbutton.button == Button3)
+ {
+ _glfwInputMouseClick(window,
+ GLFW_MOUSE_BUTTON_RIGHT,
+ GLFW_RELEASE,
+ mods);
+ }
+ else if (event->xbutton.button > Button7)
+ {
+ // Additional buttons after 7 are treated as regular buttons
+ // We subtract 4 to fill the gap left by scroll input above
+ _glfwInputMouseClick(window,
+ event->xbutton.button - Button1 - 4,
+ GLFW_RELEASE,
+ mods);
+ }
+
+ return;
+ }
+
+ case EnterNotify:
+ {
+ // HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
+ // ignore the defined cursor for hidden cursor mode
+ if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_HIDDEN);
+
+ _glfwInputCursorEnter(window, GLFW_TRUE);
+ return;
+ }
+
+ case LeaveNotify:
+ {
+ _glfwInputCursorEnter(window, GLFW_FALSE);
+ return;
+ }
+
+ case MotionNotify:
+ {
+ const int x = event->xmotion.x;
+ const int y = event->xmotion.y;
+
+ if (x != window->x11.warpCursorPosX ||
+ y != window->x11.warpCursorPosY)
+ {
+ // The cursor was moved by something other than GLFW
+
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ {
+ if (_glfw.x11.disabledCursorWindow != window)
+ return;
+ if (_glfw.x11.xi.available)
+ return;
+
+ const int dx = x - window->x11.lastCursorPosX;
+ const int dy = y - window->x11.lastCursorPosY;
+
+ _glfwInputCursorPos(window,
+ window->virtualCursorPosX + dx,
+ window->virtualCursorPosY + dy);
+ }
+ else
+ _glfwInputCursorPos(window, x, y);
+ }
+
+ window->x11.lastCursorPosX = x;
+ window->x11.lastCursorPosY = y;
+ return;
+ }
+
+ case ConfigureNotify:
+ {
+ if (event->xconfigure.width != window->x11.width ||
+ event->xconfigure.height != window->x11.height)
+ {
+ _glfwInputFramebufferSize(window,
+ event->xconfigure.width,
+ event->xconfigure.height);
+
+ _glfwInputWindowSize(window,
+ event->xconfigure.width,
+ event->xconfigure.height);
+
+ window->x11.width = event->xconfigure.width;
+ window->x11.height = event->xconfigure.height;
+ }
+
+ if (event->xconfigure.x != window->x11.xpos ||
+ event->xconfigure.y != window->x11.ypos)
+ {
+ if (window->x11.overrideRedirect || event->xany.send_event)
+ {
+ _glfwInputWindowPos(window,
+ event->xconfigure.x,
+ event->xconfigure.y);
+
+ window->x11.xpos = event->xconfigure.x;
+ window->x11.ypos = event->xconfigure.y;
+ }
+ }
+
+ return;
+ }
+
+ case ClientMessage:
+ {
+ // Custom client message, probably from the window manager
+
+ if (filtered)
+ return;
+
+ if (event->xclient.message_type == None)
+ return;
+
+ if (event->xclient.message_type == _glfw.x11.WM_PROTOCOLS)
+ {
+ const Atom protocol = event->xclient.data.l[0];
+ if (protocol == None)
+ return;
+
+ if (protocol == _glfw.x11.WM_DELETE_WINDOW)
+ {
+ // The window manager was asked to close the window, for
+ // example by the user pressing a 'close' window decoration
+ // button
+ _glfwInputWindowCloseRequest(window);
+ }
+ else if (protocol == _glfw.x11.NET_WM_PING)
+ {
+ // The window manager is pinging the application to ensure
+ // it's still responding to events
+
+ XEvent reply = *event;
+ reply.xclient.window = _glfw.x11.root;
+
+ XSendEvent(_glfw.x11.display, _glfw.x11.root,
+ False,
+ SubstructureNotifyMask | SubstructureRedirectMask,
+ &reply);
+ }
+ }
+ else if (event->xclient.message_type == _glfw.x11.XdndEnter)
+ {
+ // A drag operation has entered the window
+ unsigned long i, count;
+ Atom* formats = NULL;
+ const GLFWbool list = event->xclient.data.l[1] & 1;
+
+ _glfw.x11.xdnd.source = event->xclient.data.l[0];
+ _glfw.x11.xdnd.version = event->xclient.data.l[1] >> 24;
+ _glfw.x11.xdnd.format = None;
+
+ if (_glfw.x11.xdnd.version > _GLFW_XDND_VERSION)
+ return;
+
+ if (list)
+ {
+ count = _glfwGetWindowPropertyX11(_glfw.x11.xdnd.source,
+ _glfw.x11.XdndTypeList,
+ XA_ATOM,
+ (unsigned char**) &formats);
+ }
+ else
+ {
+ count = 3;
+ formats = (Atom*) event->xclient.data.l + 2;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (formats[i] == _glfw.x11.text_uri_list)
+ {
+ _glfw.x11.xdnd.format = _glfw.x11.text_uri_list;
+ break;
+ }
+ }
+
+ if (list && formats)
+ XFree(formats);
+ }
+ else if (event->xclient.message_type == _glfw.x11.XdndDrop)
+ {
+ // The drag operation has finished by dropping on the window
+ Time time = CurrentTime;
+
+ if (_glfw.x11.xdnd.version > _GLFW_XDND_VERSION)
+ return;
+
+ if (_glfw.x11.xdnd.format)
+ {
+ if (_glfw.x11.xdnd.version >= 1)
+ time = event->xclient.data.l[2];
+
+ // Request the chosen format from the source window
+ XConvertSelection(_glfw.x11.display,
+ _glfw.x11.XdndSelection,
+ _glfw.x11.xdnd.format,
+ _glfw.x11.XdndSelection,
+ window->x11.handle,
+ time);
+ }
+ else if (_glfw.x11.xdnd.version >= 2)
+ {
+ XEvent reply;
+ memset(&reply, 0, sizeof(reply));
+
+ reply.type = ClientMessage;
+ reply.xclient.window = _glfw.x11.xdnd.source;
+ reply.xclient.message_type = _glfw.x11.XdndFinished;
+ reply.xclient.format = 32;
+ reply.xclient.data.l[0] = window->x11.handle;
+ reply.xclient.data.l[1] = 0; // The drag was rejected
+ reply.xclient.data.l[2] = None;
+
+ XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
+ False, NoEventMask, &reply);
+ XFlush(_glfw.x11.display);
+ }
+ }
+ else if (event->xclient.message_type == _glfw.x11.XdndPosition)
+ {
+ // The drag operation has moved over the window
+ const int xabs = (event->xclient.data.l[2] >> 16) & 0xffff;
+ const int yabs = (event->xclient.data.l[2]) & 0xffff;
+ Window dummy;
+ int xpos, ypos;
+
+ if (_glfw.x11.xdnd.version > _GLFW_XDND_VERSION)
+ return;
+
+ XTranslateCoordinates(_glfw.x11.display,
+ _glfw.x11.root,
+ window->x11.handle,
+ xabs, yabs,
+ &xpos, &ypos,
+ &dummy);
+
+ _glfwInputCursorPos(window, xpos, ypos);
+
+ XEvent reply;
+ memset(&reply, 0, sizeof(reply));
+
+ reply.type = ClientMessage;
+ reply.xclient.window = _glfw.x11.xdnd.source;
+ reply.xclient.message_type = _glfw.x11.XdndStatus;
+ reply.xclient.format = 32;
+ reply.xclient.data.l[0] = window->x11.handle;
+ reply.xclient.data.l[2] = 0; // Specify an empty rectangle
+ reply.xclient.data.l[3] = 0;
+
+ if (_glfw.x11.xdnd.format)
+ {
+ // Reply that we are ready to copy the dragged data
+ reply.xclient.data.l[1] = 1; // Accept with no rectangle
+ if (_glfw.x11.xdnd.version >= 2)
+ reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;
+ }
+
+ XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
+ False, NoEventMask, &reply);
+ XFlush(_glfw.x11.display);
+ }
+
+ return;
+ }
+
+ case SelectionNotify:
+ {
+ if (event->xselection.property == _glfw.x11.XdndSelection)
+ {
+ // The converted data from the drag operation has arrived
+ char* data;
+ const unsigned long result =
+ _glfwGetWindowPropertyX11(event->xselection.requestor,
+ event->xselection.property,
+ event->xselection.target,
+ (unsigned char**) &data);
+
+ if (result)
+ {
+ int i, count;
+ char** paths = parseUriList(data, &count);
+
+ _glfwInputDrop(window, count, (const char**) paths);
+
+ for (i = 0; i < count; i++)
+ free(paths[i]);
+ free(paths);
+ }
+
+ if (data)
+ XFree(data);
+
+ if (_glfw.x11.xdnd.version >= 2)
+ {
+ XEvent reply;
+ memset(&reply, 0, sizeof(reply));
+
+ reply.type = ClientMessage;
+ reply.xclient.window = _glfw.x11.xdnd.source;
+ reply.xclient.message_type = _glfw.x11.XdndFinished;
+ reply.xclient.format = 32;
+ reply.xclient.data.l[0] = window->x11.handle;
+ reply.xclient.data.l[1] = result;
+ reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;
+
+ XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
+ False, NoEventMask, &reply);
+ XFlush(_glfw.x11.display);
+ }
+ }
+
+ return;
+ }
+
+ case FocusIn:
+ {
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
+
+ if (event->xfocus.mode == NotifyGrab ||
+ event->xfocus.mode == NotifyUngrab)
+ {
+ // Ignore focus events from popup indicator windows, window menu
+ // key chords and window dragging
+ return;
+ }
+
+ if (window->x11.ic)
+ XSetICFocus(window->x11.ic);
+
+ _glfwInputWindowFocus(window, GLFW_TRUE);
+ return;
+ }
+
+ case FocusOut:
+ {
+ if (window->cursorMode == GLFW_CURSOR_DISABLED)
+ _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
+
+ if (event->xfocus.mode == NotifyGrab ||
+ event->xfocus.mode == NotifyUngrab)
+ {
+ // Ignore focus events from popup indicator windows, window menu
+ // key chords and window dragging
+ return;
+ }
+
+ if (window->x11.ic)
+ XUnsetICFocus(window->x11.ic);
+
+ if (window->monitor && window->autoIconify)
+ _glfwPlatformIconifyWindow(window);
+
+ _glfwInputWindowFocus(window, GLFW_FALSE);
+ return;
+ }
+
+ case Expose:
+ {
+ _glfwInputWindowDamage(window);
+ return;
+ }
+
+ case PropertyNotify:
+ {
+ if (event->xproperty.state != PropertyNewValue)
+ return;
+
+ if (event->xproperty.atom == _glfw.x11.WM_STATE)
+ {
+ const int state = getWindowState(window);
+ if (state != IconicState && state != NormalState)
+ return;
+
+ const GLFWbool iconified = (state == IconicState);
+ if (window->x11.iconified != iconified)
+ {
+ if (window->monitor)
+ {
+ if (iconified)
+ releaseMonitor(window);
+ else
+ acquireMonitor(window);
+ }
+
+ window->x11.iconified = iconified;
+ _glfwInputWindowIconify(window, iconified);
+ }
+ }
+ else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE)
+ {
+ const GLFWbool maximized = _glfwPlatformWindowMaximized(window);
+ if (window->x11.maximized != maximized)
+ {
+ window->x11.maximized = maximized;
+ _glfwInputWindowMaximize(window, maximized);
+ }
+ }
+
+ return;
+ }
+
+ case DestroyNotify:
+ return;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Retrieve a single window property of the specified type
+// Inspired by fghGetWindowProperty from freeglut
+//
+unsigned long _glfwGetWindowPropertyX11(Window window,
+ Atom property,
+ Atom type,
+ unsigned char** value)
+{
+ Atom actualType;
+ int actualFormat;
+ unsigned long itemCount, bytesAfter;
+
+ XGetWindowProperty(_glfw.x11.display,
+ window,
+ property,
+ 0,
+ LONG_MAX,
+ False,
+ type,
+ &actualType,
+ &actualFormat,
+ &itemCount,
+ &bytesAfter,
+ value);
+
+ return itemCount;
+}
+
+GLFWbool _glfwIsVisualTransparentX11(Visual* visual)
+{
+ if (!_glfw.x11.xrender.available)
+ return GLFW_FALSE;
+
+ XRenderPictFormat* pf = XRenderFindVisualFormat(_glfw.x11.display, visual);
+ return pf && pf->direct.alphaMask;
+}
+
+// Push contents of our selection to clipboard manager
+//
+void _glfwPushSelectionToManagerX11(void)
+{
+ XConvertSelection(_glfw.x11.display,
+ _glfw.x11.CLIPBOARD_MANAGER,
+ _glfw.x11.SAVE_TARGETS,
+ None,
+ _glfw.x11.helperWindowHandle,
+ CurrentTime);
+
+ for (;;)
+ {
+ XEvent event;
+
+ while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))
+ {
+ switch (event.type)
+ {
+ case SelectionRequest:
+ handleSelectionRequest(&event);
+ break;
+
+ case SelectionClear:
+ handleSelectionClear(&event);
+ break;
+
+ case SelectionNotify:
+ {
+ if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
+ {
+ // This means one of two things; either the selection
+ // was not owned, which means there is no clipboard
+ // manager, or the transfer to the clipboard manager has
+ // completed
+ // In either case, it means we are done here
+ return;
+ }
+
+ break;
+ }
+ }
+ }
+
+ waitForEvent(NULL);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+int _glfwPlatformCreateWindow(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWctxconfig* ctxconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ Visual* visual;
+ int depth;
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
+ {
+ if (!_glfwInitGLX())
+ return GLFW_FALSE;
+ if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
+ {
+ if (!_glfwInitEGL())
+ return GLFW_FALSE;
+ if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwInitOSMesa())
+ return GLFW_FALSE;
+ }
+ }
+
+ if (ctxconfig->client == GLFW_NO_API ||
+ ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
+ depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
+ }
+
+ if (!createNativeWindow(window, wndconfig, visual, depth))
+ return GLFW_FALSE;
+
+ if (ctxconfig->client != GLFW_NO_API)
+ {
+ if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
+ {
+ if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
+ {
+ if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
+ {
+ if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+ return GLFW_FALSE;
+ }
+ }
+
+ if (window->monitor)
+ {
+ _glfwPlatformShowWindow(window);
+ updateWindowMode(window);
+ if (!acquireMonitor(window))
+ return GLFW_FALSE;
+
+ if (wndconfig->centerCursor)
+ centerCursor(window);
+ }
+
+ XFlush(_glfw.x11.display);
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyWindow(_GLFWwindow* window)
+{
+ if (_glfw.x11.disabledCursorWindow == window)
+ _glfw.x11.disabledCursorWindow = NULL;
+
+ if (window->monitor)
+ releaseMonitor(window);
+
+ if (window->x11.ic)
+ {
+ XDestroyIC(window->x11.ic);
+ window->x11.ic = NULL;
+ }
+
+ if (window->context.destroy)
+ window->context.destroy(window);
+
+ if (window->x11.handle)
+ {
+ XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);
+ XUnmapWindow(_glfw.x11.display, window->x11.handle);
+ XDestroyWindow(_glfw.x11.display, window->x11.handle);
+ window->x11.handle = (Window) 0;
+ }
+
+ if (window->x11.colormap)
+ {
+ XFreeColormap(_glfw.x11.display, window->x11.colormap);
+ window->x11.colormap = (Colormap) 0;
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
+{
+#if defined(X_HAVE_UTF8_STRING)
+ Xutf8SetWMProperties(_glfw.x11.display,
+ window->x11.handle,
+ title, title,
+ NULL, 0,
+ NULL, NULL, NULL);
+#else
+ // This may be a slightly better fallback than using XStoreName and
+ // XSetIconName, which always store their arguments using STRING
+ XmbSetWMProperties(_glfw.x11.display,
+ window->x11.handle,
+ title, title,
+ NULL, 0,
+ NULL, NULL, NULL);
+#endif
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8,
+ PropModeReplace,
+ (unsigned char*) title, strlen(title));
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8,
+ PropModeReplace,
+ (unsigned char*) title, strlen(title));
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
+ int count, const GLFWimage* images)
+{
+ if (count)
+ {
+ int i, j, longCount = 0;
+
+ for (i = 0; i < count; i++)
+ longCount += 2 + images[i].width * images[i].height;
+
+ long* icon = calloc(longCount, sizeof(long));
+ long* target = icon;
+
+ for (i = 0; i < count; i++)
+ {
+ *target++ = images[i].width;
+ *target++ = images[i].height;
+
+ for (j = 0; j < images[i].width * images[i].height; j++)
+ {
+ *target++ = (images[i].pixels[j * 4 + 0] << 16) |
+ (images[i].pixels[j * 4 + 1] << 8) |
+ (images[i].pixels[j * 4 + 2] << 0) |
+ (images[i].pixels[j * 4 + 3] << 24);
+ }
+ }
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_ICON,
+ XA_CARDINAL, 32,
+ PropModeReplace,
+ (unsigned char*) icon,
+ longCount);
+
+ free(icon);
+ }
+ else
+ {
+ XDeleteProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_ICON);
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
+{
+ Window dummy;
+ int x, y;
+
+ XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,
+ 0, 0, &x, &y, &dummy);
+
+ if (xpos)
+ *xpos = x;
+ if (ypos)
+ *ypos = y;
+}
+
+void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
+{
+ // HACK: Explicitly setting PPosition to any value causes some WMs, notably
+ // Compiz and Metacity, to honor the position of unmapped windows
+ if (!_glfwPlatformWindowVisible(window))
+ {
+ long supplied;
+ XSizeHints* hints = XAllocSizeHints();
+
+ if (XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied))
+ {
+ hints->flags |= PPosition;
+ hints->x = hints->y = 0;
+
+ XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
+ }
+
+ XFree(hints);
+ }
+
+ XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
+{
+ XWindowAttributes attribs;
+ XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs);
+
+ if (width)
+ *width = attribs.width;
+ if (height)
+ *height = attribs.height;
+}
+
+void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
+{
+ if (window->monitor)
+ {
+ if (window->monitor->window == window)
+ acquireMonitor(window);
+ }
+ else
+ {
+ if (!window->resizable)
+ updateNormalHints(window, width, height);
+
+ XResizeWindow(_glfw.x11.display, window->x11.handle, width, height);
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
+ int minwidth, int minheight,
+ int maxwidth, int maxheight)
+{
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ updateNormalHints(window, width, height);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
+{
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ updateNormalHints(window, width, height);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
+{
+ _glfwPlatformGetWindowSize(window, width, height);
+}
+
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+ int* left, int* top,
+ int* right, int* bottom)
+{
+ long* extents = NULL;
+
+ if (window->monitor || !window->decorated)
+ return;
+
+ if (_glfw.x11.NET_FRAME_EXTENTS == None)
+ return;
+
+ if (!_glfwPlatformWindowVisible(window) &&
+ _glfw.x11.NET_REQUEST_FRAME_EXTENTS)
+ {
+ XEvent event;
+ double timeout = 0.5;
+
+ // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
+ // function before the window is mapped
+ sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
+ 0, 0, 0, 0, 0);
+
+ // HACK: Use a timeout because earlier versions of some window managers
+ // (at least Unity, Fluxbox and Xfwm) failed to send the reply
+ // They have been fixed but broken versions are still in the wild
+ // If you are affected by this and your window manager is NOT
+ // listed above, PLEASE report it to their and our issue trackers
+ while (!XCheckIfEvent(_glfw.x11.display,
+ &event,
+ isFrameExtentsEvent,
+ (XPointer) window))
+ {
+ if (!waitForEvent(&timeout))
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
+ return;
+ }
+ }
+ }
+
+ if (_glfwGetWindowPropertyX11(window->x11.handle,
+ _glfw.x11.NET_FRAME_EXTENTS,
+ XA_CARDINAL,
+ (unsigned char**) &extents) == 4)
+ {
+ if (left)
+ *left = extents[0];
+ if (top)
+ *top = extents[2];
+ if (right)
+ *right = extents[1];
+ if (bottom)
+ *bottom = extents[3];
+ }
+
+ if (extents)
+ XFree(extents);
+}
+
+void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
+ float* xscale, float* yscale)
+{
+ if (xscale)
+ *xscale = _glfw.x11.contentScaleX;
+ if (yscale)
+ *yscale = _glfw.x11.contentScaleY;
+}
+
+void _glfwPlatformIconifyWindow(_GLFWwindow* window)
+{
+ if (window->x11.overrideRedirect)
+ {
+ // Override-redirect windows cannot be iconified or restored, as those
+ // tasks are performed by the window manager
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Iconification of full screen windows requires a WM that supports EWMH full screen");
+ return;
+ }
+
+ XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformRestoreWindow(_GLFWwindow* window)
+{
+ if (window->x11.overrideRedirect)
+ {
+ // Override-redirect windows cannot be iconified or restored, as those
+ // tasks are performed by the window manager
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Iconification of full screen windows requires a WM that supports EWMH full screen");
+ return;
+ }
+
+ if (_glfwPlatformWindowIconified(window))
+ {
+ XMapWindow(_glfw.x11.display, window->x11.handle);
+ waitForVisibilityNotify(window);
+ }
+ else if (_glfwPlatformWindowVisible(window))
+ {
+ if (_glfw.x11.NET_WM_STATE &&
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
+ {
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_STATE,
+ _NET_WM_STATE_REMOVE,
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
+ 1, 0);
+ }
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
+{
+ if (_glfw.x11.NET_WM_STATE &&
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
+ {
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_STATE,
+ _NET_WM_STATE_ADD,
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
+ _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
+ 1, 0);
+ XFlush(_glfw.x11.display);
+ }
+}
+
+void _glfwPlatformShowWindow(_GLFWwindow* window)
+{
+ if (_glfwPlatformWindowVisible(window))
+ return;
+
+ XMapWindow(_glfw.x11.display, window->x11.handle);
+ waitForVisibilityNotify(window);
+}
+
+void _glfwPlatformHideWindow(_GLFWwindow* window)
+{
+ XUnmapWindow(_glfw.x11.display, window->x11.handle);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
+{
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_STATE,
+ _NET_WM_STATE_ADD,
+ _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION,
+ 0, 1, 0);
+}
+
+void _glfwPlatformFocusWindow(_GLFWwindow* window)
+{
+ if (_glfw.x11.NET_ACTIVE_WINDOW)
+ sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
+ else
+ {
+ XRaiseWindow(_glfw.x11.display, window->x11.handle);
+ XSetInputFocus(_glfw.x11.display, window->x11.handle,
+ RevertToParent, CurrentTime);
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
+ _GLFWmonitor* monitor,
+ int xpos, int ypos,
+ int width, int height,
+ int refreshRate)
+{
+ if (window->monitor == monitor)
+ {
+ if (monitor)
+ {
+ if (monitor->window == window)
+ acquireMonitor(window);
+ }
+ else
+ {
+ XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
+ xpos, ypos, width, height);
+ }
+
+ return;
+ }
+
+ if (window->monitor)
+ releaseMonitor(window);
+
+ _glfwInputWindowMonitor(window, monitor);
+ updateNormalHints(window, width, height);
+ updateWindowMode(window);
+
+ if (window->monitor)
+ {
+ XMapRaised(_glfw.x11.display, window->x11.handle);
+ if (waitForVisibilityNotify(window))
+ acquireMonitor(window);
+ }
+ else
+ {
+ XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
+ xpos, ypos, width, height);
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+int _glfwPlatformWindowFocused(_GLFWwindow* window)
+{
+ Window focused;
+ int state;
+
+ XGetInputFocus(_glfw.x11.display, &focused, &state);
+ return window->x11.handle == focused;
+}
+
+int _glfwPlatformWindowIconified(_GLFWwindow* window)
+{
+ return getWindowState(window) == IconicState;
+}
+
+int _glfwPlatformWindowVisible(_GLFWwindow* window)
+{
+ XWindowAttributes wa;
+ XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa);
+ return wa.map_state == IsViewable;
+}
+
+int _glfwPlatformWindowMaximized(_GLFWwindow* window)
+{
+ Atom* states;
+ unsigned long i;
+ GLFWbool maximized = GLFW_FALSE;
+ const unsigned long count =
+ _glfwGetWindowPropertyX11(window->x11.handle,
+ _glfw.x11.NET_WM_STATE,
+ XA_ATOM,
+ (unsigned char**) &states);
+
+ for (i = 0; i < count; i++)
+ {
+ if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
+ states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
+ {
+ maximized = GLFW_TRUE;
+ break;
+ }
+ }
+
+ if (states)
+ XFree(states);
+
+ return maximized;
+}
+
+int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
+{
+ if (!window->x11.transparent)
+ return GLFW_FALSE;
+
+ // Check whether a compositing manager is running
+ char name[32];
+ snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen);
+ const Atom selection = XInternAtom(_glfw.x11.display, name, False);
+ return XGetSelectionOwner(_glfw.x11.display, selection) != None;
+}
+
+void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
+{
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+ updateNormalHints(window, width, height);
+}
+
+void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
+{
+ if (enabled)
+ {
+ XDeleteProperty(_glfw.x11.display,
+ window->x11.handle,
+ _glfw.x11.MOTIF_WM_HINTS);
+ }
+ else
+ {
+ struct
+ {
+ unsigned long flags;
+ unsigned long functions;
+ unsigned long decorations;
+ long input_mode;
+ unsigned long status;
+ } hints;
+
+ hints.flags = 2; // Set decorations
+ hints.decorations = 0; // No decorations
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.MOTIF_WM_HINTS,
+ _glfw.x11.MOTIF_WM_HINTS, 32,
+ PropModeReplace,
+ (unsigned char*) &hints,
+ sizeof(hints) / sizeof(long));
+ }
+}
+
+void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
+{
+ if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)
+ return;
+
+ if (_glfwPlatformWindowVisible(window))
+ {
+ const Atom action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+ sendEventToWM(window,
+ _glfw.x11.NET_WM_STATE,
+ action,
+ _glfw.x11.NET_WM_STATE_ABOVE,
+ 0, 1, 0);
+ }
+ else
+ {
+ Atom* states;
+ unsigned long i, count;
+
+ count = _glfwGetWindowPropertyX11(window->x11.handle,
+ _glfw.x11.NET_WM_STATE,
+ XA_ATOM,
+ (unsigned char**) &states);
+ if (!states)
+ return;
+
+ if (enabled)
+ {
+ for (i = 0; i < count; i++)
+ {
+ if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
+ break;
+ }
+
+ if (i == count)
+ {
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
+ PropModeAppend,
+ (unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
+ 1);
+ }
+ }
+ else
+ {
+ for (i = 0; i < count; i++)
+ {
+ if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
+ {
+ states[i] = states[count - 1];
+ count--;
+ }
+ }
+
+ XChangeProperty(_glfw.x11.display, window->x11.handle,
+ _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*) &states, count);
+ }
+
+ XFree(states);
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformPollEvents(void)
+{
+ _GLFWwindow* window;
+
+#if defined(__linux__)
+ _glfwDetectJoystickConnectionLinux();
+#endif
+ int count = XPending(_glfw.x11.display);
+ while (count--)
+ {
+ XEvent event;
+ XNextEvent(_glfw.x11.display, &event);
+ processEvent(&event);
+ }
+
+ window = _glfw.x11.disabledCursorWindow;
+ if (window)
+ {
+ int width, height;
+ _glfwPlatformGetWindowSize(window, &width, &height);
+
+ // NOTE: Re-center the cursor only if it has moved since the last call,
+ // to avoid breaking glfwWaitEvents with MotionNotify
+ if (window->x11.lastCursorPosX != width / 2 ||
+ window->x11.lastCursorPosY != height / 2)
+ {
+ _glfwPlatformSetCursorPos(window, width / 2, height / 2);
+ }
+ }
+
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformWaitEvents(void)
+{
+ while (!XPending(_glfw.x11.display))
+ waitForEvent(NULL);
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformWaitEventsTimeout(double timeout)
+{
+ while (!XPending(_glfw.x11.display))
+ {
+ if (!waitForEvent(&timeout))
+ break;
+ }
+
+ _glfwPlatformPollEvents();
+}
+
+void _glfwPlatformPostEmptyEvent(void)
+{
+ XEvent event;
+
+ memset(&event, 0, sizeof(event));
+ event.type = ClientMessage;
+ event.xclient.window = _glfw.x11.helperWindowHandle;
+ event.xclient.format = 32; // Data is 32-bit longs
+ event.xclient.message_type = _glfw.x11.NULL_;
+
+ XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
+{
+ Window root, child;
+ int rootX, rootY, childX, childY;
+ unsigned int mask;
+
+ XQueryPointer(_glfw.x11.display, window->x11.handle,
+ &root, &child,
+ &rootX, &rootY, &childX, &childY,
+ &mask);
+
+ if (xpos)
+ *xpos = childX;
+ if (ypos)
+ *ypos = childY;
+}
+
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
+{
+ // Store the new position so it can be recognized later
+ window->x11.warpCursorPosX = (int) x;
+ window->x11.warpCursorPosY = (int) y;
+
+ XWarpPointer(_glfw.x11.display, None, window->x11.handle,
+ 0,0,0,0, (int) x, (int) y);
+ XFlush(_glfw.x11.display);
+}
+
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
+{
+ if (mode == GLFW_CURSOR_DISABLED)
+ {
+ if (_glfw.x11.xi.available)
+ {
+ XIEventMask em;
+ unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
+
+ em.deviceid = XIAllMasterDevices;
+ em.mask_len = sizeof(mask);
+ em.mask = mask;
+ XISetMask(mask, XI_RawMotion);
+
+ XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
+ }
+
+ _glfw.x11.disabledCursorWindow = window;
+ _glfwPlatformGetCursorPos(window,
+ &_glfw.x11.restoreCursorPosX,
+ &_glfw.x11.restoreCursorPosY);
+ centerCursor(window);
+ XGrabPointer(_glfw.x11.display, window->x11.handle, True,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync,
+ window->x11.handle,
+ _glfw.x11.hiddenCursorHandle,
+ CurrentTime);
+ }
+ else if (_glfw.x11.disabledCursorWindow == window)
+ {
+ if (_glfw.x11.xi.available)
+ {
+ XIEventMask em;
+ unsigned char mask[] = { 0 };
+
+ em.deviceid = XIAllMasterDevices;
+ em.mask_len = sizeof(mask);
+ em.mask = mask;
+
+ XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
+ }
+
+ _glfw.x11.disabledCursorWindow = NULL;
+ XUngrabPointer(_glfw.x11.display, CurrentTime);
+ _glfwPlatformSetCursorPos(window,
+ _glfw.x11.restoreCursorPosX,
+ _glfw.x11.restoreCursorPosY);
+ }
+
+ updateCursorImage(window);
+ XFlush(_glfw.x11.display);
+}
+
+const char* _glfwPlatformGetScancodeName(int scancode)
+{
+ if (!_glfw.x11.xkb.available)
+ return NULL;
+
+ const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
+ if (keysym == NoSymbol)
+ return NULL;
+
+ const long ch = _glfwKeySym2Unicode(keysym);
+ if (ch == -1)
+ return NULL;
+
+ const size_t count = encodeUTF8(_glfw.x11.keyName, (unsigned int) ch);
+ if (count == 0)
+ return NULL;
+
+ _glfw.x11.keyName[count] = '\0';
+ return _glfw.x11.keyName;
+}
+
+int _glfwPlatformGetKeyScancode(int key)
+{
+ return _glfw.x11.scancodes[key];
+}
+
+int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
+ const GLFWimage* image,
+ int xhot, int yhot)
+{
+ cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);
+ if (!cursor->x11.handle)
+ return GLFW_FALSE;
+
+ return GLFW_TRUE;
+}
+
+int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
+{
+ cursor->x11.handle = XCreateFontCursor(_glfw.x11.display,
+ translateCursorShape(shape));
+ if (!cursor->x11.handle)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to create standard cursor");
+ return GLFW_FALSE;
+ }
+
+ return GLFW_TRUE;
+}
+
+void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
+{
+ if (cursor->x11.handle)
+ XFreeCursor(_glfw.x11.display, cursor->x11.handle);
+}
+
+void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
+{
+ if (window->cursorMode == GLFW_CURSOR_NORMAL)
+ {
+ updateCursorImage(window);
+ XFlush(_glfw.x11.display);
+ }
+}
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ free(_glfw.x11.clipboardString);
+ _glfw.x11.clipboardString = strdup(string);
+
+ XSetSelectionOwner(_glfw.x11.display,
+ _glfw.x11.CLIPBOARD,
+ _glfw.x11.helperWindowHandle,
+ CurrentTime);
+
+ if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
+ _glfw.x11.helperWindowHandle)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to become owner of clipboard selection");
+ }
+}
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ return getSelectionString(_glfw.x11.CLIPBOARD);
+}
+
+void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
+{
+ if (!_glfw.vk.KHR_surface)
+ return;
+
+ if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle)
+ {
+ if (!_glfw.vk.KHR_xlib_surface)
+ return;
+ }
+
+ extensions[0] = "VK_KHR_surface";
+
+ // NOTE: VK_KHR_xcb_surface is preferred due to some early ICDs exposing but
+ // not correctly implementing VK_KHR_xlib_surface
+ if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
+ extensions[1] = "VK_KHR_xcb_surface";
+ else
+ extensions[1] = "VK_KHR_xlib_surface";
+}
+
+int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t queuefamily)
+{
+ VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display,
+ _glfw.x11.screen));
+
+ if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
+ {
+ PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
+ vkGetPhysicalDeviceXcbPresentationSupportKHR =
+ (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
+ if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "X11: Vulkan instance missing VK_KHR_xcb_surface extension");
+ return GLFW_FALSE;
+ }
+
+ xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
+ if (!connection)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to retrieve XCB connection");
+ return GLFW_FALSE;
+ }
+
+ return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
+ queuefamily,
+ connection,
+ visualID);
+ }
+ else
+ {
+ PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
+ vkGetPhysicalDeviceXlibPresentationSupportKHR =
+ (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
+ if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "X11: Vulkan instance missing VK_KHR_xlib_surface extension");
+ return GLFW_FALSE;
+ }
+
+ return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
+ queuefamily,
+ _glfw.x11.display,
+ visualID);
+ }
+}
+
+VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
+ _GLFWwindow* window,
+ const VkAllocationCallbacks* allocator,
+ VkSurfaceKHR* surface)
+{
+ if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
+ {
+ VkResult err;
+ VkXcbSurfaceCreateInfoKHR sci;
+ PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
+
+ xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
+ if (!connection)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to retrieve XCB connection");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)
+ vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR");
+ if (!vkCreateXcbSurfaceKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "X11: Vulkan instance missing VK_KHR_xcb_surface extension");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ memset(&sci, 0, sizeof(sci));
+ sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+ sci.connection = connection;
+ sci.window = window->x11.handle;
+
+ err = vkCreateXcbSurfaceKHR(instance, &sci, allocator, surface);
+ if (err)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to create Vulkan XCB surface: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ return err;
+ }
+ else
+ {
+ VkResult err;
+ VkXlibSurfaceCreateInfoKHR sci;
+ PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
+
+ vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)
+ vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR");
+ if (!vkCreateXlibSurfaceKHR)
+ {
+ _glfwInputError(GLFW_API_UNAVAILABLE,
+ "X11: Vulkan instance missing VK_KHR_xlib_surface extension");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ memset(&sci, 0, sizeof(sci));
+ sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
+ sci.dpy = _glfw.x11.display;
+ sci.window = window->x11.handle;
+
+ err = vkCreateXlibSurfaceKHR(instance, &sci, allocator, surface);
+ if (err)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to create Vulkan X11 surface: %s",
+ _glfwGetVulkanResultString(err));
+ }
+
+ return err;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW native API //////
+//////////////////////////////////////////////////////////////////////////
+
+GLFWAPI Display* glfwGetX11Display(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return _glfw.x11.display;
+}
+
+GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
+{
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFW_REQUIRE_INIT_OR_RETURN(None);
+ return window->x11.handle;
+}
+
+GLFWAPI void glfwSetX11SelectionString(const char* string)
+{
+ _GLFW_REQUIRE_INIT();
+
+ free(_glfw.x11.primarySelectionString);
+ _glfw.x11.primarySelectionString = strdup(string);
+
+ XSetSelectionOwner(_glfw.x11.display,
+ _glfw.x11.PRIMARY,
+ _glfw.x11.helperWindowHandle,
+ CurrentTime);
+
+ if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.PRIMARY) !=
+ _glfw.x11.helperWindowHandle)
+ {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "X11: Failed to become owner of primary selection");
+ }
+}
+
+GLFWAPI const char* glfwGetX11SelectionString(void)
+{
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
+ return getSelectionString(_glfw.x11.PRIMARY);
+}
+
diff --git a/src/external/glfw/src/xkb_unicode.c b/src/external/glfw/src/xkb_unicode.c
new file mode 100644
index 00000000..ecfdc2af
--- /dev/null
+++ b/src/external/glfw/src/xkb_unicode.c
@@ -0,0 +1,940 @@
+//========================================================================
+// GLFW 3.3 X11 - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2002-2006 Marcus Geelnard
+// Copyright (c) 2006-2016 Camilla Löwy <[email protected]>
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would
+// be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+// be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+// distribution.
+//
+//========================================================================
+
+#include "internal.h"
+
+
+/*
+ * Marcus: This code was originally written by Markus G. Kuhn.
+ * I have made some slight changes (trimmed it down a bit from >60 KB to
+ * 20 KB), but the functionality is the same.
+ */
+
+/*
+ * This module converts keysym values into the corresponding ISO 10646
+ * (UCS, Unicode) values.
+ *
+ * The array keysymtab[] contains pairs of X11 keysym values for graphical
+ * characters and the corresponding Unicode value. The function
+ * _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary
+ * search, therefore keysymtab[] must remain SORTED by keysym value.
+ *
+ * We allow to represent any UCS character in the range U-00000000 to
+ * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
+ * This admittedly does not cover the entire 31-bit space of UCS, but
+ * it does cover all of the characters up to U-10FFFF, which can be
+ * represented by UTF-16, and more, and it is very unlikely that higher
+ * UCS codes will ever be assigned by ISO. So to get Unicode character
+ * U+ABCD you can directly use keysym 0x0100abcd.
+ *
+ * Original author: Markus G. Kuhn <[email protected]>, University of
+ * Cambridge, April 2001
+ *
+ * Special thanks to Richard Verhoeven <[email protected]> for preparing
+ * an initial draft of the mapping table.
+ *
+ */
+
+
+//************************************************************************
+//**** KeySym to Unicode mapping table ****
+//************************************************************************
+
+static const struct codepair {
+ unsigned short keysym;
+ unsigned short ucs;
+} keysymtab[] = {
+ { 0x01a1, 0x0104 },
+ { 0x01a2, 0x02d8 },
+ { 0x01a3, 0x0141 },
+ { 0x01a5, 0x013d },
+ { 0x01a6, 0x015a },
+ { 0x01a9, 0x0160 },
+ { 0x01aa, 0x015e },
+ { 0x01ab, 0x0164 },
+ { 0x01ac, 0x0179 },
+ { 0x01ae, 0x017d },
+ { 0x01af, 0x017b },
+ { 0x01b1, 0x0105 },
+ { 0x01b2, 0x02db },
+ { 0x01b3, 0x0142 },
+ { 0x01b5, 0x013e },
+ { 0x01b6, 0x015b },
+ { 0x01b7, 0x02c7 },
+ { 0x01b9, 0x0161 },
+ { 0x01ba, 0x015f },
+ { 0x01bb, 0x0165 },
+ { 0x01bc, 0x017a },
+ { 0x01bd, 0x02dd },
+ { 0x01be, 0x017e },
+ { 0x01bf, 0x017c },
+ { 0x01c0, 0x0154 },
+ { 0x01c3, 0x0102 },
+ { 0x01c5, 0x0139 },
+ { 0x01c6, 0x0106 },
+ { 0x01c8, 0x010c },
+ { 0x01ca, 0x0118 },
+ { 0x01cc, 0x011a },
+ { 0x01cf, 0x010e },
+ { 0x01d0, 0x0110 },
+ { 0x01d1, 0x0143 },
+ { 0x01d2, 0x0147 },
+ { 0x01d5, 0x0150 },
+ { 0x01d8, 0x0158 },
+ { 0x01d9, 0x016e },
+ { 0x01db, 0x0170 },
+ { 0x01de, 0x0162 },
+ { 0x01e0, 0x0155 },
+ { 0x01e3, 0x0103 },
+ { 0x01e5, 0x013a },
+ { 0x01e6, 0x0107 },
+ { 0x01e8, 0x010d },
+ { 0x01ea, 0x0119 },
+ { 0x01ec, 0x011b },
+ { 0x01ef, 0x010f },
+ { 0x01f0, 0x0111 },
+ { 0x01f1, 0x0144 },
+ { 0x01f2, 0x0148 },
+ { 0x01f5, 0x0151 },
+ { 0x01f8, 0x0159 },
+ { 0x01f9, 0x016f },
+ { 0x01fb, 0x0171 },
+ { 0x01fe, 0x0163 },
+ { 0x01ff, 0x02d9 },
+ { 0x02a1, 0x0126 },
+ { 0x02a6, 0x0124 },
+ { 0x02a9, 0x0130 },
+ { 0x02ab, 0x011e },
+ { 0x02ac, 0x0134 },
+ { 0x02b1, 0x0127 },
+ { 0x02b6, 0x0125 },
+ { 0x02b9, 0x0131 },
+ { 0x02bb, 0x011f },
+ { 0x02bc, 0x0135 },
+ { 0x02c5, 0x010a },
+ { 0x02c6, 0x0108 },
+ { 0x02d5, 0x0120 },
+ { 0x02d8, 0x011c },
+ { 0x02dd, 0x016c },
+ { 0x02de, 0x015c },
+ { 0x02e5, 0x010b },
+ { 0x02e6, 0x0109 },
+ { 0x02f5, 0x0121 },
+ { 0x02f8, 0x011d },
+ { 0x02fd, 0x016d },
+ { 0x02fe, 0x015d },
+ { 0x03a2, 0x0138 },
+ { 0x03a3, 0x0156 },
+ { 0x03a5, 0x0128 },
+ { 0x03a6, 0x013b },
+ { 0x03aa, 0x0112 },
+ { 0x03ab, 0x0122 },
+ { 0x03ac, 0x0166 },
+ { 0x03b3, 0x0157 },
+ { 0x03b5, 0x0129 },
+ { 0x03b6, 0x013c },
+ { 0x03ba, 0x0113 },
+ { 0x03bb, 0x0123 },
+ { 0x03bc, 0x0167 },
+ { 0x03bd, 0x014a },
+ { 0x03bf, 0x014b },
+ { 0x03c0, 0x0100 },
+ { 0x03c7, 0x012e },
+ { 0x03cc, 0x0116 },
+ { 0x03cf, 0x012a },
+ { 0x03d1, 0x0145 },
+ { 0x03d2, 0x014c },
+ { 0x03d3, 0x0136 },
+ { 0x03d9, 0x0172 },
+ { 0x03dd, 0x0168 },
+ { 0x03de, 0x016a },
+ { 0x03e0, 0x0101 },
+ { 0x03e7, 0x012f },
+ { 0x03ec, 0x0117 },
+ { 0x03ef, 0x012b },
+ { 0x03f1, 0x0146 },
+ { 0x03f2, 0x014d },
+ { 0x03f3, 0x0137 },
+ { 0x03f9, 0x0173 },
+ { 0x03fd, 0x0169 },
+ { 0x03fe, 0x016b },
+ { 0x047e, 0x203e },
+ { 0x04a1, 0x3002 },
+ { 0x04a2, 0x300c },
+ { 0x04a3, 0x300d },
+ { 0x04a4, 0x3001 },
+ { 0x04a5, 0x30fb },
+ { 0x04a6, 0x30f2 },
+ { 0x04a7, 0x30a1 },
+ { 0x04a8, 0x30a3 },
+ { 0x04a9, 0x30a5 },
+ { 0x04aa, 0x30a7 },
+ { 0x04ab, 0x30a9 },
+ { 0x04ac, 0x30e3 },
+ { 0x04ad, 0x30e5 },
+ { 0x04ae, 0x30e7 },
+ { 0x04af, 0x30c3 },
+ { 0x04b0, 0x30fc },
+ { 0x04b1, 0x30a2 },
+ { 0x04b2, 0x30a4 },
+ { 0x04b3, 0x30a6 },
+ { 0x04b4, 0x30a8 },
+ { 0x04b5, 0x30aa },
+ { 0x04b6, 0x30ab },
+ { 0x04b7, 0x30ad },
+ { 0x04b8, 0x30af },
+ { 0x04b9, 0x30b1 },
+ { 0x04ba, 0x30b3 },
+ { 0x04bb, 0x30b5 },
+ { 0x04bc, 0x30b7 },
+ { 0x04bd, 0x30b9 },
+ { 0x04be, 0x30bb },
+ { 0x04bf, 0x30bd },
+ { 0x04c0, 0x30bf },
+ { 0x04c1, 0x30c1 },
+ { 0x04c2, 0x30c4 },
+ { 0x04c3, 0x30c6 },
+ { 0x04c4, 0x30c8 },
+ { 0x04c5, 0x30ca },
+ { 0x04c6, 0x30cb },
+ { 0x04c7, 0x30cc },
+ { 0x04c8, 0x30cd },
+ { 0x04c9, 0x30ce },
+ { 0x04ca, 0x30cf },
+ { 0x04cb, 0x30d2 },
+ { 0x04cc, 0x30d5 },
+ { 0x04cd, 0x30d8 },
+ { 0x04ce, 0x30db },
+ { 0x04cf, 0x30de },
+ { 0x04d0, 0x30df },
+ { 0x04d1, 0x30e0 },
+ { 0x04d2, 0x30e1 },
+ { 0x04d3, 0x30e2 },
+ { 0x04d4, 0x30e4 },
+ { 0x04d5, 0x30e6 },
+ { 0x04d6, 0x30e8 },
+ { 0x04d7, 0x30e9 },
+ { 0x04d8, 0x30ea },
+ { 0x04d9, 0x30eb },
+ { 0x04da, 0x30ec },
+ { 0x04db, 0x30ed },
+ { 0x04dc, 0x30ef },
+ { 0x04dd, 0x30f3 },
+ { 0x04de, 0x309b },
+ { 0x04df, 0x309c },
+ { 0x05ac, 0x060c },
+ { 0x05bb, 0x061b },
+ { 0x05bf, 0x061f },
+ { 0x05c1, 0x0621 },
+ { 0x05c2, 0x0622 },
+ { 0x05c3, 0x0623 },
+ { 0x05c4, 0x0624 },
+ { 0x05c5, 0x0625 },
+ { 0x05c6, 0x0626 },
+ { 0x05c7, 0x0627 },
+ { 0x05c8, 0x0628 },
+ { 0x05c9, 0x0629 },
+ { 0x05ca, 0x062a },
+ { 0x05cb, 0x062b },
+ { 0x05cc, 0x062c },
+ { 0x05cd, 0x062d },
+ { 0x05ce, 0x062e },
+ { 0x05cf, 0x062f },
+ { 0x05d0, 0x0630 },
+ { 0x05d1, 0x0631 },
+ { 0x05d2, 0x0632 },
+ { 0x05d3, 0x0633 },
+ { 0x05d4, 0x0634 },
+ { 0x05d5, 0x0635 },
+ { 0x05d6, 0x0636 },
+ { 0x05d7, 0x0637 },
+ { 0x05d8, 0x0638 },
+ { 0x05d9, 0x0639 },
+ { 0x05da, 0x063a },
+ { 0x05e0, 0x0640 },
+ { 0x05e1, 0x0641 },
+ { 0x05e2, 0x0642 },
+ { 0x05e3, 0x0643 },
+ { 0x05e4, 0x0644 },
+ { 0x05e5, 0x0645 },
+ { 0x05e6, 0x0646 },
+ { 0x05e7, 0x0647 },
+ { 0x05e8, 0x0648 },
+ { 0x05e9, 0x0649 },
+ { 0x05ea, 0x064a },
+ { 0x05eb, 0x064b },
+ { 0x05ec, 0x064c },
+ { 0x05ed, 0x064d },
+ { 0x05ee, 0x064e },
+ { 0x05ef, 0x064f },
+ { 0x05f0, 0x0650 },
+ { 0x05f1, 0x0651 },
+ { 0x05f2, 0x0652 },
+ { 0x06a1, 0x0452 },
+ { 0x06a2, 0x0453 },
+ { 0x06a3, 0x0451 },
+ { 0x06a4, 0x0454 },
+ { 0x06a5, 0x0455 },
+ { 0x06a6, 0x0456 },
+ { 0x06a7, 0x0457 },
+ { 0x06a8, 0x0458 },
+ { 0x06a9, 0x0459 },
+ { 0x06aa, 0x045a },
+ { 0x06ab, 0x045b },
+ { 0x06ac, 0x045c },
+ { 0x06ae, 0x045e },
+ { 0x06af, 0x045f },
+ { 0x06b0, 0x2116 },
+ { 0x06b1, 0x0402 },
+ { 0x06b2, 0x0403 },
+ { 0x06b3, 0x0401 },
+ { 0x06b4, 0x0404 },
+ { 0x06b5, 0x0405 },
+ { 0x06b6, 0x0406 },
+ { 0x06b7, 0x0407 },
+ { 0x06b8, 0x0408 },
+ { 0x06b9, 0x0409 },
+ { 0x06ba, 0x040a },
+ { 0x06bb, 0x040b },
+ { 0x06bc, 0x040c },
+ { 0x06be, 0x040e },
+ { 0x06bf, 0x040f },
+ { 0x06c0, 0x044e },
+ { 0x06c1, 0x0430 },
+ { 0x06c2, 0x0431 },
+ { 0x06c3, 0x0446 },
+ { 0x06c4, 0x0434 },
+ { 0x06c5, 0x0435 },
+ { 0x06c6, 0x0444 },
+ { 0x06c7, 0x0433 },
+ { 0x06c8, 0x0445 },
+ { 0x06c9, 0x0438 },
+ { 0x06ca, 0x0439 },
+ { 0x06cb, 0x043a },
+ { 0x06cc, 0x043b },
+ { 0x06cd, 0x043c },
+ { 0x06ce, 0x043d },
+ { 0x06cf, 0x043e },
+ { 0x06d0, 0x043f },
+ { 0x06d1, 0x044f },
+ { 0x06d2, 0x0440 },
+ { 0x06d3, 0x0441 },
+ { 0x06d4, 0x0442 },
+ { 0x06d5, 0x0443 },
+ { 0x06d6, 0x0436 },
+ { 0x06d7, 0x0432 },
+ { 0x06d8, 0x044c },
+ { 0x06d9, 0x044b },
+ { 0x06da, 0x0437 },
+ { 0x06db, 0x0448 },
+ { 0x06dc, 0x044d },
+ { 0x06dd, 0x0449 },
+ { 0x06de, 0x0447 },
+ { 0x06df, 0x044a },
+ { 0x06e0, 0x042e },
+ { 0x06e1, 0x0410 },
+ { 0x06e2, 0x0411 },
+ { 0x06e3, 0x0426 },
+ { 0x06e4, 0x0414 },
+ { 0x06e5, 0x0415 },
+ { 0x06e6, 0x0424 },
+ { 0x06e7, 0x0413 },
+ { 0x06e8, 0x0425 },
+ { 0x06e9, 0x0418 },
+ { 0x06ea, 0x0419 },
+ { 0x06eb, 0x041a },
+ { 0x06ec, 0x041b },
+ { 0x06ed, 0x041c },
+ { 0x06ee, 0x041d },
+ { 0x06ef, 0x041e },
+ { 0x06f0, 0x041f },
+ { 0x06f1, 0x042f },
+ { 0x06f2, 0x0420 },
+ { 0x06f3, 0x0421 },
+ { 0x06f4, 0x0422 },
+ { 0x06f5, 0x0423 },
+ { 0x06f6, 0x0416 },
+ { 0x06f7, 0x0412 },
+ { 0x06f8, 0x042c },
+ { 0x06f9, 0x042b },
+ { 0x06fa, 0x0417 },
+ { 0x06fb, 0x0428 },
+ { 0x06fc, 0x042d },
+ { 0x06fd, 0x0429 },
+ { 0x06fe, 0x0427 },
+ { 0x06ff, 0x042a },
+ { 0x07a1, 0x0386 },
+ { 0x07a2, 0x0388 },
+ { 0x07a3, 0x0389 },
+ { 0x07a4, 0x038a },
+ { 0x07a5, 0x03aa },
+ { 0x07a7, 0x038c },
+ { 0x07a8, 0x038e },
+ { 0x07a9, 0x03ab },
+ { 0x07ab, 0x038f },
+ { 0x07ae, 0x0385 },
+ { 0x07af, 0x2015 },
+ { 0x07b1, 0x03ac },
+ { 0x07b2, 0x03ad },
+ { 0x07b3, 0x03ae },
+ { 0x07b4, 0x03af },
+ { 0x07b5, 0x03ca },
+ { 0x07b6, 0x0390 },
+ { 0x07b7, 0x03cc },
+ { 0x07b8, 0x03cd },
+ { 0x07b9, 0x03cb },
+ { 0x07ba, 0x03b0 },
+ { 0x07bb, 0x03ce },
+ { 0x07c1, 0x0391 },
+ { 0x07c2, 0x0392 },
+ { 0x07c3, 0x0393 },
+ { 0x07c4, 0x0394 },
+ { 0x07c5, 0x0395 },
+ { 0x07c6, 0x0396 },
+ { 0x07c7, 0x0397 },
+ { 0x07c8, 0x0398 },
+ { 0x07c9, 0x0399 },
+ { 0x07ca, 0x039a },
+ { 0x07cb, 0x039b },
+ { 0x07cc, 0x039c },
+ { 0x07cd, 0x039d },
+ { 0x07ce, 0x039e },
+ { 0x07cf, 0x039f },
+ { 0x07d0, 0x03a0 },
+ { 0x07d1, 0x03a1 },
+ { 0x07d2, 0x03a3 },
+ { 0x07d4, 0x03a4 },
+ { 0x07d5, 0x03a5 },
+ { 0x07d6, 0x03a6 },
+ { 0x07d7, 0x03a7 },
+ { 0x07d8, 0x03a8 },
+ { 0x07d9, 0x03a9 },
+ { 0x07e1, 0x03b1 },
+ { 0x07e2, 0x03b2 },
+ { 0x07e3, 0x03b3 },
+ { 0x07e4, 0x03b4 },
+ { 0x07e5, 0x03b5 },
+ { 0x07e6, 0x03b6 },
+ { 0x07e7, 0x03b7 },
+ { 0x07e8, 0x03b8 },
+ { 0x07e9, 0x03b9 },
+ { 0x07ea, 0x03ba },
+ { 0x07eb, 0x03bb },
+ { 0x07ec, 0x03bc },
+ { 0x07ed, 0x03bd },
+ { 0x07ee, 0x03be },
+ { 0x07ef, 0x03bf },
+ { 0x07f0, 0x03c0 },
+ { 0x07f1, 0x03c1 },
+ { 0x07f2, 0x03c3 },
+ { 0x07f3, 0x03c2 },
+ { 0x07f4, 0x03c4 },
+ { 0x07f5, 0x03c5 },
+ { 0x07f6, 0x03c6 },
+ { 0x07f7, 0x03c7 },
+ { 0x07f8, 0x03c8 },
+ { 0x07f9, 0x03c9 },
+ { 0x08a1, 0x23b7 },
+ { 0x08a2, 0x250c },
+ { 0x08a3, 0x2500 },
+ { 0x08a4, 0x2320 },
+ { 0x08a5, 0x2321 },
+ { 0x08a6, 0x2502 },
+ { 0x08a7, 0x23a1 },
+ { 0x08a8, 0x23a3 },
+ { 0x08a9, 0x23a4 },
+ { 0x08aa, 0x23a6 },
+ { 0x08ab, 0x239b },
+ { 0x08ac, 0x239d },
+ { 0x08ad, 0x239e },
+ { 0x08ae, 0x23a0 },
+ { 0x08af, 0x23a8 },
+ { 0x08b0, 0x23ac },
+ { 0x08bc, 0x2264 },
+ { 0x08bd, 0x2260 },
+ { 0x08be, 0x2265 },
+ { 0x08bf, 0x222b },
+ { 0x08c0, 0x2234 },
+ { 0x08c1, 0x221d },
+ { 0x08c2, 0x221e },
+ { 0x08c5, 0x2207 },
+ { 0x08c8, 0x223c },
+ { 0x08c9, 0x2243 },
+ { 0x08cd, 0x21d4 },
+ { 0x08ce, 0x21d2 },
+ { 0x08cf, 0x2261 },
+ { 0x08d6, 0x221a },
+ { 0x08da, 0x2282 },
+ { 0x08db, 0x2283 },
+ { 0x08dc, 0x2229 },
+ { 0x08dd, 0x222a },
+ { 0x08de, 0x2227 },
+ { 0x08df, 0x2228 },
+ { 0x08ef, 0x2202 },
+ { 0x08f6, 0x0192 },
+ { 0x08fb, 0x2190 },
+ { 0x08fc, 0x2191 },
+ { 0x08fd, 0x2192 },
+ { 0x08fe, 0x2193 },
+ { 0x09e0, 0x25c6 },
+ { 0x09e1, 0x2592 },
+ { 0x09e2, 0x2409 },
+ { 0x09e3, 0x240c },
+ { 0x09e4, 0x240d },
+ { 0x09e5, 0x240a },
+ { 0x09e8, 0x2424 },
+ { 0x09e9, 0x240b },
+ { 0x09ea, 0x2518 },
+ { 0x09eb, 0x2510 },
+ { 0x09ec, 0x250c },
+ { 0x09ed, 0x2514 },
+ { 0x09ee, 0x253c },
+ { 0x09ef, 0x23ba },
+ { 0x09f0, 0x23bb },
+ { 0x09f1, 0x2500 },
+ { 0x09f2, 0x23bc },
+ { 0x09f3, 0x23bd },
+ { 0x09f4, 0x251c },
+ { 0x09f5, 0x2524 },
+ { 0x09f6, 0x2534 },
+ { 0x09f7, 0x252c },
+ { 0x09f8, 0x2502 },
+ { 0x0aa1, 0x2003 },
+ { 0x0aa2, 0x2002 },
+ { 0x0aa3, 0x2004 },
+ { 0x0aa4, 0x2005 },
+ { 0x0aa5, 0x2007 },
+ { 0x0aa6, 0x2008 },
+ { 0x0aa7, 0x2009 },
+ { 0x0aa8, 0x200a },
+ { 0x0aa9, 0x2014 },
+ { 0x0aaa, 0x2013 },
+ { 0x0aae, 0x2026 },
+ { 0x0aaf, 0x2025 },
+ { 0x0ab0, 0x2153 },
+ { 0x0ab1, 0x2154 },
+ { 0x0ab2, 0x2155 },
+ { 0x0ab3, 0x2156 },
+ { 0x0ab4, 0x2157 },
+ { 0x0ab5, 0x2158 },
+ { 0x0ab6, 0x2159 },
+ { 0x0ab7, 0x215a },
+ { 0x0ab8, 0x2105 },
+ { 0x0abb, 0x2012 },
+ { 0x0abc, 0x2329 },
+ { 0x0abe, 0x232a },
+ { 0x0ac3, 0x215b },
+ { 0x0ac4, 0x215c },
+ { 0x0ac5, 0x215d },
+ { 0x0ac6, 0x215e },
+ { 0x0ac9, 0x2122 },
+ { 0x0aca, 0x2613 },
+ { 0x0acc, 0x25c1 },
+ { 0x0acd, 0x25b7 },
+ { 0x0ace, 0x25cb },
+ { 0x0acf, 0x25af },
+ { 0x0ad0, 0x2018 },
+ { 0x0ad1, 0x2019 },
+ { 0x0ad2, 0x201c },
+ { 0x0ad3, 0x201d },
+ { 0x0ad4, 0x211e },
+ { 0x0ad6, 0x2032 },
+ { 0x0ad7, 0x2033 },
+ { 0x0ad9, 0x271d },
+ { 0x0adb, 0x25ac },
+ { 0x0adc, 0x25c0 },
+ { 0x0add, 0x25b6 },
+ { 0x0ade, 0x25cf },
+ { 0x0adf, 0x25ae },
+ { 0x0ae0, 0x25e6 },
+ { 0x0ae1, 0x25ab },
+ { 0x0ae2, 0x25ad },
+ { 0x0ae3, 0x25b3 },
+ { 0x0ae4, 0x25bd },
+ { 0x0ae5, 0x2606 },
+ { 0x0ae6, 0x2022 },
+ { 0x0ae7, 0x25aa },
+ { 0x0ae8, 0x25b2 },
+ { 0x0ae9, 0x25bc },
+ { 0x0aea, 0x261c },
+ { 0x0aeb, 0x261e },
+ { 0x0aec, 0x2663 },
+ { 0x0aed, 0x2666 },
+ { 0x0aee, 0x2665 },
+ { 0x0af0, 0x2720 },
+ { 0x0af1, 0x2020 },
+ { 0x0af2, 0x2021 },
+ { 0x0af3, 0x2713 },
+ { 0x0af4, 0x2717 },
+ { 0x0af5, 0x266f },
+ { 0x0af6, 0x266d },
+ { 0x0af7, 0x2642 },
+ { 0x0af8, 0x2640 },
+ { 0x0af9, 0x260e },
+ { 0x0afa, 0x2315 },
+ { 0x0afb, 0x2117 },
+ { 0x0afc, 0x2038 },
+ { 0x0afd, 0x201a },
+ { 0x0afe, 0x201e },
+ { 0x0ba3, 0x003c },
+ { 0x0ba6, 0x003e },
+ { 0x0ba8, 0x2228 },
+ { 0x0ba9, 0x2227 },
+ { 0x0bc0, 0x00af },
+ { 0x0bc2, 0x22a5 },
+ { 0x0bc3, 0x2229 },
+ { 0x0bc4, 0x230a },
+ { 0x0bc6, 0x005f },
+ { 0x0bca, 0x2218 },
+ { 0x0bcc, 0x2395 },
+ { 0x0bce, 0x22a4 },
+ { 0x0bcf, 0x25cb },
+ { 0x0bd3, 0x2308 },
+ { 0x0bd6, 0x222a },
+ { 0x0bd8, 0x2283 },
+ { 0x0bda, 0x2282 },
+ { 0x0bdc, 0x22a2 },
+ { 0x0bfc, 0x22a3 },
+ { 0x0cdf, 0x2017 },
+ { 0x0ce0, 0x05d0 },
+ { 0x0ce1, 0x05d1 },
+ { 0x0ce2, 0x05d2 },
+ { 0x0ce3, 0x05d3 },
+ { 0x0ce4, 0x05d4 },
+ { 0x0ce5, 0x05d5 },
+ { 0x0ce6, 0x05d6 },
+ { 0x0ce7, 0x05d7 },
+ { 0x0ce8, 0x05d8 },
+ { 0x0ce9, 0x05d9 },
+ { 0x0cea, 0x05da },
+ { 0x0ceb, 0x05db },
+ { 0x0cec, 0x05dc },
+ { 0x0ced, 0x05dd },
+ { 0x0cee, 0x05de },
+ { 0x0cef, 0x05df },
+ { 0x0cf0, 0x05e0 },
+ { 0x0cf1, 0x05e1 },
+ { 0x0cf2, 0x05e2 },
+ { 0x0cf3, 0x05e3 },
+ { 0x0cf4, 0x05e4 },
+ { 0x0cf5, 0x05e5 },
+ { 0x0cf6, 0x05e6 },
+ { 0x0cf7, 0x05e7 },
+ { 0x0cf8, 0x05e8 },
+ { 0x0cf9, 0x05e9 },
+ { 0x0cfa, 0x05ea },
+ { 0x0da1, 0x0e01 },
+ { 0x0da2, 0x0e02 },
+ { 0x0da3, 0x0e03 },
+ { 0x0da4, 0x0e04 },
+ { 0x0da5, 0x0e05 },
+ { 0x0da6, 0x0e06 },
+ { 0x0da7, 0x0e07 },
+ { 0x0da8, 0x0e08 },
+ { 0x0da9, 0x0e09 },
+ { 0x0daa, 0x0e0a },
+ { 0x0dab, 0x0e0b },
+ { 0x0dac, 0x0e0c },
+ { 0x0dad, 0x0e0d },
+ { 0x0dae, 0x0e0e },
+ { 0x0daf, 0x0e0f },
+ { 0x0db0, 0x0e10 },
+ { 0x0db1, 0x0e11 },
+ { 0x0db2, 0x0e12 },
+ { 0x0db3, 0x0e13 },
+ { 0x0db4, 0x0e14 },
+ { 0x0db5, 0x0e15 },
+ { 0x0db6, 0x0e16 },
+ { 0x0db7, 0x0e17 },
+ { 0x0db8, 0x0e18 },
+ { 0x0db9, 0x0e19 },
+ { 0x0dba, 0x0e1a },
+ { 0x0dbb, 0x0e1b },
+ { 0x0dbc, 0x0e1c },
+ { 0x0dbd, 0x0e1d },
+ { 0x0dbe, 0x0e1e },
+ { 0x0dbf, 0x0e1f },
+ { 0x0dc0, 0x0e20 },
+ { 0x0dc1, 0x0e21 },
+ { 0x0dc2, 0x0e22 },
+ { 0x0dc3, 0x0e23 },
+ { 0x0dc4, 0x0e24 },
+ { 0x0dc5, 0x0e25 },
+ { 0x0dc6, 0x0e26 },
+ { 0x0dc7, 0x0e27 },
+ { 0x0dc8, 0x0e28 },
+ { 0x0dc9, 0x0e29 },
+ { 0x0dca, 0x0e2a },
+ { 0x0dcb, 0x0e2b },
+ { 0x0dcc, 0x0e2c },
+ { 0x0dcd, 0x0e2d },
+ { 0x0dce, 0x0e2e },
+ { 0x0dcf, 0x0e2f },
+ { 0x0dd0, 0x0e30 },
+ { 0x0dd1, 0x0e31 },
+ { 0x0dd2, 0x0e32 },
+ { 0x0dd3, 0x0e33 },
+ { 0x0dd4, 0x0e34 },
+ { 0x0dd5, 0x0e35 },
+ { 0x0dd6, 0x0e36 },
+ { 0x0dd7, 0x0e37 },
+ { 0x0dd8, 0x0e38 },
+ { 0x0dd9, 0x0e39 },
+ { 0x0dda, 0x0e3a },
+ { 0x0ddf, 0x0e3f },
+ { 0x0de0, 0x0e40 },
+ { 0x0de1, 0x0e41 },
+ { 0x0de2, 0x0e42 },
+ { 0x0de3, 0x0e43 },
+ { 0x0de4, 0x0e44 },
+ { 0x0de5, 0x0e45 },
+ { 0x0de6, 0x0e46 },
+ { 0x0de7, 0x0e47 },
+ { 0x0de8, 0x0e48 },
+ { 0x0de9, 0x0e49 },
+ { 0x0dea, 0x0e4a },
+ { 0x0deb, 0x0e4b },
+ { 0x0dec, 0x0e4c },
+ { 0x0ded, 0x0e4d },
+ { 0x0df0, 0x0e50 },
+ { 0x0df1, 0x0e51 },
+ { 0x0df2, 0x0e52 },
+ { 0x0df3, 0x0e53 },
+ { 0x0df4, 0x0e54 },
+ { 0x0df5, 0x0e55 },
+ { 0x0df6, 0x0e56 },
+ { 0x0df7, 0x0e57 },
+ { 0x0df8, 0x0e58 },
+ { 0x0df9, 0x0e59 },
+ { 0x0ea1, 0x3131 },
+ { 0x0ea2, 0x3132 },
+ { 0x0ea3, 0x3133 },
+ { 0x0ea4, 0x3134 },
+ { 0x0ea5, 0x3135 },
+ { 0x0ea6, 0x3136 },
+ { 0x0ea7, 0x3137 },
+ { 0x0ea8, 0x3138 },
+ { 0x0ea9, 0x3139 },
+ { 0x0eaa, 0x313a },
+ { 0x0eab, 0x313b },
+ { 0x0eac, 0x313c },
+ { 0x0ead, 0x313d },
+ { 0x0eae, 0x313e },
+ { 0x0eaf, 0x313f },
+ { 0x0eb0, 0x3140 },
+ { 0x0eb1, 0x3141 },
+ { 0x0eb2, 0x3142 },
+ { 0x0eb3, 0x3143 },
+ { 0x0eb4, 0x3144 },
+ { 0x0eb5, 0x3145 },
+ { 0x0eb6, 0x3146 },
+ { 0x0eb7, 0x3147 },
+ { 0x0eb8, 0x3148 },
+ { 0x0eb9, 0x3149 },
+ { 0x0eba, 0x314a },
+ { 0x0ebb, 0x314b },
+ { 0x0ebc, 0x314c },
+ { 0x0ebd, 0x314d },
+ { 0x0ebe, 0x314e },
+ { 0x0ebf, 0x314f },
+ { 0x0ec0, 0x3150 },
+ { 0x0ec1, 0x3151 },
+ { 0x0ec2, 0x3152 },
+ { 0x0ec3, 0x3153 },
+ { 0x0ec4, 0x3154 },
+ { 0x0ec5, 0x3155 },
+ { 0x0ec6, 0x3156 },
+ { 0x0ec7, 0x3157 },
+ { 0x0ec8, 0x3158 },
+ { 0x0ec9, 0x3159 },
+ { 0x0eca, 0x315a },
+ { 0x0ecb, 0x315b },
+ { 0x0ecc, 0x315c },
+ { 0x0ecd, 0x315d },
+ { 0x0ece, 0x315e },
+ { 0x0ecf, 0x315f },
+ { 0x0ed0, 0x3160 },
+ { 0x0ed1, 0x3161 },
+ { 0x0ed2, 0x3162 },
+ { 0x0ed3, 0x3163 },
+ { 0x0ed4, 0x11a8 },
+ { 0x0ed5, 0x11a9 },
+ { 0x0ed6, 0x11aa },
+ { 0x0ed7, 0x11ab },
+ { 0x0ed8, 0x11ac },
+ { 0x0ed9, 0x11ad },
+ { 0x0eda, 0x11ae },
+ { 0x0edb, 0x11af },
+ { 0x0edc, 0x11b0 },
+ { 0x0edd, 0x11b1 },
+ { 0x0ede, 0x11b2 },
+ { 0x0edf, 0x11b3 },
+ { 0x0ee0, 0x11b4 },
+ { 0x0ee1, 0x11b5 },
+ { 0x0ee2, 0x11b6 },
+ { 0x0ee3, 0x11b7 },
+ { 0x0ee4, 0x11b8 },
+ { 0x0ee5, 0x11b9 },
+ { 0x0ee6, 0x11ba },
+ { 0x0ee7, 0x11bb },
+ { 0x0ee8, 0x11bc },
+ { 0x0ee9, 0x11bd },
+ { 0x0eea, 0x11be },
+ { 0x0eeb, 0x11bf },
+ { 0x0eec, 0x11c0 },
+ { 0x0eed, 0x11c1 },
+ { 0x0eee, 0x11c2 },
+ { 0x0eef, 0x316d },
+ { 0x0ef0, 0x3171 },
+ { 0x0ef1, 0x3178 },
+ { 0x0ef2, 0x317f },
+ { 0x0ef3, 0x3181 },
+ { 0x0ef4, 0x3184 },
+ { 0x0ef5, 0x3186 },
+ { 0x0ef6, 0x318d },
+ { 0x0ef7, 0x318e },
+ { 0x0ef8, 0x11eb },
+ { 0x0ef9, 0x11f0 },
+ { 0x0efa, 0x11f9 },
+ { 0x0eff, 0x20a9 },
+ { 0x13a4, 0x20ac },
+ { 0x13bc, 0x0152 },
+ { 0x13bd, 0x0153 },
+ { 0x13be, 0x0178 },
+ { 0x20ac, 0x20ac },
+ { 0xfe50, '`' },
+ { 0xfe51, 0x00b4 },
+ { 0xfe52, '^' },
+ { 0xfe53, '~' },
+ { 0xfe54, 0x00af },
+ { 0xfe55, 0x02d8 },
+ { 0xfe56, 0x02d9 },
+ { 0xfe57, 0x00a8 },
+ { 0xfe58, 0x02da },
+ { 0xfe59, 0x02dd },
+ { 0xfe5a, 0x02c7 },
+ { 0xfe5b, 0x00b8 },
+ { 0xfe5c, 0x02db },
+ { 0xfe5d, 0x037a },
+ { 0xfe5e, 0x309b },
+ { 0xfe5f, 0x309c },
+ { 0xfe63, '/' },
+ { 0xfe64, 0x02bc },
+ { 0xfe65, 0x02bd },
+ { 0xfe66, 0x02f5 },
+ { 0xfe67, 0x02f3 },
+ { 0xfe68, 0x02cd },
+ { 0xfe69, 0xa788 },
+ { 0xfe6a, 0x02f7 },
+ { 0xfe6e, ',' },
+ { 0xfe6f, 0x00a4 },
+ { 0xfe80, 'a' }, // XK_dead_a
+ { 0xfe81, 'A' }, // XK_dead_A
+ { 0xfe82, 'e' }, // XK_dead_e
+ { 0xfe83, 'E' }, // XK_dead_E
+ { 0xfe84, 'i' }, // XK_dead_i
+ { 0xfe85, 'I' }, // XK_dead_I
+ { 0xfe86, 'o' }, // XK_dead_o
+ { 0xfe87, 'O' }, // XK_dead_O
+ { 0xfe88, 'u' }, // XK_dead_u
+ { 0xfe89, 'U' }, // XK_dead_U
+ { 0xfe8a, 0x0259 },
+ { 0xfe8b, 0x018f },
+ { 0xfe8c, 0x00b5 },
+ { 0xfe90, '_' },
+ { 0xfe91, 0x02c8 },
+ { 0xfe92, 0x02cc },
+ { 0xff80 /*XKB_KEY_KP_Space*/, ' ' },
+ { 0xff95 /*XKB_KEY_KP_7*/, 0x0037 },
+ { 0xff96 /*XKB_KEY_KP_4*/, 0x0034 },
+ { 0xff97 /*XKB_KEY_KP_8*/, 0x0038 },
+ { 0xff98 /*XKB_KEY_KP_6*/, 0x0036 },
+ { 0xff99 /*XKB_KEY_KP_2*/, 0x0032 },
+ { 0xff9a /*XKB_KEY_KP_9*/, 0x0039 },
+ { 0xff9b /*XKB_KEY_KP_3*/, 0x0033 },
+ { 0xff9c /*XKB_KEY_KP_1*/, 0x0031 },
+ { 0xff9d /*XKB_KEY_KP_5*/, 0x0035 },
+ { 0xff9e /*XKB_KEY_KP_0*/, 0x0030 },
+ { 0xffaa /*XKB_KEY_KP_Multiply*/, '*' },
+ { 0xffab /*XKB_KEY_KP_Add*/, '+' },
+ { 0xffac /*XKB_KEY_KP_Separator*/, ',' },
+ { 0xffad /*XKB_KEY_KP_Subtract*/, '-' },
+ { 0xffae /*XKB_KEY_KP_Decimal*/, '.' },
+ { 0xffaf /*XKB_KEY_KP_Divide*/, '/' },
+ { 0xffb0 /*XKB_KEY_KP_0*/, 0x0030 },
+ { 0xffb1 /*XKB_KEY_KP_1*/, 0x0031 },
+ { 0xffb2 /*XKB_KEY_KP_2*/, 0x0032 },
+ { 0xffb3 /*XKB_KEY_KP_3*/, 0x0033 },
+ { 0xffb4 /*XKB_KEY_KP_4*/, 0x0034 },
+ { 0xffb5 /*XKB_KEY_KP_5*/, 0x0035 },
+ { 0xffb6 /*XKB_KEY_KP_6*/, 0x0036 },
+ { 0xffb7 /*XKB_KEY_KP_7*/, 0x0037 },
+ { 0xffb8 /*XKB_KEY_KP_8*/, 0x0038 },
+ { 0xffb9 /*XKB_KEY_KP_9*/, 0x0039 },
+ { 0xffbd /*XKB_KEY_KP_Equal*/, '=' }
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+// Convert XKB KeySym to Unicode
+//
+long _glfwKeySym2Unicode(unsigned int keysym)
+{
+ int min = 0;
+ int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
+ int mid;
+
+ // First check for Latin-1 characters (1:1 mapping)
+ if ((keysym >= 0x0020 && keysym <= 0x007e) ||
+ (keysym >= 0x00a0 && keysym <= 0x00ff))
+ {
+ return keysym;
+ }
+
+ // Also check for directly encoded 24-bit UCS characters
+ if ((keysym & 0xff000000) == 0x01000000)
+ return keysym & 0x00ffffff;
+
+ // Binary search in table
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (keysymtab[mid].keysym < keysym)
+ min = mid + 1;
+ else if (keysymtab[mid].keysym > keysym)
+ max = mid - 1;
+ else
+ return keysymtab[mid].ucs;
+ }
+
+ // No matching Unicode value found
+ return -1;
+}
+
diff --git a/src/external/glfw/src/xkb_unicode.h b/src/external/glfw/src/xkb_unicode.h
new file mode 100644
index 00000000..f95e14f1
--- /dev/null
+++ b/src/external/glfw/src/xkb_unicode.h
@@ -0,0 +1,28 @@
+//========================================================================
+// GLFW 3.3 Linux - www.glfw.org
+//------------------------------------------------------------------------
+// Copyright (c) 2014 Jonas Ã…dahl <[email protected]>
+//
+// 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.
+//
+//========================================================================
+
+long _glfwKeySym2Unicode(unsigned int keysym);
+
diff --git a/src/external/include/GLFW/glfw3.h b/src/external/include/GLFW/glfw3.h
deleted file mode 100644
index 5a0c4508..00000000
--- a/src/external/include/GLFW/glfw3.h
+++ /dev/null
@@ -1,4235 +0,0 @@
-/*************************************************************************
- * GLFW 3.2 - www.glfw.org
- * A library for OpenGL, window and input
- *------------------------------------------------------------------------
- * Copyright (c) 2002-2006 Marcus Geelnard
- * Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
- *
- * 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.
- *
- *************************************************************************/
-
-#ifndef _glfw3_h_
-#define _glfw3_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*************************************************************************
- * Doxygen documentation
- *************************************************************************/
-
-/*! @file glfw3.h
- * @brief The header of the GLFW 3 API.
- *
- * This is the header file of the GLFW 3 API. It defines all its types and
- * declares all its functions.
- *
- * For more information about how to use this file, see @ref build_include.
- */
-/*! @defgroup context Context reference
- *
- * This is the reference documentation for OpenGL and OpenGL ES context related
- * functions. For more task-oriented information, see the @ref context_guide.
- */
-/*! @defgroup vulkan Vulkan reference
- *
- * This is the reference documentation for Vulkan related functions and types.
- * For more task-oriented information, see the @ref vulkan_guide.
- */
-/*! @defgroup init Initialization, version and error reference
- *
- * This is the reference documentation for initialization and termination of
- * the library, version management and error handling. For more task-oriented
- * information, see the @ref intro_guide.
- */
-/*! @defgroup input Input reference
- *
- * This is the reference documentation for input related functions and types.
- * For more task-oriented information, see the @ref input_guide.
- */
-/*! @defgroup monitor Monitor reference
- *
- * This is the reference documentation for monitor related functions and types.
- * For more task-oriented information, see the @ref monitor_guide.
- */
-/*! @defgroup window Window reference
- *
- * This is the reference documentation for window related functions and types,
- * including creation, deletion and event polling. For more task-oriented
- * information, see the @ref window_guide.
- */
-
-
-/*************************************************************************
- * Compiler- and platform-specific preprocessor work
- *************************************************************************/
-
-/* If we are we on Windows, we want a single define for it.
- */
-#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
- #define _WIN32
-#endif /* _WIN32 */
-
-/* It is customary to use APIENTRY for OpenGL function pointer declarations on
- * all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
- */
-#ifndef APIENTRY
- #ifdef _WIN32
- #define APIENTRY __stdcall
- #else
- #define APIENTRY
- #endif
-#endif /* APIENTRY */
-
-/* Some Windows OpenGL headers need this.
- */
-#if !defined(WINGDIAPI) && defined(_WIN32)
- #define WINGDIAPI __declspec(dllimport)
- #define GLFW_WINGDIAPI_DEFINED
-#endif /* WINGDIAPI */
-
-/* Some Windows GLU headers need this.
- */
-#if !defined(CALLBACK) && defined(_WIN32)
- #define CALLBACK __stdcall
- #define GLFW_CALLBACK_DEFINED
-#endif /* CALLBACK */
-
-/* Most Windows GLU headers need wchar_t.
- * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
- * Include it unconditionally to avoid surprising side-effects.
- */
-#include <stddef.h>
-#include <stdint.h>
-
-/* Include the chosen client API headers.
- */
-#if defined(__APPLE__)
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include <OpenGL/gl3.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <OpenGL/gl3ext.h>
- #endif
- #elif !defined(GLFW_INCLUDE_NONE)
- #if !defined(GLFW_INCLUDE_GLEXT)
- #define GL_GLEXT_LEGACY
- #endif
- #include <OpenGL/gl.h>
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include <OpenGL/glu.h>
- #endif
-#else
- #if defined(GLFW_INCLUDE_GLCOREARB)
- #include <GL/glcorearb.h>
- #elif defined(GLFW_INCLUDE_ES1)
- #include <GLES/gl.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES/glext.h>
- #endif
- #elif defined(GLFW_INCLUDE_ES2)
- #include <GLES2/gl2.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES2/gl2ext.h>
- #endif
- #elif defined(GLFW_INCLUDE_ES3)
- #include <GLES3/gl3.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES2/gl2ext.h>
- #endif
- #elif defined(GLFW_INCLUDE_ES31)
- #include <GLES3/gl31.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GLES2/gl2ext.h>
- #endif
- #elif defined(GLFW_INCLUDE_VULKAN)
- #include <vulkan/vulkan.h>
- #elif !defined(GLFW_INCLUDE_NONE)
- #include <GL/gl.h>
- #if defined(GLFW_INCLUDE_GLEXT)
- #include <GL/glext.h>
- #endif
- #endif
- #if defined(GLFW_INCLUDE_GLU)
- #include <GL/glu.h>
- #endif
-#endif
-
-#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
- /* GLFW_DLL must be defined by applications that are linking against the DLL
- * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
- * configuration header when compiling the DLL version of the library.
- */
- #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
-#endif
-
-/* GLFWAPI is used to declare public API functions for export
- * from the DLL / shared library / dynamic library.
- */
-#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
- /* We are building GLFW as a Win32 DLL */
- #define GLFWAPI __declspec(dllexport)
-#elif defined(_WIN32) && defined(GLFW_DLL)
- /* We are calling GLFW as a Win32 DLL */
- #define GLFWAPI __declspec(dllimport)
-#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
- /* We are building GLFW as a shared / dynamic library */
- #define GLFWAPI __attribute__((visibility("default")))
-#else
- /* We are building or calling GLFW as a static library */
- #define GLFWAPI
-#endif
-
-
-/*************************************************************************
- * GLFW API tokens
- *************************************************************************/
-
-/*! @name GLFW version macros
- * @{ */
-/*! @brief The major version number of the GLFW library.
- *
- * This is incremented when the API is changed in non-compatible ways.
- * @ingroup init
- */
-#define GLFW_VERSION_MAJOR 3
-/*! @brief The minor version number of the GLFW library.
- *
- * This is incremented when features are added to the API but it remains
- * backward-compatible.
- * @ingroup init
- */
-#define GLFW_VERSION_MINOR 2
-/*! @brief The revision number of the GLFW library.
- *
- * This is incremented when a bug fix release is made that does not contain any
- * API changes.
- * @ingroup init
- */
-#define GLFW_VERSION_REVISION 0
-/*! @} */
-
-/*! @name Boolean values
- * @{ */
-/*! @brief One.
- *
- * One. Seriously. You don't _need_ to use this symbol in your code. It's
- * just semantic sugar for the number 1. You can use `1` or `true` or `_True`
- * or `GL_TRUE` or whatever you want.
- */
-#define GLFW_TRUE 1
-/*! @brief Zero.
- *
- * Zero. Seriously. You don't _need_ to use this symbol in your code. It's
- * just just semantic sugar for the number 0. You can use `0` or `false` or
- * `_False` or `GL_FALSE` or whatever you want.
- */
-#define GLFW_FALSE 0
-/*! @} */
-
-/*! @name Key and button actions
- * @{ */
-/*! @brief The key or mouse button was released.
- *
- * The key or mouse button was released.
- *
- * @ingroup input
- */
-#define GLFW_RELEASE 0
-/*! @brief The key or mouse button was pressed.
- *
- * The key or mouse button was pressed.
- *
- * @ingroup input
- */
-#define GLFW_PRESS 1
-/*! @brief The key was held down until it repeated.
- *
- * The key was held down until it repeated.
- *
- * @ingroup input
- */
-#define GLFW_REPEAT 2
-/*! @} */
-
-/*! @defgroup keys Keyboard keys
- *
- * See [key input](@ref input_key) for how these are used.
- *
- * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60),
- * but re-arranged to map to 7-bit ASCII for printable keys (function keys are
- * put in the 256+ range).
- *
- * The naming of the key codes follow these rules:
- * - The US keyboard layout is used
- * - Names of printable alpha-numeric characters are used (e.g. "A", "R",
- * "3", etc.)
- * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
- * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
- * correspond to the Unicode standard (usually for brevity)
- * - Keys that lack a clear US mapping are named "WORLD_x"
- * - For non-printable keys, custom names are used (e.g. "F4",
- * "BACKSPACE", etc.)
- *
- * @ingroup input
- * @{
- */
-
-/* The unknown key */
-#define GLFW_KEY_UNKNOWN -1
-
-/* Printable keys */
-#define GLFW_KEY_SPACE 32
-#define GLFW_KEY_APOSTROPHE 39 /* ' */
-#define GLFW_KEY_COMMA 44 /* , */
-#define GLFW_KEY_MINUS 45 /* - */
-#define GLFW_KEY_PERIOD 46 /* . */
-#define GLFW_KEY_SLASH 47 /* / */
-#define GLFW_KEY_0 48
-#define GLFW_KEY_1 49
-#define GLFW_KEY_2 50
-#define GLFW_KEY_3 51
-#define GLFW_KEY_4 52
-#define GLFW_KEY_5 53
-#define GLFW_KEY_6 54
-#define GLFW_KEY_7 55
-#define GLFW_KEY_8 56
-#define GLFW_KEY_9 57
-#define GLFW_KEY_SEMICOLON 59 /* ; */
-#define GLFW_KEY_EQUAL 61 /* = */
-#define GLFW_KEY_A 65
-#define GLFW_KEY_B 66
-#define GLFW_KEY_C 67
-#define GLFW_KEY_D 68
-#define GLFW_KEY_E 69
-#define GLFW_KEY_F 70
-#define GLFW_KEY_G 71
-#define GLFW_KEY_H 72
-#define GLFW_KEY_I 73
-#define GLFW_KEY_J 74
-#define GLFW_KEY_K 75
-#define GLFW_KEY_L 76
-#define GLFW_KEY_M 77
-#define GLFW_KEY_N 78
-#define GLFW_KEY_O 79
-#define GLFW_KEY_P 80
-#define GLFW_KEY_Q 81
-#define GLFW_KEY_R 82
-#define GLFW_KEY_S 83
-#define GLFW_KEY_T 84
-#define GLFW_KEY_U 85
-#define GLFW_KEY_V 86
-#define GLFW_KEY_W 87
-#define GLFW_KEY_X 88
-#define GLFW_KEY_Y 89
-#define GLFW_KEY_Z 90
-#define GLFW_KEY_LEFT_BRACKET 91 /* [ */
-#define GLFW_KEY_BACKSLASH 92 /* \ */
-#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */
-#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */
-#define GLFW_KEY_WORLD_1 161 /* non-US #1 */
-#define GLFW_KEY_WORLD_2 162 /* non-US #2 */
-
-/* Function keys */
-#define GLFW_KEY_ESCAPE 256
-#define GLFW_KEY_ENTER 257
-#define GLFW_KEY_TAB 258
-#define GLFW_KEY_BACKSPACE 259
-#define GLFW_KEY_INSERT 260
-#define GLFW_KEY_DELETE 261
-#define GLFW_KEY_RIGHT 262
-#define GLFW_KEY_LEFT 263
-#define GLFW_KEY_DOWN 264
-#define GLFW_KEY_UP 265
-#define GLFW_KEY_PAGE_UP 266
-#define GLFW_KEY_PAGE_DOWN 267
-#define GLFW_KEY_HOME 268
-#define GLFW_KEY_END 269
-#define GLFW_KEY_CAPS_LOCK 280
-#define GLFW_KEY_SCROLL_LOCK 281
-#define GLFW_KEY_NUM_LOCK 282
-#define GLFW_KEY_PRINT_SCREEN 283
-#define GLFW_KEY_PAUSE 284
-#define GLFW_KEY_F1 290
-#define GLFW_KEY_F2 291
-#define GLFW_KEY_F3 292
-#define GLFW_KEY_F4 293
-#define GLFW_KEY_F5 294
-#define GLFW_KEY_F6 295
-#define GLFW_KEY_F7 296
-#define GLFW_KEY_F8 297
-#define GLFW_KEY_F9 298
-#define GLFW_KEY_F10 299
-#define GLFW_KEY_F11 300
-#define GLFW_KEY_F12 301
-#define GLFW_KEY_F13 302
-#define GLFW_KEY_F14 303
-#define GLFW_KEY_F15 304
-#define GLFW_KEY_F16 305
-#define GLFW_KEY_F17 306
-#define GLFW_KEY_F18 307
-#define GLFW_KEY_F19 308
-#define GLFW_KEY_F20 309
-#define GLFW_KEY_F21 310
-#define GLFW_KEY_F22 311
-#define GLFW_KEY_F23 312
-#define GLFW_KEY_F24 313
-#define GLFW_KEY_F25 314
-#define GLFW_KEY_KP_0 320
-#define GLFW_KEY_KP_1 321
-#define GLFW_KEY_KP_2 322
-#define GLFW_KEY_KP_3 323
-#define GLFW_KEY_KP_4 324
-#define GLFW_KEY_KP_5 325
-#define GLFW_KEY_KP_6 326
-#define GLFW_KEY_KP_7 327
-#define GLFW_KEY_KP_8 328
-#define GLFW_KEY_KP_9 329
-#define GLFW_KEY_KP_DECIMAL 330
-#define GLFW_KEY_KP_DIVIDE 331
-#define GLFW_KEY_KP_MULTIPLY 332
-#define GLFW_KEY_KP_SUBTRACT 333
-#define GLFW_KEY_KP_ADD 334
-#define GLFW_KEY_KP_ENTER 335
-#define GLFW_KEY_KP_EQUAL 336
-#define GLFW_KEY_LEFT_SHIFT 340
-#define GLFW_KEY_LEFT_CONTROL 341
-#define GLFW_KEY_LEFT_ALT 342
-#define GLFW_KEY_LEFT_SUPER 343
-#define GLFW_KEY_RIGHT_SHIFT 344
-#define GLFW_KEY_RIGHT_CONTROL 345
-#define GLFW_KEY_RIGHT_ALT 346
-#define GLFW_KEY_RIGHT_SUPER 347
-#define GLFW_KEY_MENU 348
-
-#define GLFW_KEY_LAST GLFW_KEY_MENU
-
-/*! @} */
-
-/*! @defgroup mods Modifier key flags
- *
- * See [key input](@ref input_key) for how these are used.
- *
- * @ingroup input
- * @{ */
-
-/*! @brief If this bit is set one or more Shift keys were held down.
- */
-#define GLFW_MOD_SHIFT 0x0001
-/*! @brief If this bit is set one or more Control keys were held down.
- */
-#define GLFW_MOD_CONTROL 0x0002
-/*! @brief If this bit is set one or more Alt keys were held down.
- */
-#define GLFW_MOD_ALT 0x0004
-/*! @brief If this bit is set one or more Super keys were held down.
- */
-#define GLFW_MOD_SUPER 0x0008
-
-/*! @} */
-
-/*! @defgroup buttons Mouse buttons
- *
- * See [mouse button input](@ref input_mouse_button) for how these are used.
- *
- * @ingroup input
- * @{ */
-#define GLFW_MOUSE_BUTTON_1 0
-#define GLFW_MOUSE_BUTTON_2 1
-#define GLFW_MOUSE_BUTTON_3 2
-#define GLFW_MOUSE_BUTTON_4 3
-#define GLFW_MOUSE_BUTTON_5 4
-#define GLFW_MOUSE_BUTTON_6 5
-#define GLFW_MOUSE_BUTTON_7 6
-#define GLFW_MOUSE_BUTTON_8 7
-#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8
-#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1
-#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2
-#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
-/*! @} */
-
-/*! @defgroup joysticks Joysticks
- *
- * See [joystick input](@ref joystick) for how these are used.
- *
- * @ingroup input
- * @{ */
-#define GLFW_JOYSTICK_1 0
-#define GLFW_JOYSTICK_2 1
-#define GLFW_JOYSTICK_3 2
-#define GLFW_JOYSTICK_4 3
-#define GLFW_JOYSTICK_5 4
-#define GLFW_JOYSTICK_6 5
-#define GLFW_JOYSTICK_7 6
-#define GLFW_JOYSTICK_8 7
-#define GLFW_JOYSTICK_9 8
-#define GLFW_JOYSTICK_10 9
-#define GLFW_JOYSTICK_11 10
-#define GLFW_JOYSTICK_12 11
-#define GLFW_JOYSTICK_13 12
-#define GLFW_JOYSTICK_14 13
-#define GLFW_JOYSTICK_15 14
-#define GLFW_JOYSTICK_16 15
-#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
-/*! @} */
-
-/*! @defgroup errors Error codes
- *
- * See [error handling](@ref error_handling) for how these are used.
- *
- * @ingroup init
- * @{ */
-/*! @brief GLFW has not been initialized.
- *
- * This occurs if a GLFW function was called that must not be called unless the
- * library is [initialized](@ref intro_init).
- *
- * @analysis Application programmer error. Initialize GLFW before calling any
- * function that requires initialization.
- */
-#define GLFW_NOT_INITIALIZED 0x00010001
-/*! @brief No context is current for this thread.
- *
- * This occurs if a GLFW function was called that needs and operates on the
- * current OpenGL or OpenGL ES context but no context is current on the calling
- * thread. One such function is @ref glfwSwapInterval.
- *
- * @analysis Application programmer error. Ensure a context is current before
- * calling functions that require a current context.
- */
-#define GLFW_NO_CURRENT_CONTEXT 0x00010002
-/*! @brief One of the arguments to the function was an invalid enum value.
- *
- * One of the arguments to the function was an invalid enum value, for example
- * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref
- * glfwGetWindowAttrib.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_INVALID_ENUM 0x00010003
-/*! @brief One of the arguments to the function was an invalid value.
- *
- * One of the arguments to the function was an invalid value, for example
- * requesting a non-existent OpenGL or OpenGL ES version like 2.7.
- *
- * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead
- * result in a @ref GLFW_VERSION_UNAVAILABLE error.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_INVALID_VALUE 0x00010004
-/*! @brief A memory allocation failed.
- *
- * A memory allocation failed.
- *
- * @analysis A bug in GLFW or the underlying operating system. Report the bug
- * to our [issue tracker](https://github.com/glfw/glfw/issues).
- */
-#define GLFW_OUT_OF_MEMORY 0x00010005
-/*! @brief GLFW could not find support for the requested API on the system.
- *
- * GLFW could not find support for the requested API on the system.
- *
- * @analysis The installed graphics driver does not support the requested
- * API, or does not support it via the chosen context creation backend.
- * Below are a few examples.
- *
- * @par
- * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only
- * supports OpenGL ES via EGL, while Nvidia and Intel only support it via
- * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa
- * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary
- * driver. Older graphics drivers do not support Vulkan.
- */
-#define GLFW_API_UNAVAILABLE 0x00010006
-/*! @brief The requested OpenGL or OpenGL ES version is not available.
- *
- * The requested OpenGL or OpenGL ES version (including any requested context
- * or framebuffer hints) is not available on this machine.
- *
- * @analysis The machine does not support your requirements. If your
- * application is sufficiently flexible, downgrade your requirements and try
- * again. Otherwise, inform the user that their machine does not match your
- * requirements.
- *
- * @par
- * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0
- * comes out before the 4.x series gets that far, also fail with this error and
- * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions
- * will exist.
- */
-#define GLFW_VERSION_UNAVAILABLE 0x00010007
-/*! @brief A platform-specific error occurred that does not match any of the
- * more specific categories.
- *
- * A platform-specific error occurred that does not match any of the more
- * specific categories.
- *
- * @analysis A bug or configuration error in GLFW, the underlying operating
- * system or its drivers, or a lack of required resources. Report the issue to
- * our [issue tracker](https://github.com/glfw/glfw/issues).
- */
-#define GLFW_PLATFORM_ERROR 0x00010008
-/*! @brief The requested format is not supported or available.
- *
- * If emitted during window creation, the requested pixel format is not
- * supported.
- *
- * If emitted when querying the clipboard, the contents of the clipboard could
- * not be converted to the requested format.
- *
- * @analysis If emitted during window creation, one or more
- * [hard constraints](@ref window_hints_hard) did not match any of the
- * available pixel formats. If your application is sufficiently flexible,
- * downgrade your requirements and try again. Otherwise, inform the user that
- * their machine does not match your requirements.
- *
- * @par
- * If emitted when querying the clipboard, ignore the error or report it to
- * the user, as appropriate.
- */
-#define GLFW_FORMAT_UNAVAILABLE 0x00010009
-/*! @brief The specified window does not have an OpenGL or OpenGL ES context.
- *
- * A window that does not have an OpenGL or OpenGL ES context was passed to
- * a function that requires it to have one.
- *
- * @analysis Application programmer error. Fix the offending call.
- */
-#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
-/*! @} */
-
-#define GLFW_FOCUSED 0x00020001
-#define GLFW_ICONIFIED 0x00020002
-#define GLFW_RESIZABLE 0x00020003
-#define GLFW_VISIBLE 0x00020004
-#define GLFW_DECORATED 0x00020005
-#define GLFW_AUTO_ICONIFY 0x00020006
-#define GLFW_FLOATING 0x00020007
-#define GLFW_MAXIMIZED 0x00020008
-
-#define GLFW_RED_BITS 0x00021001
-#define GLFW_GREEN_BITS 0x00021002
-#define GLFW_BLUE_BITS 0x00021003
-#define GLFW_ALPHA_BITS 0x00021004
-#define GLFW_DEPTH_BITS 0x00021005
-#define GLFW_STENCIL_BITS 0x00021006
-#define GLFW_ACCUM_RED_BITS 0x00021007
-#define GLFW_ACCUM_GREEN_BITS 0x00021008
-#define GLFW_ACCUM_BLUE_BITS 0x00021009
-#define GLFW_ACCUM_ALPHA_BITS 0x0002100A
-#define GLFW_AUX_BUFFERS 0x0002100B
-#define GLFW_STEREO 0x0002100C
-#define GLFW_SAMPLES 0x0002100D
-#define GLFW_SRGB_CAPABLE 0x0002100E
-#define GLFW_REFRESH_RATE 0x0002100F
-#define GLFW_DOUBLEBUFFER 0x00021010
-
-#define GLFW_CLIENT_API 0x00022001
-#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
-#define GLFW_CONTEXT_VERSION_MINOR 0x00022003
-#define GLFW_CONTEXT_REVISION 0x00022004
-#define GLFW_CONTEXT_ROBUSTNESS 0x00022005
-#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006
-#define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007
-#define GLFW_OPENGL_PROFILE 0x00022008
-#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
-#define GLFW_CONTEXT_NO_ERROR 0x0002200A
-#define GLFW_CONTEXT_CREATION_API 0x0002200B
-
-#define GLFW_NO_API 0
-#define GLFW_OPENGL_API 0x00030001
-#define GLFW_OPENGL_ES_API 0x00030002
-
-#define GLFW_NO_ROBUSTNESS 0
-#define GLFW_NO_RESET_NOTIFICATION 0x00031001
-#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002
-
-#define GLFW_OPENGL_ANY_PROFILE 0
-#define GLFW_OPENGL_CORE_PROFILE 0x00032001
-#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002
-
-#define GLFW_CURSOR 0x00033001
-#define GLFW_STICKY_KEYS 0x00033002
-#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003
-
-#define GLFW_CURSOR_NORMAL 0x00034001
-#define GLFW_CURSOR_HIDDEN 0x00034002
-#define GLFW_CURSOR_DISABLED 0x00034003
-
-#define GLFW_ANY_RELEASE_BEHAVIOR 0
-#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
-#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
-
-#define GLFW_NATIVE_CONTEXT_API 0x00036001
-#define GLFW_EGL_CONTEXT_API 0x00036002
-
-/*! @defgroup shapes Standard cursor shapes
- *
- * See [standard cursor creation](@ref cursor_standard) for how these are used.
- *
- * @ingroup input
- * @{ */
-
-/*! @brief The regular arrow cursor shape.
- *
- * The regular arrow cursor.
- */
-#define GLFW_ARROW_CURSOR 0x00036001
-/*! @brief The text input I-beam cursor shape.
- *
- * The text input I-beam cursor shape.
- */
-#define GLFW_IBEAM_CURSOR 0x00036002
-/*! @brief The crosshair shape.
- *
- * The crosshair shape.
- */
-#define GLFW_CROSSHAIR_CURSOR 0x00036003
-/*! @brief The hand shape.
- *
- * The hand shape.
- */
-#define GLFW_HAND_CURSOR 0x00036004
-/*! @brief The horizontal resize arrow shape.
- *
- * The horizontal resize arrow shape.
- */
-#define GLFW_HRESIZE_CURSOR 0x00036005
-/*! @brief The vertical resize arrow shape.
- *
- * The vertical resize arrow shape.
- */
-#define GLFW_VRESIZE_CURSOR 0x00036006
-/*! @} */
-
-#define GLFW_CONNECTED 0x00040001
-#define GLFW_DISCONNECTED 0x00040002
-
-#define GLFW_DONT_CARE -1
-
-
-/*************************************************************************
- * GLFW API types
- *************************************************************************/
-
-/*! @brief Client API function pointer type.
- *
- * Generic function pointer used for returning client API function pointers
- * without forcing a cast from a regular pointer.
- *
- * @sa @ref context_glext
- * @sa glfwGetProcAddress
- *
- * @since Added in version 3.0.
-
- * @ingroup context
- */
-typedef void (*GLFWglproc)(void);
-
-/*! @brief Vulkan API function pointer type.
- *
- * Generic function pointer used for returning Vulkan API function pointers
- * without forcing a cast from a regular pointer.
- *
- * @sa @ref vulkan_proc
- * @sa glfwGetInstanceProcAddress
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-typedef void (*GLFWvkproc)(void);
-
-/*! @brief Opaque monitor object.
- *
- * Opaque monitor object.
- *
- * @see @ref monitor_object
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef struct GLFWmonitor GLFWmonitor;
-
-/*! @brief Opaque window object.
- *
- * Opaque window object.
- *
- * @see @ref window_object
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef struct GLFWwindow GLFWwindow;
-
-/*! @brief Opaque cursor object.
- *
- * Opaque cursor object.
- *
- * @see @ref cursor_object
- *
- * @since Added in version 3.1.
- *
- * @ingroup cursor
- */
-typedef struct GLFWcursor GLFWcursor;
-
-/*! @brief The function signature for error callbacks.
- *
- * This is the function signature for error callback functions.
- *
- * @param[in] error An [error code](@ref errors).
- * @param[in] description A UTF-8 encoded string describing the error.
- *
- * @sa @ref error_handling
- * @sa glfwSetErrorCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-typedef void (* GLFWerrorfun)(int,const char*);
-
-/*! @brief The function signature for window position callbacks.
- *
- * This is the function signature for window position callback functions.
- *
- * @param[in] window The window that was moved.
- * @param[in] xpos The new x-coordinate, in screen coordinates, of the
- * upper-left corner of the client area of the window.
- * @param[in] ypos The new y-coordinate, in screen coordinates, of the
- * upper-left corner of the client area of the window.
- *
- * @sa @ref window_pos
- * @sa glfwSetWindowPosCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for window resize callbacks.
- *
- * This is the function signature for window size callback functions.
- *
- * @param[in] window The window that was resized.
- * @param[in] width The new width, in screen coordinates, of the window.
- * @param[in] height The new height, in screen coordinates, of the window.
- *
- * @sa @ref window_size
- * @sa glfwSetWindowSizeCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for window close callbacks.
- *
- * This is the function signature for window close callback functions.
- *
- * @param[in] window The window that the user attempted to close.
- *
- * @sa @ref window_close
- * @sa glfwSetWindowCloseCallback
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowclosefun)(GLFWwindow*);
-
-/*! @brief The function signature for window content refresh callbacks.
- *
- * This is the function signature for window refresh callback functions.
- *
- * @param[in] window The window whose content needs to be refreshed.
- *
- * @sa @ref window_refresh
- * @sa glfwSetWindowRefreshCallback
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
-
-/*! @brief The function signature for window focus/defocus callbacks.
- *
- * This is the function signature for window focus callback functions.
- *
- * @param[in] window The window that gained or lost input focus.
- * @param[in] focused `GLFW_TRUE` if the window was given input focus, or
- * `GLFW_FALSE` if it lost it.
- *
- * @sa @ref window_focus
- * @sa glfwSetWindowFocusCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for window iconify/restore callbacks.
- *
- * This is the function signature for window iconify/restore callback
- * functions.
- *
- * @param[in] window The window that was iconified or restored.
- * @param[in] iconified `GLFW_TRUE` if the window was iconified, or
- * `GLFW_FALSE` if it was restored.
- *
- * @sa @ref window_iconify
- * @sa glfwSetWindowIconifyCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for framebuffer resize callbacks.
- *
- * This is the function signature for framebuffer resize callback
- * functions.
- *
- * @param[in] window The window whose framebuffer was resized.
- * @param[in] width The new width, in pixels, of the framebuffer.
- * @param[in] height The new height, in pixels, of the framebuffer.
- *
- * @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
-
-/*! @brief The function signature for mouse button callbacks.
- *
- * This is the function signature for mouse button callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] button The [mouse button](@ref buttons) that was pressed or
- * released.
- * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_mouse_button
- * @sa glfwSetMouseButtonCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle and modifier mask parameters.
- *
- * @ingroup input
- */
-typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
-
-/*! @brief The function signature for cursor position callbacks.
- *
- * This is the function signature for cursor position callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] xpos The new cursor x-coordinate, relative to the left edge of
- * the client area.
- * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the
- * client area.
- *
- * @sa @ref cursor_pos
- * @sa glfwSetCursorPosCallback
- *
- * @since Added in version 3.0. Replaces `GLFWmouseposfun`.
- *
- * @ingroup input
- */
-typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
-
-/*! @brief The function signature for cursor enter/leave callbacks.
- *
- * This is the function signature for cursor enter/leave callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client
- * area, or `GLFW_FALSE` if it left it.
- *
- * @sa @ref cursor_enter
- * @sa glfwSetCursorEnterCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
-
-/*! @brief The function signature for scroll callbacks.
- *
- * This is the function signature for scroll callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] xoffset The scroll offset along the x-axis.
- * @param[in] yoffset The scroll offset along the y-axis.
- *
- * @sa @ref scrolling
- * @sa glfwSetScrollCallback
- *
- * @since Added in version 3.0. Replaces `GLFWmousewheelfun`.
- *
- * @ingroup input
- */
-typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
-
-/*! @brief The function signature for keyboard key callbacks.
- *
- * This is the function signature for keyboard key callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
- * @param[in] scancode The system-specific scancode of the key.
- * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_key
- * @sa glfwSetKeyCallback
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle, scancode and modifier mask parameters.
- *
- * @ingroup input
- */
-typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
-
-/*! @brief The function signature for Unicode character callbacks.
- *
- * This is the function signature for Unicode character callback functions.
- *
- * @param[in] window The window that received the event.
- * @param[in] codepoint The Unicode code point of the character.
- *
- * @sa @ref input_char
- * @sa glfwSetCharCallback
- *
- * @since Added in version 2.4.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
-
-/*! @brief The function signature for Unicode character with modifiers
- * callbacks.
- *
- * This is the function signature for Unicode character with modifiers callback
- * functions. It is called for each input character, regardless of what
- * modifier keys are held down.
- *
- * @param[in] window The window that received the event.
- * @param[in] codepoint The Unicode code point of the character.
- * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
- * held down.
- *
- * @sa @ref input_char
- * @sa glfwSetCharModsCallback
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
-
-/*! @brief The function signature for file drop callbacks.
- *
- * This is the function signature for file drop callbacks.
- *
- * @param[in] window The window that received the event.
- * @param[in] count The number of dropped files.
- * @param[in] paths The UTF-8 encoded file and/or directory path names.
- *
- * @sa @ref path_drop
- * @sa glfwSetDropCallback
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
-
-/*! @brief The function signature for monitor configuration callbacks.
- *
- * This is the function signature for monitor configuration callback functions.
- *
- * @param[in] monitor The monitor that was connected or disconnected.
- * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
- *
- * @sa @ref monitor_event
- * @sa glfwSetMonitorCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
-
-/*! @brief The function signature for joystick configuration callbacks.
- *
- * This is the function signature for joystick configuration callback
- * functions.
- *
- * @param[in] joy The joystick that was connected or disconnected.
- * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
- *
- * @sa @ref joystick_event
- * @sa glfwSetJoystickCallback
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-typedef void (* GLFWjoystickfun)(int,int);
-
-/*! @brief Video mode type.
- *
- * This describes a single video mode.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoMode glfwGetVideoModes
- *
- * @since Added in version 1.0.
- * @glfw3 Added refresh rate member.
- *
- * @ingroup monitor
- */
-typedef struct GLFWvidmode
-{
- /*! The width, in screen coordinates, of the video mode.
- */
- int width;
- /*! The height, in screen coordinates, of the video mode.
- */
- int height;
- /*! The bit depth of the red channel of the video mode.
- */
- int redBits;
- /*! The bit depth of the green channel of the video mode.
- */
- int greenBits;
- /*! The bit depth of the blue channel of the video mode.
- */
- int blueBits;
- /*! The refresh rate, in Hz, of the video mode.
- */
- int refreshRate;
-} GLFWvidmode;
-
-/*! @brief Gamma ramp.
- *
- * This describes the gamma ramp for a monitor.
- *
- * @sa @ref monitor_gamma
- * @sa glfwGetGammaRamp glfwSetGammaRamp
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-typedef struct GLFWgammaramp
-{
- /*! An array of value describing the response of the red channel.
- */
- unsigned short* red;
- /*! An array of value describing the response of the green channel.
- */
- unsigned short* green;
- /*! An array of value describing the response of the blue channel.
- */
- unsigned short* blue;
- /*! The number of elements in each array.
- */
- unsigned int size;
-} GLFWgammaramp;
-
-/*! @brief Image data.
- *
- * @sa @ref cursor_custom
- *
- * @since Added in version 2.1.
- * @glfw3 Removed format and bytes-per-pixel members.
- */
-typedef struct GLFWimage
-{
- /*! The width, in pixels, of this image.
- */
- int width;
- /*! The height, in pixels, of this image.
- */
- int height;
- /*! The pixel data of this image, arranged left-to-right, top-to-bottom.
- */
- unsigned char* pixels;
-} GLFWimage;
-
-
-/*************************************************************************
- * GLFW API functions
- *************************************************************************/
-
-/*! @brief Initializes the GLFW library.
- *
- * This function initializes the GLFW library. Before most GLFW functions can
- * be used, GLFW must be initialized, and before an application terminates GLFW
- * should be terminated in order to free any resources allocated during or
- * after initialization.
- *
- * If this function fails, it calls @ref glfwTerminate before returning. If it
- * succeeds, you should call @ref glfwTerminate before the application exits.
- *
- * Additional calls to this function after successful initialization but before
- * termination will return `GLFW_TRUE` immediately.
- *
- * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
- *
- * @remark @osx This function will change the current directory of the
- * application to the `Contents/Resources` subdirectory of the application's
- * bundle, if present. This can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref intro_init
- * @sa glfwTerminate
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI int glfwInit(void);
-
-/*! @brief Terminates the GLFW library.
- *
- * This function destroys all remaining windows and cursors, restores any
- * modified gamma ramps and frees any other allocated resources. Once this
- * function is called, you must again call @ref glfwInit successfully before
- * you will be able to use most GLFW functions.
- *
- * If GLFW has been successfully initialized, this function should be called
- * before the application exits. If initialization fails, there is no need to
- * call this function, as it is called by @ref glfwInit before it returns
- * failure.
- *
- * @errors Possible errors include @ref GLFW_PLATFORM_ERROR.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @warning The contexts of any remaining windows must not be current on any
- * other thread when this function is called.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref intro_init
- * @sa glfwInit
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI void glfwTerminate(void);
-
-/*! @brief Retrieves the version of the GLFW library.
- *
- * This function retrieves the major, minor and revision numbers of the GLFW
- * library. It is intended for when you are using GLFW as a shared library and
- * want to ensure that you are using the minimum required version.
- *
- * Any or all of the version arguments may be `NULL`.
- *
- * @param[out] major Where to store the major version number, or `NULL`.
- * @param[out] minor Where to store the minor version number, or `NULL`.
- * @param[out] rev Where to store the revision number, or `NULL`.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref intro_version
- * @sa glfwGetVersionString
- *
- * @since Added in version 1.0.
- *
- * @ingroup init
- */
-GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
-
-/*! @brief Returns a string describing the compile-time configuration.
- *
- * This function returns the compile-time generated
- * [version string](@ref intro_version_string) of the GLFW library binary. It
- * describes the version, platform, compiler and any platform-specific
- * compile-time options. It should not be confused with the OpenGL or OpenGL
- * ES version string, queried with `glGetString`.
- *
- * __Do not use the version string__ to parse the GLFW library version. The
- * @ref glfwGetVersion function provides the version of the running library
- * binary in numerical format.
- *
- * @return The ASCII encoded GLFW version string.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @pointer_lifetime The returned string is static and compile-time generated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref intro_version
- * @sa glfwGetVersion
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-GLFWAPI const char* glfwGetVersionString(void);
-
-/*! @brief Sets the error callback.
- *
- * This function sets the error callback, which is called with an error code
- * and a human-readable description each time a GLFW error occurs.
- *
- * The error callback is called on the thread where the error occurred. If you
- * are using GLFW from multiple threads, your error callback needs to be
- * written accordingly.
- *
- * Because the description string may have been generated specifically for that
- * error, it is not guaranteed to be valid after the callback has returned. If
- * you wish to use it after the callback returns, you need to make a copy.
- *
- * Once set, the error callback remains set even after the library has been
- * terminated.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set.
- *
- * @errors None.
- *
- * @remark This function may be called before @ref glfwInit.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref error_handling
- *
- * @since Added in version 3.0.
- *
- * @ingroup init
- */
-GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
-
-/*! @brief Returns the currently connected monitors.
- *
- * This function returns an array of handles for all currently connected
- * monitors. The primary monitor is always first in the returned array. If no
- * monitors were found, this function returns `NULL`.
- *
- * @param[out] count Where to store the number of monitors in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of monitor handles, or `NULL` if no monitors were found or
- * if an [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is guaranteed to be valid only until the
- * monitor configuration changes or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_monitors
- * @sa @ref monitor_event
- * @sa glfwGetPrimaryMonitor
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
-
-/*! @brief Returns the primary monitor.
- *
- * This function returns the primary monitor. This is usually the monitor
- * where elements like the task bar or global menu bar are located.
- *
- * @return The primary monitor, or `NULL` if no monitors were found or if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @remark The primary monitor is always first in the array returned by @ref
- * glfwGetMonitors.
- *
- * @sa @ref monitor_monitors
- * @sa glfwGetMonitors
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
-
-/*! @brief Returns the position of the monitor's viewport on the virtual screen.
- *
- * This function returns the position, in screen coordinates, of the upper-left
- * corner of the specified monitor.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] monitor The monitor to query.
- * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`.
- * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
-
-/*! @brief Returns the physical size of the monitor.
- *
- * This function returns the size, in millimetres, of the display area of the
- * specified monitor.
- *
- * Some systems do not provide accurate monitor size information, either
- * because the monitor
- * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)
- * data is incorrect or because the driver does not report it accurately.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] monitor The monitor to query.
- * @param[out] widthMM Where to store the width, in millimetres, of the
- * monitor's display area, or `NULL`.
- * @param[out] heightMM Where to store the height, in millimetres, of the
- * monitor's display area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @remark @win32 calculates the returned physical size from the
- * current resolution and system DPI instead of querying the monitor EDID data.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM);
-
-/*! @brief Returns the name of the specified monitor.
- *
- * This function returns a human-readable name, encoded as UTF-8, of the
- * specified monitor. The name typically reflects the make and model of the
- * monitor and is not guaranteed to be unique among the connected monitors.
- *
- * @param[in] monitor The monitor to query.
- * @return The UTF-8 encoded name of the monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_properties
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
-
-/*! @brief Sets the monitor configuration callback.
- *
- * This function sets the monitor configuration callback, or removes the
- * currently set callback. This is called when a monitor is connected to or
- * disconnected from the system.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_event
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
-
-/*! @brief Returns the available video modes for the specified monitor.
- *
- * This function returns an array of all video modes supported by the specified
- * monitor. The returned array is sorted in ascending order, first by color
- * bit depth (the sum of all channel depths) and then by resolution area (the
- * product of width and height).
- *
- * @param[in] monitor The monitor to query.
- * @param[out] count Where to store the number of video modes in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of video modes, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected, this function is called again for that monitor or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoMode
- *
- * @since Added in version 1.0.
- * @glfw3 Changed to return an array of modes for a specific monitor.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
-
-/*! @brief Returns the current mode of the specified monitor.
- *
- * This function returns the current video mode of the specified monitor. If
- * you have created a full screen window for that monitor, the return value
- * will depend on whether that window is iconified.
- *
- * @param[in] monitor The monitor to query.
- * @return The current mode of the monitor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified monitor is
- * disconnected or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_modes
- * @sa glfwGetVideoModes
- *
- * @since Added in version 3.0. Replaces `glfwGetDesktopMode`.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
-
-/*! @brief Generates a gamma ramp and sets it for the specified monitor.
- *
- * This function generates a 256-element gamma ramp from the specified exponent
- * and then calls @ref glfwSetGammaRamp with it. The value must be a finite
- * number greater than zero.
- *
- * @param[in] monitor The monitor whose gamma ramp to set.
- * @param[in] gamma The desired exponent.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
-
-/*! @brief Returns the current gamma ramp for the specified monitor.
- *
- * This function returns the current gamma ramp of the specified monitor.
- *
- * @param[in] monitor The monitor to query.
- * @return The current gamma ramp, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned structure and its arrays are allocated and
- * freed by GLFW. You should not free them yourself. They are valid until the
- * specified monitor is disconnected, this function is called again for that
- * monitor or the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
-
-/*! @brief Sets the current gamma ramp for the specified monitor.
- *
- * This function sets the current gamma ramp for the specified monitor. The
- * original gamma ramp for that monitor is saved by GLFW the first time this
- * function is called and is restored by @ref glfwTerminate.
- *
- * @param[in] monitor The monitor whose gamma ramp to set.
- * @param[in] ramp The gamma ramp to use.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark Gamma ramp sizes other than 256 are not supported by all platforms
- * or graphics hardware.
- *
- * @remark @win32 The gamma ramp size must be 256.
- *
- * @pointer_lifetime The specified gamma ramp is copied before this function
- * returns.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref monitor_gamma
- *
- * @since Added in version 3.0.
- *
- * @ingroup monitor
- */
-GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
-
-/*! @brief Resets all window hints to their default values.
- *
- * This function resets all window hints to their
- * [default values](@ref window_hints_values).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hints
- * @sa glfwWindowHint
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwDefaultWindowHints(void);
-
-/*! @brief Sets the specified window hint to the desired value.
- *
- * This function sets hints for the next call to @ref glfwCreateWindow. The
- * hints, once set, retain their values until changed by a call to @ref
- * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is
- * terminated.
- *
- * This function does not check whether the specified hint values are valid.
- * If you set hints to invalid values this will instead be reported by the next
- * call to @ref glfwCreateWindow.
- *
- * @param[in] hint The [window hint](@ref window_hints) to set.
- * @param[in] value The new value of the window hint.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hints
- * @sa glfwDefaultWindowHints
- *
- * @since Added in version 3.0. Replaces `glfwOpenWindowHint`.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWindowHint(int hint, int value);
-
-/*! @brief Creates a window and its associated context.
- *
- * This function creates a window and its associated OpenGL or OpenGL ES
- * context. Most of the options controlling how the window and its context
- * should be created are specified with [window hints](@ref window_hints).
- *
- * Successful creation does not change which context is current. Before you
- * can use the newly created context, you need to
- * [make it current](@ref context_current). For information about the `share`
- * parameter, see @ref context_sharing.
- *
- * The created window, framebuffer and context may differ from what you
- * requested, as not all parameters and hints are
- * [hard constraints](@ref window_hints_hard). This includes the size of the
- * window, especially for full screen windows. To query the actual attributes
- * of the created window, framebuffer and context, see @ref
- * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize.
- *
- * To create a full screen window, you need to specify the monitor the window
- * will cover. If no monitor is specified, the window will be windowed mode.
- * Unless you have a way for the user to choose a specific monitor, it is
- * recommended that you pick the primary monitor. For more information on how
- * to query connected monitors, see @ref monitor_monitors.
- *
- * For full screen windows, the specified size becomes the resolution of the
- * window's _desired video mode_. As long as a full screen window is not
- * iconified, the supported video mode most closely matching the desired video
- * mode is set for the specified monitor. For more information about full
- * screen windows, including the creation of so called _windowed full screen_
- * or _borderless full screen_ windows, see @ref window_windowed_full_screen.
- *
- * By default, newly created windows use the placement recommended by the
- * window system. To create the window at a specific position, make it
- * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
- * hint, set its [position](@ref window_pos) and then [show](@ref window_hide)
- * it.
- *
- * As long as at least one full screen window is not iconified, the screensaver
- * is prohibited from starting.
- *
- * Window systems put limits on window sizes. Very large or very small window
- * dimensions may be overridden by the window system on creation. Check the
- * actual [size](@ref window_size) after creation.
- *
- * The [swap interval](@ref buffer_swap) is not set during window creation and
- * the initial value may vary depending on driver settings and defaults.
- *
- * @param[in] width The desired width, in screen coordinates, of the window.
- * This must be greater than zero.
- * @param[in] height The desired height, in screen coordinates, of the window.
- * This must be greater than zero.
- * @param[in] title The initial, UTF-8 encoded window title.
- * @param[in] monitor The monitor to use for full screen mode, or `NULL` for
- * windowed mode.
- * @param[in] share The window whose context to share resources with, or `NULL`
- * to not share resources.
- * @return The handle of the created window, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
- * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark @win32 Window creation will fail if the Microsoft GDI software
- * OpenGL implementation is the only one available.
- *
- * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
- * will be set as the initial icon for the window. If no such icon is present,
- * the `IDI_WINLOGO` icon will be used instead. To set a different icon, see
- * @ref glfwSetWindowIcon.
- *
- * @remark @win32 The context to share resources with must not be current on
- * any other thread.
- *
- * @remark @osx The GLFW window has no icon, as it is not a document
- * window, but the dock icon will be the same as the application bundle's icon.
- * For more information on bundles, see the
- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
- * in the Mac Developer Library.
- *
- * @remark @osx The first time a window is created the menu bar is populated
- * with common commands like Hide, Quit and About. The About entry opens
- * a minimal about dialog with information from the application's bundle. The
- * menu bar can be disabled with a
- * [compile-time option](@ref compile_options_osx).
- *
- * @remark @osx On OS X 10.10 and later the window frame will not be rendered
- * at full resolution on Retina displays unless the `NSHighResolutionCapable`
- * key is enabled in the application bundle's `Info.plist`. For more
- * information, see
- * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
- * in the Mac Developer Library. The GLFW test and example programs use
- * a custom `Info.plist` template for this, which can be found as
- * `CMake/MacOSXBundleInfo.plist.in` in the source tree.
- *
- * @remark @x11 Some window managers will not respect the placement of
- * initially hidden windows.
- *
- * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
- * a window to reach its requested state. This means you may not be able to
- * query the final size, position or other attributes directly after window
- * creation.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_creation
- * @sa glfwDestroyWindow
- *
- * @since Added in version 3.0. Replaces `glfwOpenWindow`.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
-
-/*! @brief Destroys the specified window and its context.
- *
- * This function destroys the specified window and its context. On calling
- * this function, no further callbacks will be called for that window.
- *
- * If the context of the specified window is current on the main thread, it is
- * detached before being destroyed.
- *
- * @param[in] window The window to destroy.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @note The context of the specified window must not be current on any other
- * thread when this function is called.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_creation
- * @sa glfwCreateWindow
- *
- * @since Added in version 3.0. Replaces `glfwCloseWindow`.
- *
- * @ingroup window
- */
-GLFWAPI void glfwDestroyWindow(GLFWwindow* window);
-
-/*! @brief Checks the close flag of the specified window.
- *
- * This function returns the value of the close flag of the specified window.
- *
- * @param[in] window The window to query.
- * @return The value of the close flag.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_close
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
-
-/*! @brief Sets the close flag of the specified window.
- *
- * This function sets the value of the close flag of the specified window.
- * This can be used to override the user's attempt to close the window, or
- * to signal that it should be closed.
- *
- * @param[in] window The window whose flag to change.
- * @param[in] value The new value.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_close
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
-
-/*! @brief Sets the title of the specified window.
- *
- * This function sets the window title, encoded as UTF-8, of the specified
- * window.
- *
- * @param[in] window The window whose title to change.
- * @param[in] title The UTF-8 encoded window title.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @remark @osx The window title will not be updated until the next time you
- * process events.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_title
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
-
-/*! @brief Sets the icon for the specified window.
- *
- * This function sets the icon of the specified window. If passed an array of
- * candidate images, those of or closest to the sizes desired by the system are
- * selected. If no images are specified, the window reverts to its default
- * icon.
- *
- * The desired image sizes varies depending on platform and system settings.
- * The selected images will be rescaled as needed. Good sizes include 16x16,
- * 32x32 and 48x48.
- *
- * @param[in] window The window whose icon to set.
- * @param[in] count The number of images in the specified array, or zero to
- * revert to the default window icon.
- * @param[in] images The images to create the icon from. This is ignored if
- * count is zero.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified image data is copied before this function
- * returns.
- *
- * @remark @osx The GLFW window has no icon, as it is not a document
- * window, so this function does nothing. The dock icon will be the same as
- * the application bundle's icon. For more information on bundles, see the
- * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
- * in the Mac Developer Library.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_icon
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
-
-/*! @brief Retrieves the position of the client area of the specified window.
- *
- * This function retrieves the position, in screen coordinates, of the
- * upper-left corner of the client area of the specified window.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] window The window to query.
- * @param[out] xpos Where to store the x-coordinate of the upper-left corner of
- * the client area, or `NULL`.
- * @param[out] ypos Where to store the y-coordinate of the upper-left corner of
- * the client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- * @sa glfwSetWindowPos
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
-
-/*! @brief Sets the position of the client area of the specified window.
- *
- * This function sets the position, in screen coordinates, of the upper-left
- * corner of the client area of the specified windowed mode window. If the
- * window is a full screen window, this function does nothing.
- *
- * __Do not use this function__ to move an already visible window unless you
- * have very good reasons for doing so, as it will confuse and annoy the user.
- *
- * The window manager may put limits on what positions are allowed. GLFW
- * cannot and should not override these limits.
- *
- * @param[in] window The window to query.
- * @param[in] xpos The x-coordinate of the upper-left corner of the client area.
- * @param[in] ypos The y-coordinate of the upper-left corner of the client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- * @sa glfwGetWindowPos
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
-
-/*! @brief Retrieves the size of the client area of the specified window.
- *
- * This function retrieves the size, in screen coordinates, of the client area
- * of the specified window. If you wish to retrieve the size of the
- * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose size to retrieve.
- * @param[out] width Where to store the width, in screen coordinates, of the
- * client area, or `NULL`.
- * @param[out] height Where to store the height, in screen coordinates, of the
- * client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- * @sa glfwSetWindowSize
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
-
-/*! @brief Sets the size limits of the specified window.
- *
- * This function sets the size limits of the client area of the specified
- * window. If the window is full screen, the size limits only take effect
- * once it is made windowed. If the window is not resizable, this function
- * does nothing.
- *
- * The size limits are applied immediately to a windowed mode window and may
- * cause it to be resized.
- *
- * The maximum dimensions must be greater than or equal to the minimum
- * dimensions and all must be greater than or equal to zero.
- *
- * @param[in] window The window to set limits for.
- * @param[in] minwidth The minimum width, in screen coordinates, of the client
- * area, or `GLFW_DONT_CARE`.
- * @param[in] minheight The minimum height, in screen coordinates, of the
- * client area, or `GLFW_DONT_CARE`.
- * @param[in] maxwidth The maximum width, in screen coordinates, of the client
- * area, or `GLFW_DONT_CARE`.
- * @param[in] maxheight The maximum height, in screen coordinates, of the
- * client area, or `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark If you set size limits and an aspect ratio that conflict, the
- * results are undefined.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_sizelimits
- * @sa glfwSetWindowAspectRatio
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
-
-/*! @brief Sets the aspect ratio of the specified window.
- *
- * This function sets the required aspect ratio of the client area of the
- * specified window. If the window is full screen, the aspect ratio only takes
- * effect once it is made windowed. If the window is not resizable, this
- * function does nothing.
- *
- * The aspect ratio is specified as a numerator and a denominator and both
- * values must be greater than zero. For example, the common 16:9 aspect ratio
- * is specified as 16 and 9, respectively.
- *
- * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect
- * ratio limit is disabled.
- *
- * The aspect ratio is applied immediately to a windowed mode window and may
- * cause it to be resized.
- *
- * @param[in] window The window to set limits for.
- * @param[in] numer The numerator of the desired aspect ratio, or
- * `GLFW_DONT_CARE`.
- * @param[in] denom The denominator of the desired aspect ratio, or
- * `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark If you set size limits and an aspect ratio that conflict, the
- * results are undefined.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_sizelimits
- * @sa glfwSetWindowSizeLimits
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
-
-/*! @brief Sets the size of the client area of the specified window.
- *
- * This function sets the size, in screen coordinates, of the client area of
- * the specified window.
- *
- * For full screen windows, this function updates the resolution of its desired
- * video mode and switches to the video mode closest to it, without affecting
- * the window's context. As the context is unaffected, the bit depths of the
- * framebuffer remain unchanged.
- *
- * If you wish to update the refresh rate of the desired video mode in addition
- * to its resolution, see @ref glfwSetWindowMonitor.
- *
- * The window manager may put limits on what sizes are allowed. GLFW cannot
- * and should not override these limits.
- *
- * @param[in] window The window to resize.
- * @param[in] width The desired width, in screen coordinates, of the window
- * client area.
- * @param[in] height The desired height, in screen coordinates, of the window
- * client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- * @sa glfwGetWindowSize
- * @sa glfwSetWindowMonitor
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
-
-/*! @brief Retrieves the size of the framebuffer of the specified window.
- *
- * This function retrieves the size, in pixels, of the framebuffer of the
- * specified window. If you wish to retrieve the size of the window in screen
- * coordinates, see @ref glfwGetWindowSize.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose framebuffer to query.
- * @param[out] width Where to store the width, in pixels, of the framebuffer,
- * or `NULL`.
- * @param[out] height Where to store the height, in pixels, of the framebuffer,
- * or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_fbsize
- * @sa glfwSetFramebufferSizeCallback
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
-
-/*! @brief Retrieves the size of the frame of the window.
- *
- * This function retrieves the size, in screen coordinates, of each edge of the
- * frame of the specified window. This size includes the title bar, if the
- * window has one. The size of the frame may vary depending on the
- * [window-related hints](@ref window_hints_wnd) used to create it.
- *
- * Because this function retrieves the size of each window frame edge and not
- * the offset along a particular coordinate axis, the retrieved values will
- * always be zero or positive.
- *
- * Any or all of the size arguments may be `NULL`. If an error occurs, all
- * non-`NULL` size arguments will be set to zero.
- *
- * @param[in] window The window whose frame size to query.
- * @param[out] left Where to store the size, in screen coordinates, of the left
- * edge of the window frame, or `NULL`.
- * @param[out] top Where to store the size, in screen coordinates, of the top
- * edge of the window frame, or `NULL`.
- * @param[out] right Where to store the size, in screen coordinates, of the
- * right edge of the window frame, or `NULL`.
- * @param[out] bottom Where to store the size, in screen coordinates, of the
- * bottom edge of the window frame, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- *
- * @since Added in version 3.1.
- *
- * @ingroup window
- */
-GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
-
-/*! @brief Iconifies the specified window.
- *
- * This function iconifies (minimizes) the specified window if it was
- * previously restored. If the window is already iconified, this function does
- * nothing.
- *
- * If the specified window is a full screen window, the original monitor
- * resolution is restored until the window is restored.
- *
- * @param[in] window The window to iconify.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwRestoreWindow
- * @sa glfwMaximizeWindow
- *
- * @since Added in version 2.1.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
-
-/*! @brief Restores the specified window.
- *
- * This function restores the specified window if it was previously iconified
- * (minimized) or maximized. If the window is already restored, this function
- * does nothing.
- *
- * If the specified window is a full screen window, the resolution chosen for
- * the window is restored on the selected monitor.
- *
- * @param[in] window The window to restore.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwMaximizeWindow
- *
- * @since Added in version 2.1.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
-
-/*! @brief Maximizes the specified window.
- *
- * This function maximizes the specified window if it was previously not
- * maximized. If the window is already maximized, this function does nothing.
- *
- * If the specified window is a full screen window, this function does nothing.
- *
- * @param[in] window The window to maximize.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @par Thread Safety
- * This function may only be called from the main thread.
- *
- * @sa @ref window_iconify
- * @sa glfwIconifyWindow
- * @sa glfwRestoreWindow
- *
- * @since Added in GLFW 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
-
-/*! @brief Makes the specified window visible.
- *
- * This function makes the specified window visible if it was previously
- * hidden. If the window is already visible or is in full screen mode, this
- * function does nothing.
- *
- * @param[in] window The window to make visible.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hide
- * @sa glfwHideWindow
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwShowWindow(GLFWwindow* window);
-
-/*! @brief Hides the specified window.
- *
- * This function hides the specified window if it was previously visible. If
- * the window is already hidden or is in full screen mode, this function does
- * nothing.
- *
- * @param[in] window The window to hide.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_hide
- * @sa glfwShowWindow
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwHideWindow(GLFWwindow* window);
-
-/*! @brief Brings the specified window to front and sets input focus.
- *
- * This function brings the specified window to front and sets input focus.
- * The window should already be visible and not iconified.
- *
- * By default, both windowed and full screen mode windows are focused when
- * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable
- * this behavior.
- *
- * __Do not use this function__ to steal focus from other applications unless
- * you are certain that is what the user wants. Focus stealing can be
- * extremely disruptive.
- *
- * @param[in] window The window to give input focus.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_focus
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwFocusWindow(GLFWwindow* window);
-
-/*! @brief Returns the monitor that the window uses for full screen mode.
- *
- * This function returns the handle of the monitor that the specified window is
- * in full screen on.
- *
- * @param[in] window The window to query.
- * @return The monitor, or `NULL` if the window is in windowed mode or an error
- * occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_monitor
- * @sa glfwSetWindowMonitor
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
-
-/*! @brief Sets the mode, monitor, video mode and placement of a window.
- *
- * This function sets the monitor that the window uses for full screen mode or,
- * if the monitor is `NULL`, makes it windowed mode.
- *
- * When setting a monitor, this function updates the width, height and refresh
- * rate of the desired video mode and switches to the video mode closest to it.
- * The window position is ignored when setting a monitor.
- *
- * When the monitor is `NULL`, the position, width and height are used to
- * place the window client area. The refresh rate is ignored when no monitor
- * is specified.
- *
- * If you only wish to update the resolution of a full screen window or the
- * size of a windowed mode window, see @ref glfwSetWindowSize.
- *
- * When a window transitions from full screen to windowed mode, this function
- * restores any previous window settings such as whether it is decorated,
- * floating, resizable, has size or aspect ratio limits, etc..
- *
- * @param[in] window The window whose monitor, size or video mode to set.
- * @param[in] monitor The desired monitor, or `NULL` to set windowed mode.
- * @param[in] xpos The desired x-coordinate of the upper-left corner of the
- * client area.
- * @param[in] ypos The desired y-coordinate of the upper-left corner of the
- * client area.
- * @param[in] width The desired with, in screen coordinates, of the client area
- * or video mode.
- * @param[in] height The desired height, in screen coordinates, of the client
- * area or video mode.
- * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,
- * or `GLFW_DONT_CARE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_monitor
- * @sa @ref window_full_screen
- * @sa glfwGetWindowMonitor
- * @sa glfwSetWindowSize
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
-
-/*! @brief Returns an attribute of the specified window.
- *
- * This function returns the value of an attribute of the specified window or
- * its OpenGL or OpenGL ES context.
- *
- * @param[in] window The window to query.
- * @param[in] attrib The [window attribute](@ref window_attribs) whose value to
- * return.
- * @return The value of the attribute, or zero if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark Framebuffer related hints are not window attributes. See @ref
- * window_attribs_fb for more information.
- *
- * @remark Zero is a valid value for many window and context related
- * attributes so you cannot use a return value of zero as an indication of
- * errors. However, this function should not fail as long as it is passed
- * valid arguments and the library has been [initialized](@ref intro_init).
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_attribs
- *
- * @since Added in version 3.0. Replaces `glfwGetWindowParam` and
- * `glfwGetGLVersion`.
- *
- * @ingroup window
- */
-GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
-
-/*! @brief Sets the user pointer of the specified window.
- *
- * This function sets the user-defined pointer of the specified window. The
- * current value is retained until the window is destroyed. The initial value
- * is `NULL`.
- *
- * @param[in] window The window whose pointer to set.
- * @param[in] pointer The new value.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_userptr
- * @sa glfwGetWindowUserPointer
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer);
-
-/*! @brief Returns the user pointer of the specified window.
- *
- * This function returns the current value of the user-defined pointer of the
- * specified window. The initial value is `NULL`.
- *
- * @param[in] window The window whose pointer to return.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread. Access is not
- * synchronized.
- *
- * @sa @ref window_userptr
- * @sa glfwSetWindowUserPointer
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
-
-/*! @brief Sets the position callback for the specified window.
- *
- * This function sets the position callback of the specified window, which is
- * called when the window is moved. The callback is provided with the screen
- * position of the upper-left corner of the client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_pos
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun cbfun);
-
-/*! @brief Sets the size callback for the specified window.
- *
- * This function sets the size callback of the specified window, which is
- * called when the window is resized. The callback is provided with the size,
- * in screen coordinates, of the client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_size
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun cbfun);
-
-/*! @brief Sets the close callback for the specified window.
- *
- * This function sets the close callback of the specified window, which is
- * called when the user attempts to close the window, for example by clicking
- * the close widget in the title bar.
- *
- * The close flag is set before this callback is called, but you can modify it
- * at any time with @ref glfwSetWindowShouldClose.
- *
- * The close callback is not triggered by @ref glfwDestroyWindow.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @remark @osx Selecting Quit from the application menu will trigger the close
- * callback for all windows.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_close
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun cbfun);
-
-/*! @brief Sets the refresh callback for the specified window.
- *
- * This function sets the refresh callback of the specified window, which is
- * called when the client area of the window needs to be redrawn, for example
- * if the window has been exposed after having been covered by another window.
- *
- * On compositing window systems such as Aero, Compiz or Aqua, where the window
- * contents are saved off-screen, this callback may be called only very
- * infrequently or never at all.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_refresh
- *
- * @since Added in version 2.5.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun cbfun);
-
-/*! @brief Sets the focus callback for the specified window.
- *
- * This function sets the focus callback of the specified window, which is
- * called when the window gains or loses input focus.
- *
- * After the focus callback is called for a window that lost input focus,
- * synthetic key and mouse button release events will be generated for all such
- * that had been pressed. For more information, see @ref glfwSetKeyCallback
- * and @ref glfwSetMouseButtonCallback.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_focus
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);
-
-/*! @brief Sets the iconify callback for the specified window.
- *
- * This function sets the iconification callback of the specified window, which
- * is called when the window is iconified or restored.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_iconify
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);
-
-/*! @brief Sets the framebuffer resize callback for the specified window.
- *
- * This function sets the framebuffer resize callback of the specified window,
- * which is called when the framebuffer of the specified window is resized.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref window_fbsize
- *
- * @since Added in version 3.0.
- *
- * @ingroup window
- */
-GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);
-
-/*! @brief Processes all pending events.
- *
- * This function processes only those events that are already in the event
- * queue and then returns immediately. Processing events will cause the window
- * and input callbacks associated with those events to be called.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain events are sent directly to the application
- * without going through the event queue, causing callbacks to be called
- * outside of a call to one of the event processing functions.
- *
- * Event processing is not required for joystick input to work.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwWaitEvents
- * @sa glfwWaitEventsTimeout
- *
- * @since Added in version 1.0.
- *
- * @ingroup window
- */
-GLFWAPI void glfwPollEvents(void);
-
-/*! @brief Waits until events are queued and processes them.
- *
- * This function puts the calling thread to sleep until at least one event is
- * available in the event queue. Once one or more events are available,
- * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue
- * are processed and the function then returns immediately. Processing events
- * will cause the window and input callbacks associated with those events to be
- * called.
- *
- * Since not all events are associated with callbacks, this function may return
- * without a callback having been called even if you are monitoring all
- * callbacks.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * Event processing is not required for joystick input to work.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEventsTimeout
- *
- * @since Added in version 2.5.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWaitEvents(void);
-
-/*! @brief Waits with timeout until events are queued and processes them.
- *
- * This function puts the calling thread to sleep until at least one event is
- * available in the event queue, or until the specified timeout is reached. If
- * one or more events are available, it behaves exactly like @ref
- * glfwPollEvents, i.e. the events in the queue are processed and the function
- * then returns immediately. Processing events will cause the window and input
- * callbacks associated with those events to be called.
- *
- * The timeout value must be a positive finite number.
- *
- * Since not all events are associated with callbacks, this function may return
- * without a callback having been called even if you are monitoring all
- * callbacks.
- *
- * On some platforms, a window move, resize or menu operation will cause event
- * processing to block. This is due to how event processing is designed on
- * those platforms. You can use the
- * [window refresh callback](@ref window_refresh) to redraw the contents of
- * your window when necessary during such operations.
- *
- * On some platforms, certain callbacks may be called outside of a call to one
- * of the event processing functions.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * Event processing is not required for joystick input to work.
- *
- * @param[in] timeout The maximum amount of time, in seconds, to wait.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref events
- * @sa glfwPollEvents
- * @sa glfwWaitEvents
- *
- * @since Added in version 3.2.
- *
- * @ingroup window
- */
-GLFWAPI void glfwWaitEventsTimeout(double timeout);
-
-/*! @brief Posts an empty event to the event queue.
- *
- * This function posts an empty event from the current thread to the event
- * queue, causing @ref glfwWaitEvents to return.
- *
- * If no windows exist, this function returns immediately. For synchronization
- * of threads in applications that do not create windows, use your threading
- * library of choice.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref events
- * @sa glfwWaitEvents
- *
- * @since Added in version 3.1.
- *
- * @ingroup window
- */
-GLFWAPI void glfwPostEmptyEvent(void);
-
-/*! @brief Returns the value of an input option for the specified window.
- *
- * This function returns the value of an input option for the specified window.
- * The mode must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * @param[in] window The window to query.
- * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa glfwSetInputMode
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
-
-/*! @brief Sets an input option for the specified window.
- *
- * This function sets an input mode option for the specified window. The mode
- * must be one of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- *
- * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
- * modes:
- * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally.
- * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the client
- * area of the window but does not restrict the cursor from leaving.
- * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
- * and unlimited cursor movement. This is useful for implementing for
- * example 3D camera controls.
- *
- * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
- * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
- * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS`
- * the next time it is called even if the key had been released before the
- * call. This is useful when you are only interested in whether keys have been
- * pressed but not when or in which order.
- *
- * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either
- * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it.
- * If sticky mouse buttons are enabled, a mouse button press will ensure that
- * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even
- * if the mouse button had been released before the call. This is useful when
- * you are only interested in whether mouse buttons have been pressed but not
- * when or in which order.
- *
- * @param[in] window The window whose input mode to set.
- * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or
- * `GLFW_STICKY_MOUSE_BUTTONS`.
- * @param[in] value The new value of the specified input mode.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa glfwGetInputMode
- *
- * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
-
-/*! @brief Returns the localized name of the specified printable key.
- *
- * This function returns the localized name of the specified printable key.
- * This is intended for displaying key bindings to the user.
- *
- * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise
- * the scancode is ignored. If a non-printable key or (if the key is
- * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is
- * specified, this function returns `NULL`.
- *
- * This behavior allows you to pass in the arguments passed to the
- * [key callback](@ref input_key) without modification.
- *
- * The printable keys are:
- * - `GLFW_KEY_APOSTROPHE`
- * - `GLFW_KEY_COMMA`
- * - `GLFW_KEY_MINUS`
- * - `GLFW_KEY_PERIOD`
- * - `GLFW_KEY_SLASH`
- * - `GLFW_KEY_SEMICOLON`
- * - `GLFW_KEY_EQUAL`
- * - `GLFW_KEY_LEFT_BRACKET`
- * - `GLFW_KEY_RIGHT_BRACKET`
- * - `GLFW_KEY_BACKSLASH`
- * - `GLFW_KEY_WORLD_1`
- * - `GLFW_KEY_WORLD_2`
- * - `GLFW_KEY_0` to `GLFW_KEY_9`
- * - `GLFW_KEY_A` to `GLFW_KEY_Z`
- * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9`
- * - `GLFW_KEY_KP_DECIMAL`
- * - `GLFW_KEY_KP_DIVIDE`
- * - `GLFW_KEY_KP_MULTIPLY`
- * - `GLFW_KEY_KP_SUBTRACT`
- * - `GLFW_KEY_KP_ADD`
- * - `GLFW_KEY_KP_EQUAL`
- *
- * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`.
- * @param[in] scancode The scancode of the key to query.
- * @return The localized name of the key, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the next call to @ref
- * glfwGetKeyName, or until the library is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key_name
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetKeyName(int key, int scancode);
-
-/*! @brief Returns the last reported state of a keyboard key for the specified
- * window.
- *
- * This function returns the last state reported for the specified key to the
- * specified window. The returned state is one of `GLFW_PRESS` or
- * `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to
- * the key callback.
- *
- * If the `GLFW_STICKY_KEYS` input mode is enabled, this function returns
- * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
- * that key has already been released.
- *
- * The key functions deal with physical keys, with [key tokens](@ref keys)
- * named after their use on the standard US keyboard layout. If you want to
- * input text, use the Unicode character callback instead.
- *
- * The [modifier key bit masks](@ref mods) are not key tokens and cannot be
- * used with this function.
- *
- * __Do not use this function__ to implement [text input](@ref input_char).
- *
- * @param[in] window The desired window.
- * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is
- * not a valid key for this function.
- * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
-
-/*! @brief Returns the last reported state of a mouse button for the specified
- * window.
- *
- * This function returns the last state reported for the specified mouse button
- * to the specified window. The returned state is one of `GLFW_PRESS` or
- * `GLFW_RELEASE`.
- *
- * If the `GLFW_STICKY_MOUSE_BUTTONS` input mode is enabled, this function
- * `GLFW_PRESS` the first time you call it for a mouse button that was pressed,
- * even if that mouse button has already been released.
- *
- * @param[in] window The desired window.
- * @param[in] button The desired [mouse button](@ref buttons).
- * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_ENUM.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_mouse_button
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup input
- */
-GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
-
-/*! @brief Retrieves the position of the cursor relative to the client area of
- * the window.
- *
- * This function returns the position of the cursor, in screen coordinates,
- * relative to the upper-left corner of the client area of the specified
- * window.
- *
- * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor
- * position is unbounded and limited only by the minimum and maximum values of
- * a `double`.
- *
- * The coordinate can be converted to their integer equivalents with the
- * `floor` function. Casting directly to an integer type works for positive
- * coordinates, but fails for negative ones.
- *
- * Any or all of the position arguments may be `NULL`. If an error occurs, all
- * non-`NULL` position arguments will be set to zero.
- *
- * @param[in] window The desired window.
- * @param[out] xpos Where to store the cursor x-coordinate, relative to the
- * left edge of the client area, or `NULL`.
- * @param[out] ypos Where to store the cursor y-coordinate, relative to the to
- * top edge of the client area, or `NULL`.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- * @sa glfwSetCursorPos
- *
- * @since Added in version 3.0. Replaces `glfwGetMousePos`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
-
-/*! @brief Sets the position of the cursor, relative to the client area of the
- * window.
- *
- * This function sets the position, in screen coordinates, of the cursor
- * relative to the upper-left corner of the client area of the specified
- * window. The window must have input focus. If the window does not have
- * input focus when this function is called, it fails silently.
- *
- * __Do not use this function__ to implement things like camera controls. GLFW
- * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the
- * cursor, transparently re-centers it and provides unconstrained cursor
- * motion. See @ref glfwSetInputMode for more information.
- *
- * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is
- * unconstrained and limited only by the minimum and maximum values of
- * a `double`.
- *
- * @param[in] window The desired window.
- * @param[in] xpos The desired x-coordinate, relative to the left edge of the
- * client area.
- * @param[in] ypos The desired y-coordinate, relative to the top edge of the
- * client area.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- * @sa glfwGetCursorPos
- *
- * @since Added in version 3.0. Replaces `glfwSetMousePos`.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
-
-/*! @brief Creates a custom cursor.
- *
- * Creates a new custom cursor image that can be set for a window with @ref
- * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor.
- * Any remaining cursors are destroyed by @ref glfwTerminate.
- *
- * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
- * bits per channel. They are arranged canonically as packed sequential rows,
- * starting from the top-left corner.
- *
- * The cursor hotspot is specified in pixels, relative to the upper-left corner
- * of the cursor image. Like all other coordinate systems in GLFW, the X-axis
- * points to the right and the Y-axis points down.
- *
- * @param[in] image The desired cursor image.
- * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot.
- * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot.
- * @return The handle of the created cursor, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified image data is copied before this function
- * returns.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwDestroyCursor
- * @sa glfwCreateStandardCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot);
-
-/*! @brief Creates a cursor with a standard shape.
- *
- * Returns a cursor with a [standard shape](@ref shapes), that can be set for
- * a window with @ref glfwSetCursor.
- *
- * @param[in] shape One of the [standard shapes](@ref shapes).
- * @return A new cursor ready to use or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwCreateCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
-
-/*! @brief Destroys a cursor.
- *
- * This function destroys a cursor previously created with @ref
- * glfwCreateCursor. Any remaining cursors will be destroyed by @ref
- * glfwTerminate.
- *
- * @param[in] cursor The cursor object to destroy.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @reentrancy This function must not be called from a callback.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- * @sa glfwCreateCursor
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
-
-/*! @brief Sets the cursor for the window.
- *
- * This function sets the cursor image to be used when the cursor is over the
- * client area of the specified window. The set cursor will only be visible
- * when the [cursor mode](@ref cursor_mode) of the window is
- * `GLFW_CURSOR_NORMAL`.
- *
- * On some platforms, the set cursor may not be visible unless the window also
- * has input focus.
- *
- * @param[in] window The window to set the cursor for.
- * @param[in] cursor The cursor to set, or `NULL` to switch back to the default
- * arrow cursor.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_object
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
-
-/*! @brief Sets the key callback.
- *
- * This function sets the key callback of the specified window, which is called
- * when a key is pressed, repeated or released.
- *
- * The key functions deal with physical keys, with layout independent
- * [key tokens](@ref keys) named after their values in the standard US keyboard
- * layout. If you want to input text, use the
- * [character callback](@ref glfwSetCharCallback) instead.
- *
- * When a window loses input focus, it will generate synthetic key release
- * events for all pressed keys. You can tell these events from user-generated
- * events by the fact that the synthetic ones are generated after the focus
- * loss event has been processed, i.e. after the
- * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
- *
- * The scancode of a key is specific to that platform or sometimes even to that
- * machine. Scancodes are intended to allow users to bind keys that don't have
- * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their
- * state is not saved and so it cannot be queried with @ref glfwGetKey.
- *
- * Sometimes GLFW needs to generate synthetic key events, in which case the
- * scancode may be zero.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new key callback, or `NULL` to remove the currently
- * set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_key
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
-
-/*! @brief Sets the Unicode character callback.
- *
- * This function sets the character callback of the specified window, which is
- * called when a Unicode character is input.
- *
- * The character callback is intended for Unicode text input. As it deals with
- * characters, it is keyboard layout dependent, whereas the
- * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1
- * to physical keys, as a key may produce zero, one or more characters. If you
- * want to know whether a specific physical key was pressed or released, see
- * the key callback instead.
- *
- * The character callback behaves as system text input normally does and will
- * not be called if modifier keys are held down that would prevent normal text
- * input on that platform, for example a Super (Command) key on OS X or Alt key
- * on Windows. There is a
- * [character with modifiers callback](@ref glfwSetCharModsCallback) that
- * receives these events.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_char
- *
- * @since Added in version 2.4.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
-
-/*! @brief Sets the Unicode character with modifiers callback.
- *
- * This function sets the character with modifiers callback of the specified
- * window, which is called when a Unicode character is input regardless of what
- * modifier keys are used.
- *
- * The character with modifiers callback is intended for implementing custom
- * Unicode character input. For regular Unicode text input, see the
- * [character callback](@ref glfwSetCharCallback). Like the character
- * callback, the character with modifiers callback deals with characters and is
- * keyboard layout dependent. Characters do not map 1:1 to physical keys, as
- * a key may produce zero, one or more characters. If you want to know whether
- * a specific physical key was pressed or released, see the
- * [key callback](@ref glfwSetKeyCallback) instead.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or an
- * error occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_char
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun cbfun);
-
-/*! @brief Sets the mouse button callback.
- *
- * This function sets the mouse button callback of the specified window, which
- * is called when a mouse button is pressed or released.
- *
- * When a window loses input focus, it will generate synthetic mouse button
- * release events for all pressed mouse buttons. You can tell these events
- * from user-generated events by the fact that the synthetic ones are generated
- * after the focus loss event has been processed, i.e. after the
- * [window focus callback](@ref glfwSetWindowFocusCallback) has been called.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref input_mouse_button
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter and return value.
- *
- * @ingroup input
- */
-GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);
-
-/*! @brief Sets the cursor position callback.
- *
- * This function sets the cursor position callback of the specified window,
- * which is called when the cursor is moved. The callback is provided with the
- * position, in screen coordinates, relative to the upper-left corner of the
- * client area of the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_pos
- *
- * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun cbfun);
-
-/*! @brief Sets the cursor enter/exit callback.
- *
- * This function sets the cursor boundary crossing callback of the specified
- * window, which is called when the cursor enters or leaves the client area of
- * the window.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref cursor_enter
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun cbfun);
-
-/*! @brief Sets the scroll callback.
- *
- * This function sets the scroll callback of the specified window, which is
- * called when a scrolling device is used, such as a mouse wheel or scrolling
- * area of a touchpad.
- *
- * The scroll callback receives all scrolling input, like that from a mouse
- * wheel or a touchpad scrolling area.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new scroll callback, or `NULL` to remove the currently
- * set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref scrolling
- *
- * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`.
- *
- * @ingroup input
- */
-GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);
-
-/*! @brief Sets the file drop callback.
- *
- * This function sets the file drop callback of the specified window, which is
- * called when one or more dragged files are dropped on the window.
- *
- * Because the path array and its strings may have been generated specifically
- * for that event, they are not guaranteed to be valid after the callback has
- * returned. If you wish to use them after the callback returns, you need to
- * make a deep copy.
- *
- * @param[in] window The window whose callback to set.
- * @param[in] cbfun The new file drop callback, or `NULL` to remove the
- * currently set callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref path_drop
- *
- * @since Added in version 3.1.
- *
- * @ingroup input
- */
-GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
-
-/*! @brief Returns whether the specified joystick is present.
- *
- * This function returns whether the specified joystick is present.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick
- *
- * @since Added in version 3.0. Replaces `glfwGetJoystickParam`.
- *
- * @ingroup input
- */
-GLFWAPI int glfwJoystickPresent(int joy);
-
-/*! @brief Returns the values of all axes of the specified joystick.
- *
- * This function returns the values of all axes of the specified joystick.
- * Each element in the array is a value between -1.0 and 1.0.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @param[out] count Where to store the number of axis values in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of axis values, or `NULL` if the joystick is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_axis
- *
- * @since Added in version 3.0. Replaces `glfwGetJoystickPos`.
- *
- * @ingroup input
- */
-GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
-
-/*! @brief Returns the state of all buttons of the specified joystick.
- *
- * This function returns the state of all buttons of the specified joystick.
- * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @param[out] count Where to store the number of button states in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of button states, or `NULL` if the joystick is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_button
- *
- * @since Added in version 2.2.
- * @glfw3 Changed to return a dynamic array.
- *
- * @ingroup input
- */
-GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
-
-/*! @brief Returns the name of the specified joystick.
- *
- * This function returns the name, encoded as UTF-8, of the specified joystick.
- * The returned string is allocated and freed by GLFW. You should not free it
- * yourself.
- *
- * Querying a joystick slot with no device present is not an error, but will
- * cause this function to return `NULL`. Call @ref glfwJoystickPresent to
- * check device presence.
- *
- * @param[in] joy The [joystick](@ref joysticks) to query.
- * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
- * is not present.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the specified joystick is
- * disconnected, this function is called again for that joystick or the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_name
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetJoystickName(int joy);
-
-/*! @brief Sets the joystick configuration callback.
- *
- * This function sets the joystick configuration callback, or removes the
- * currently set callback. This is called when a joystick is connected to or
- * disconnected from the system.
- *
- * @param[in] cbfun The new callback, or `NULL` to remove the currently set
- * callback.
- * @return The previously set callback, or `NULL` if no callback was set or the
- * library had not been [initialized](@ref intro_init).
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref joystick_event
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
-
-/*! @brief Sets the clipboard to the specified string.
- *
- * This function sets the system clipboard to the specified, UTF-8 encoded
- * string.
- *
- * @param[in] window The window that will own the clipboard contents.
- * @param[in] string A UTF-8 encoded string.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The specified string is copied before this function
- * returns.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref clipboard
- * @sa glfwGetClipboardString
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
-
-/*! @brief Returns the contents of the clipboard as a string.
- *
- * This function returns the contents of the system clipboard, if it contains
- * or is convertible to a UTF-8 encoded string. If the clipboard is empty or
- * if its contents cannot be converted, `NULL` is returned and a @ref
- * GLFW_FORMAT_UNAVAILABLE error is generated.
- *
- * @param[in] window The window that will request the clipboard contents.
- * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
- * if an [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @pointer_lifetime The returned string is allocated and freed by GLFW. You
- * should not free it yourself. It is valid until the next call to @ref
- * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library
- * is terminated.
- *
- * @thread_safety This function must only be called from the main thread.
- *
- * @sa @ref clipboard
- * @sa glfwSetClipboardString
- *
- * @since Added in version 3.0.
- *
- * @ingroup input
- */
-GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
-
-/*! @brief Returns the value of the GLFW timer.
- *
- * This function returns the value of the GLFW timer. Unless the timer has
- * been set using @ref glfwSetTime, the timer measures time elapsed since GLFW
- * was initialized.
- *
- * The resolution of the timer is system dependent, but is usually on the order
- * of a few micro- or nanoseconds. It uses the highest-resolution monotonic
- * time source on each supported platform.
- *
- * @return The current value, in seconds, or zero 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. Reading and
- * writing of the internal timer offset is not atomic, so it needs to be
- * externally synchronized with calls to @ref glfwSetTime.
- *
- * @sa @ref time
- *
- * @since Added in version 1.0.
- *
- * @ingroup input
- */
-GLFWAPI double glfwGetTime(void);
-
-/*! @brief Sets the GLFW timer.
- *
- * This function sets the value of the GLFW timer. It then continues to count
- * up from that value. The value must be a positive finite number less than
- * or equal to 18446744073.0, which is approximately 584.5 years.
- *
- * @param[in] time The new value, in seconds.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_INVALID_VALUE.
- *
- * @remark The upper limit of the timer is calculated as
- * floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
- * storing nanoseconds in 64 bits. The limit may be increased in the future.
- *
- * @thread_safety This function may be called from any thread. Reading and
- * writing of the internal timer offset is not atomic, so it needs to be
- * externally synchronized with calls to @ref glfwGetTime.
- *
- * @sa @ref time
- *
- * @since Added in version 2.2.
- *
- * @ingroup input
- */
-GLFWAPI void glfwSetTime(double time);
-
-/*! @brief Returns the current value of the raw timer.
- *
- * This function returns the current value of the raw timer, measured in
- * 1&nbsp;/&nbsp;frequency seconds. To get the frequency, call @ref
- * glfwGetTimerFrequency.
- *
- * @return The value of the timer, or zero 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.
- *
- * @sa @ref time
- * @sa glfwGetTimerFrequency
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI uint64_t glfwGetTimerValue(void);
-
-/*! @brief Returns the frequency, in Hz, of the raw timer.
- *
- * This function returns the frequency, in Hz, of the raw timer.
- *
- * @return The frequency of the timer, in Hz, or zero 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.
- *
- * @sa @ref time
- * @sa glfwGetTimerValue
- *
- * @since Added in version 3.2.
- *
- * @ingroup input
- */
-GLFWAPI uint64_t glfwGetTimerFrequency(void);
-
-/*! @brief Makes the context of the specified window current for the calling
- * thread.
- *
- * This function makes the OpenGL or OpenGL ES context of the specified window
- * current on the calling thread. A context can only be made current on
- * a single thread at a time and each thread can have only a single current
- * context at a time.
- *
- * By default, making a context non-current implicitly forces a pipeline flush.
- * On machines that support `GL_KHR_context_flush_control`, you can control
- * whether a context performs this flush by setting the
- * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint.
- *
- * The specified window must have an OpenGL or OpenGL ES context. Specifying
- * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
- * error.
- *
- * @param[in] window The window whose context to make current, or `NULL` to
- * detach the current context.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_current
- * @sa glfwGetCurrentContext
- *
- * @since Added in version 3.0.
- *
- * @ingroup context
- */
-GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window);
-
-/*! @brief Returns the window whose context is current on the calling thread.
- *
- * This function returns the window whose OpenGL or OpenGL ES context is
- * current on the calling thread.
- *
- * @return The window whose context is current, or `NULL` if no window's
- * context is current.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_current
- * @sa glfwMakeContextCurrent
- *
- * @since Added in version 3.0.
- *
- * @ingroup context
- */
-GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
-
-/*! @brief Swaps the front and back buffers of the specified window.
- *
- * This function swaps the front and back buffers of the specified window when
- * rendering with OpenGL or OpenGL ES. If the swap interval is greater than
- * zero, the GPU driver waits the specified number of screen updates before
- * swapping the buffers.
- *
- * The specified window must have an OpenGL or OpenGL ES context. Specifying
- * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT
- * error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see `vkQueuePresentKHR` instead.
- *
- * @param[in] window The window whose buffers to swap.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark __EGL:__ The context of the specified window must be current on the
- * calling thread.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref buffer_swap
- * @sa glfwSwapInterval
- *
- * @since Added in version 1.0.
- * @glfw3 Added window handle parameter.
- *
- * @ingroup window
- */
-GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
-
-/*! @brief Sets the swap interval for the current context.
- *
- * This function sets the swap interval for the current OpenGL or OpenGL ES
- * context, i.e. the number of screen updates to wait from the time @ref
- * glfwSwapBuffers was called before swapping the buffers and returning. This
- * is sometimes called _vertical synchronization_, _vertical retrace
- * synchronization_ or just _vsync_.
- *
- * Contexts that support either of the `WGL_EXT_swap_control_tear` and
- * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals,
- * which allow the driver to swap even if a frame arrives a little bit late.
- * You can check for the presence of these extensions using @ref
- * glfwExtensionSupported. For more information about swap tearing, see the
- * extension specifications.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see the present mode of your swapchain instead.
- *
- * @param[in] interval The minimum number of screen updates to wait for
- * until the buffers are swapped by @ref glfwSwapBuffers.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark This function is not called during context creation, leaving the
- * swap interval set to whatever is the default on that platform. This is done
- * because some swap interval extensions used by GLFW do not allow the swap
- * interval to be reset to zero once it has been set to a non-zero value.
- *
- * @remark Some GPU drivers do not honor the requested swap interval, either
- * because of a user setting that overrides the application's request or due to
- * bugs in the driver.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref buffer_swap
- * @sa glfwSwapBuffers
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI void glfwSwapInterval(int interval);
-
-/*! @brief Returns whether the specified extension is available.
- *
- * This function returns whether the specified
- * [API extension](@ref context_glext) is supported by the current OpenGL or
- * OpenGL ES context. It searches both for client API extension and context
- * creation API extensions.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * As this functions retrieves and searches one or more extension strings each
- * call, it is recommended that you cache its results if it is going to be used
- * frequently. The extension strings will not change during the lifetime of
- * a context, so there is no danger in doing this.
- *
- * This function does not apply to Vulkan. If you are using Vulkan, see @ref
- * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties`
- * and `vkEnumerateDeviceExtensionProperties` instead.
- *
- * @param[in] extension The ASCII encoded name of the extension.
- * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE`
- * otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref
- * GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_glext
- * @sa glfwGetProcAddress
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI int glfwExtensionSupported(const char* extension);
-
-/*! @brief Returns the address of the specified function for the current
- * context.
- *
- * This function returns the address of the specified OpenGL or OpenGL ES
- * [core or extension function](@ref context_glext), if it is supported
- * by the current context.
- *
- * A context must be current on the calling thread. Calling this function
- * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error.
- *
- * This function does not apply to Vulkan. If you are rendering with Vulkan,
- * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and
- * `vkGetDeviceProcAddr` instead.
- *
- * @param[in] procname The ASCII encoded name of the function.
- * @return The address of the function, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
- *
- * @remark The address of a given function is not guaranteed to be the same
- * between contexts.
- *
- * @remark This function may return a non-`NULL` address despite the
- * associated version or extension not being available. Always check the
- * context version or extension string first.
- *
- * @pointer_lifetime The returned function pointer is valid until the context
- * is destroyed or the library is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref context_glext
- * @sa glfwExtensionSupported
- *
- * @since Added in version 1.0.
- *
- * @ingroup context
- */
-GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
-
-/*! @brief Returns whether the Vulkan loader has been found.
- *
- * This function returns whether the Vulkan loader has been found. This check
- * is performed by @ref glfwInit.
- *
- * The availability of a Vulkan loader does not by itself guarantee that window
- * surface creation or even device creation is possible. Call @ref
- * glfwGetRequiredInstanceExtensions to check whether the extensions necessary
- * for Vulkan surface creation are available and @ref
- * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of
- * a physical device supports image presentation.
- *
- * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_support
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI int glfwVulkanSupported(void);
-
-/*! @brief Returns the Vulkan instance extensions required by GLFW.
- *
- * This function returns an array of names of Vulkan instance extensions required
- * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the
- * list will always contains `VK_KHR_surface`, so if you don't require any
- * additional extensions you can pass this list directly to the
- * `VkInstanceCreateInfo` struct.
- *
- * If Vulkan is not available on the machine, this function returns `NULL` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
- *
- * If Vulkan is available but no set of extensions allowing window surface
- * creation was found, this function returns `NULL`. You may still use Vulkan
- * for off-screen rendering and compute work.
- *
- * @param[out] count Where to store the number of extensions in the returned
- * array. This is set to zero if an error occurred.
- * @return An array of ASCII encoded extension names, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_API_UNAVAILABLE.
- *
- * @remarks Additional extensions may be required by future versions of GLFW.
- * You should check if any extensions you wish to enable are already in the
- * returned array, as it is an error to specify an extension more than once in
- * the `VkInstanceCreateInfo` struct.
- *
- * @pointer_lifetime The returned array is allocated and freed by GLFW. You
- * should not free it yourself. It is guaranteed to be valid only until the
- * library is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_ext
- * @sa glfwCreateWindowSurface
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count);
-
-#if defined(VK_VERSION_1_0)
-
-/*! @brief Returns the address of the specified Vulkan instance function.
- *
- * This function returns the address of the specified Vulkan core or extension
- * function for the specified instance. If instance is set to `NULL` it can
- * return any function exported from the Vulkan loader, including at least the
- * following functions:
- *
- * - `vkEnumerateInstanceExtensionProperties`
- * - `vkEnumerateInstanceLayerProperties`
- * - `vkCreateInstance`
- * - `vkGetInstanceProcAddr`
- *
- * If Vulkan is not available on the machine, this function returns `NULL` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available.
- *
- * This function is equivalent to calling `vkGetInstanceProcAddr` with
- * a platform-specific query of the Vulkan loader as a fallback.
- *
- * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve
- * functions related to instance creation.
- * @param[in] procname The ASCII encoded name of the function.
- * @return The address of the function, or `NULL` if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
- * GLFW_API_UNAVAILABLE.
- *
- * @pointer_lifetime The returned function pointer is valid until the library
- * is terminated.
- *
- * @thread_safety This function may be called from any thread.
- *
- * @sa @ref vulkan_proc
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname);
-
-/*! @brief Returns whether the specified queue family can present images.
- *
- * This function returns whether the specified queue family of the specified
- * physical device supports presentation to the platform GLFW was built for.
- *
- * If Vulkan or the required window surface creation instance extensions are
- * not available on the machine, or if the specified instance was not created
- * with the required extensions, this function returns `GLFW_FALSE` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported
- * to check whether Vulkan is available and @ref
- * glfwGetRequiredInstanceExtensions to check what instance extensions are
- * required.
- *
- * @param[in] instance The instance that the physical device belongs to.
- * @param[in] device The physical device that the queue family belongs to.
- * @param[in] queuefamily The index of the queue family to query.
- * @return `GLFW_TRUE` if the queue family supports presentation, or
- * `GLFW_FALSE` otherwise.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
- *
- * @thread_safety This function may be called from any thread. For
- * synchronization details of Vulkan objects, see the Vulkan specification.
- *
- * @sa @ref vulkan_present
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
-
-/*! @brief Creates a Vulkan surface for the specified window.
- *
- * This function creates a Vulkan surface for the specified window.
- *
- * If the Vulkan loader was not found at initialization, this function returns
- * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE
- * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was
- * found.
- *
- * If the required window surface creation instance extensions are not
- * available or if the specified instance was not created with these extensions
- * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and
- * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref
- * glfwGetRequiredInstanceExtensions to check what instance extensions are
- * required.
- *
- * The window surface must be destroyed before the specified Vulkan instance.
- * It is the responsibility of the caller to destroy the window surface. GLFW
- * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the
- * surface.
- *
- * @param[in] instance The Vulkan instance to create the surface in.
- * @param[in] window The window to create the surface for.
- * @param[in] allocator The allocator to use, or `NULL` to use the default
- * allocator.
- * @param[out] surface Where to store the handle of the surface. This is set
- * to `VK_NULL_HANDLE` if an error occurred.
- * @return `VK_SUCCESS` if successful, or a Vulkan error code if an
- * [error](@ref error_handling) occurred.
- *
- * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
- * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
- *
- * @remarks If an error occurs before the creation call is made, GLFW returns
- * the Vulkan error code most appropriate for the error. Appropriate use of
- * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
- * eliminate almost all occurrences of these errors.
- *
- * @thread_safety This function may be called from any thread. For
- * synchronization details of Vulkan objects, see the Vulkan specification.
- *
- * @sa @ref vulkan_surface
- * @sa glfwGetRequiredInstanceExtensions
- *
- * @since Added in version 3.2.
- *
- * @ingroup vulkan
- */
-GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
-
-#endif /*VK_VERSION_1_0*/
-
-
-/*************************************************************************
- * Global definition cleanup
- *************************************************************************/
-
-/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */
-
-#ifdef GLFW_WINGDIAPI_DEFINED
- #undef WINGDIAPI
- #undef GLFW_WINGDIAPI_DEFINED
-#endif
-
-#ifdef GLFW_CALLBACK_DEFINED
- #undef CALLBACK
- #undef GLFW_CALLBACK_DEFINED
-#endif
-
-/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _glfw3_h_ */
-
diff --git a/src/external/include/GLFW_COPYING.txt b/src/external/include/GLFW_COPYING.txt
deleted file mode 100644
index ad16462a..00000000
--- a/src/external/include/GLFW_COPYING.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2002-2006 Marcus Geelnard
-Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
-
-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.
-
diff --git a/src/external/rgif.h b/src/external/rgif.h
index f26f67d1..8a32ef61 100644
--- a/src/external/rgif.h
+++ b/src/external/rgif.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* rgif.h original implementation by Charlie Tangora [ctangora -at- gmail -dot- com]
+* rgif.h original implementation (gif.h) by Charlie Tangora [ctangora -at- gmail -dot- com]
* adapted to C99, reformatted and renamed by Ramon Santamaria (@raysan5)
*
* This file offers a simple, very limited way to create animated GIFs directly in code.
@@ -28,7 +28,32 @@
* 3) Finally, call GifEnd() to close the file handle and free memory.
*
*
-* LICENSE: public domain (www.unlicense.org)
+* LICENSE: This software is available under 2 licenses -- choose whichever you prefer
+*
+* ALTERNATIVE A - MIT License
+*
+* Copyright (c) 2017 Ramon Santamaria
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to
+* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+* of the Software, and to permit persons to whom the Software is 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 Software.
+*
+* THE SOFTWARE IS 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*
+* ------------------------------------------------------------------------------
+*
+* ALTERNATIVE B - public domain (www.unlicense.org)
*
* This is free and unencumbered software released into the public domain.
* Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
@@ -150,7 +175,7 @@ typedef struct GifBitStatus {
// The LZW dictionary is a 256-ary tree constructed
// as the file is encoded, this is one node
typedef struct GifLzwNode {
- uint16_t m_next[256];
+ unsigned short m_next[256];
} GifLzwNode;
//----------------------------------------------------------------------------------
@@ -299,9 +324,9 @@ static void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int
if (ind == gifTransparentIndex) return;
// check whether this color is better than the current winner
- int r_err = r - ((int32_t)pPal->r[ind]);
- int g_err = g - ((int32_t)pPal->g[ind]);
- int b_err = b - ((int32_t)pPal->b[ind]);
+ int r_err = r - ((int)pPal->r[ind]);
+ int g_err = g - ((int)pPal->g[ind]);
+ int b_err = b - ((int)pPal->b[ind]);
int diff = GIFABS(r_err)+GIFABS(g_err)+GIFABS(b_err);
if (diff < *bestDiff)
@@ -463,7 +488,7 @@ static void GifSplitPalette(unsigned char *image, int numPixels, int firstElt, i
}
// otherwise, take the average of all colors in this subcube
- uint64_t r=0, g=0, b=0;
+ unsigned long long r=0, g=0, b=0;
for (int ii=0; ii<numPixels; ++ii)
{
r += image[ii*4+0];
@@ -594,12 +619,12 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
// quantPixels initially holds color*256 for all pixels
// The extra 8 bits of precision allow for sub-single-color error values
// to be propagated
- int32_t *quantPixels = (int32_t*)GIF_TEMP_MALLOC(sizeof(int32_t)*numPixels*4);
+ int *quantPixels = (int*)GIF_TEMP_MALLOC(sizeof(int)*numPixels*4);
for (int ii=0; ii<numPixels*4; ++ii)
{
unsigned char pix = nextFrame[ii];
- int32_t pix16 = (int32_t)pix*256;
+ int pix16 = (int)pix*256;
quantPixels[ii] = pix16;
}
@@ -607,13 +632,13 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
{
for (unsigned int xx=0; xx<width; ++xx)
{
- int32_t *nextPix = quantPixels + 4*(yy*width+xx);
+ int *nextPix = quantPixels + 4*(yy*width+xx);
const unsigned char *lastPix = lastFrame? lastFrame + 4*(yy*width+xx) : NULL;
// Compute the colors we want (rounding to nearest)
- int32_t rr = (nextPix[0] + 127) / 256;
- int32_t gg = (nextPix[1] + 127) / 256;
- int32_t bb = (nextPix[2] + 127) / 256;
+ int rr = (nextPix[0] + 127) / 256;
+ int gg = (nextPix[1] + 127) / 256;
+ int bb = (nextPix[2] + 127) / 256;
// if it happens that we want the color from last frame, then just write out
// a transparent pixel
@@ -629,16 +654,16 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
continue;
}
- int32_t bestDiff = 1000000;
- int32_t bestInd = gifTransparentIndex;
+ int bestDiff = 1000000;
+ int bestInd = gifTransparentIndex;
// Search the palete
GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1);
// Write the result to the temp buffer
- int32_t r_err = nextPix[0] - (int32_t)(pPal->r[bestInd])*256;
- int32_t g_err = nextPix[1] - (int32_t)(pPal->g[bestInd])*256;
- int32_t b_err = nextPix[2] - (int32_t)(pPal->b[bestInd])*256;
+ int r_err = nextPix[0] - (int)(pPal->r[bestInd])*256;
+ int g_err = nextPix[1] - (int)(pPal->g[bestInd])*256;
+ int b_err = nextPix[2] - (int)(pPal->b[bestInd])*256;
nextPix[0] = pPal->r[bestInd];
nextPix[1] = pPal->g[bestInd];
@@ -654,7 +679,7 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
if (quantloc_7 < numPixels)
{
- int32_t *pix7 = quantPixels+4*quantloc_7;
+ int *pix7 = quantPixels+4*quantloc_7;
pix7[0] += GIFMAX(-pix7[0], r_err*7 / 16);
pix7[1] += GIFMAX(-pix7[1], g_err*7 / 16);
pix7[2] += GIFMAX(-pix7[2], b_err*7 / 16);
@@ -662,7 +687,7 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
if (quantloc_3 < numPixels)
{
- int32_t *pix3 = quantPixels+4*quantloc_3;
+ int *pix3 = quantPixels+4*quantloc_3;
pix3[0] += GIFMAX(-pix3[0], r_err*3 / 16);
pix3[1] += GIFMAX(-pix3[1], g_err*3 / 16);
pix3[2] += GIFMAX(-pix3[2], b_err*3 / 16);
@@ -670,7 +695,7 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
if (quantloc_5 < numPixels)
{
- int32_t *pix5 = quantPixels+4*quantloc_5;
+ int *pix5 = quantPixels+4*quantloc_5;
pix5[0] += GIFMAX(-pix5[0], r_err*5 / 16);
pix5[1] += GIFMAX(-pix5[1], g_err*5 / 16);
pix5[2] += GIFMAX(-pix5[2], b_err*5 / 16);
@@ -678,7 +703,7 @@ static void GifDitherImage(const unsigned char *lastFrame, const unsigned char *
if (quantloc_1 < numPixels)
{
- int32_t *pix1 = quantPixels+4*quantloc_1;
+ int *pix1 = quantPixels+4*quantloc_1;
pix1[0] += GIFMAX(-pix1[0], r_err / 16);
pix1[1] += GIFMAX(-pix1[1], g_err / 16);
pix1[2] += GIFMAX(-pix1[2], b_err / 16);
@@ -716,8 +741,8 @@ static void GifThresholdImage(const unsigned char *lastFrame, const unsigned cha
else
{
// palettize the pixel
- int32_t bestDiff = 1000000;
- int32_t bestInd = 1;
+ int bestDiff = 1000000;
+ int bestInd = 1;
GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], &bestInd, &bestDiff, 1);
// Write the resulting color to the output buffer
@@ -835,7 +860,7 @@ static void GifWriteLzwImage(FILE *f, unsigned char *image, unsigned int left, u
GifLzwNode *codetree = (GifLzwNode *)GIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096);
memset(codetree, 0, sizeof(GifLzwNode)*4096);
- int32_t curCode = -1;
+ int curCode = -1;
unsigned int codeSize = minCodeSize + 1;
unsigned int maxCode = clearCode + 1;
diff --git a/src/gestures.h b/src/gestures.h
index f4d38dfb..68bdc11b 100644
--- a/src/gestures.h
+++ b/src/gestures.h
@@ -140,17 +140,25 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
#if defined(GESTURES_IMPLEMENTATION)
-#include <math.h> // Required for: atan2(), sqrt()
-#include <stdint.h> // Required for: uint64_t
-
#if defined(_WIN32)
// Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
#elif defined(__linux__)
- #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
+ #if _POSIX_C_SOURCE < 199309L
+ #undef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
+ #endif
#include <sys/time.h> // Required for: timespec
#include <time.h> // Required for: clock_gettime()
+
+ #include <math.h> // Required for: atan2(), sqrt()
+ #include <stdint.h> // Required for: uint64_t
+#endif
+
+#if defined(__APPLE__) // macOS also defines __MACH__
+ #include <mach/clock.h> // Required for: clock_get_time()
+ #include <mach/mach.h> // Required for: mach_timespec_t
#endif
//----------------------------------------------------------------------------------
@@ -529,6 +537,22 @@ static double GetCurrentTime(void)
time = ((double)nowTime/1000000.0); // Time in miliseconds
#endif
+#if defined(__APPLE__)
+ //#define CLOCK_REALTIME CALENDAR_CLOCK
+ //#define CLOCK_MONOTONIC SYSTEM_CLOCK
+
+ clock_serv_t cclock;
+ mach_timespec_t now;
+ host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
+
+ // NOTE: OS X does not have clock_gettime(), using clock_get_time()
+ clock_get_time(cclock, &now);
+ mach_port_deallocate(mach_task_self(), cclock);
+ uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
+
+ time = ((double)nowTime/1000000.0); // Time in miliseconds
+#endif
+
return time;
}
diff --git a/src/physac.h b/src/physac.h
index 5ecd2815..ef78aab8 100644
--- a/src/physac.h
+++ b/src/physac.h
@@ -235,6 +235,22 @@ PHYSACDEF void ClosePhysics(void);
#if defined(PHYSAC_IMPLEMENTATION)
+#if defined(_WIN32)
+ // Functions required to query time on Windows
+ int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
+ int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
+#elif (defined(__linux__) || defined(__APPLE__) || defined(PLATFORM_WEB))
+ #if _POSIX_C_SOURCE < 199309L
+ #undef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
+ #endif
+ //#define _DEFAULT_SOURCE // Enables BSD function definitions and C99 POSIX compliance
+ #include <sys/time.h> // Required for: timespec
+ #include <time.h> // Required for: clock_gettime()
+ #include <stdint.h>
+#endif
+
+
#if !defined(PHYSAC_NO_THREADS)
#include <pthread.h> // Required for: pthread_t, pthread_create()
#endif
@@ -248,18 +264,6 @@ PHYSACDEF void ClosePhysics(void);
#include "raymath.h" // Required for: Vector2Add(), Vector2Subtract()
-#if defined(_WIN32)
- // Functions required to query time on Windows
- int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
- int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
-#elif defined(__linux__) || defined(__APPLE__) || defined(PLATFORM_WEB)
- #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
- //#define _DEFAULT_SOURCE // Enables BSD function definitions and C99 POSIX compliance
- #include <sys/time.h> // Required for: timespec
- #include <time.h> // Required for: clock_gettime()
- #include <stdint.h>
-#endif
-
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
diff --git a/src/raylib.h b/src/raylib.h
index 331817cf..95247235 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* raylib v1.8.0
+* raylib v1.9-dev
*
* A simple and easy-to-use library to learn videogames programming (www.raylib.com)
*
@@ -72,20 +72,6 @@
#ifndef RAYLIB_H
#define RAYLIB_H
-// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
-//#define PLATFORM_DESKTOP // Windows, Linux or OSX
-//#define PLATFORM_ANDROID // Android device
-//#define PLATFORM_RPI // Raspberry Pi
-//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
-
-// Security check in case no PLATFORM_* defined
-#if !defined(PLATFORM_DESKTOP) && \
- !defined(PLATFORM_ANDROID) && \
- !defined(PLATFORM_RPI) && \
- !defined(PLATFORM_WEB)
- #define PLATFORM_DESKTOP
-#endif
-
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
#define RLAPI __declspec(dllexport) // We are building raylib as a Win32 shared library (.dll)
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
@@ -179,13 +165,11 @@
#define KEY_Y 89
#define KEY_Z 90
-#if defined(PLATFORM_ANDROID)
- // Android Physical Buttons
- #define KEY_BACK 4
- #define KEY_MENU 82
- #define KEY_VOLUME_UP 24
- #define KEY_VOLUME_DOWN 25
-#endif
+// Android Physical Buttons
+#define KEY_BACK 4
+#define KEY_MENU 82
+#define KEY_VOLUME_UP 24
+#define KEY_VOLUME_DOWN 25
// Mouse Buttons
#define MOUSE_LEFT_BUTTON 0
@@ -714,11 +698,7 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Window-related functions
-#if defined(PLATFORM_ANDROID)
-RLAPI void InitWindow(int width, int height, void *state); // Initialize Android activity
-#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context
-#endif
+RLAPI void InitWindow(int width, int height, void *data); // Initialize window and OpenGL context
RLAPI void CloseWindow(void); // Close window and unload OpenGL context
RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed
RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus)
@@ -731,14 +711,12 @@ RLAPI void SetWindowMinSize(int width, int height); // Set window
RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height
-#if !defined(PLATFORM_ANDROID)
// Cursor-related functions
RLAPI void ShowCursor(void); // Shows cursor
RLAPI void HideCursor(void); // Hides cursor
RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
-#endif
// Drawing-related functions
RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
@@ -768,7 +746,7 @@ RLAPI Color Fade(Color color, float alpha); // Color fade-
RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
// Math useful functions (available from raymath.h)
-RLAPI float *VectorToFloat(Vector3 vec); // Returns Vector3 as float array
+RLAPI float *Vector3ToFloat(Vector3 vec); // Returns Vector3 as float array
RLAPI float *MatrixToFloat(Matrix mat); // Returns Matrix as float array
RLAPI Vector3 Vector3Zero(void); // Vector with components value 0.0f
RLAPI Vector3 Vector3One(void); // Vector with components value 1.0f
@@ -944,6 +922,7 @@ RLAPI void ImageColorContrast(Image *image, float contrast);
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
// Image generation functions
+RLAPI Image GenImageColor(int width, int height, Color color); // Generate image: plain color
RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom); // Generate image: vertical gradient
RLAPI Image GenImageGradientH(int width, int height, Color left, Color right); // Generate image: horizontal gradient
RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
@@ -1078,8 +1057,8 @@ RLAPI Texture2D GetTextureDefault(void); // Get
// Shader configuration functions
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
-RLAPI void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
+RLAPI void SetShaderValue(Shader shader, int uniformLoc, const float *value, int size); // Set shader uniform value (float)
+RLAPI void SetShaderValuei(Shader shader, int uniformLoc, const int *value, int size); // Set shader uniform value (int)
RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
@@ -1098,14 +1077,15 @@ RLAPI void BeginBlendMode(int mode); // Beg
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
// VR control functions
-VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
-void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
-RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
-RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
-RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
-RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
-RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
-RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
+RLAPI VrDeviceInfo GetVrDeviceInfo(int vrDeviceType); // Get VR device information for some standard devices
+RLAPI void InitVrSimulator(VrDeviceInfo info); // Init VR simulator for selected device parameters
+RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
+RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
+RLAPI void SetVrDistortionShader(Shader shader); // Set VR distortion shader for stereoscopic rendering
+RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
+RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
+RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
+RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
diff --git a/src/raymath.h b/src/raymath.h
index fe0b8947..decd02c5 100644
--- a/src/raymath.h
+++ b/src/raymath.h
@@ -191,8 +191,8 @@ RMDEF void QuaternionNormalize(Quaternion *q); // Normalize pro
RMDEF void QuaternionInvert(Quaternion *quat); // Invert provided quaternion
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount); // Calculate linear interpolation between two quaternions
-RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount); // Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount); // Calculate slerp-optimized interpolation between two quaternions
+RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount); // Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to); // Calculate quaternion based on the rotation from one vector to another
RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix
RMDEF Matrix QuaternionToMatrix(Quaternion q); // Returns a matrix for a given quaternion
@@ -1083,6 +1083,15 @@ RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
return result;
}
+// Calculate slerp-optimized interpolation between two quaternions
+RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
+{
+ Quaternion result = QuaternionLerp(q1, q2, amount);
+ QuaternionNormalize(&result);
+
+ return result;
+}
+
// Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
{
@@ -1119,15 +1128,6 @@ RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
return result;
}
-// Calculate slerp-optimized interpolation between two quaternions
-RMDEF Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
-{
- Quaternion result = QuaternionLerp(q1, q2, amount);
- QuaternionNormalize(&result);
-
- return result;
-}
-
// Calculate quaternion based on the rotation from one vector to another
RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
{
diff --git a/src/rglfw.c b/src/rglfw.c
new file mode 100644
index 00000000..5cd2c937
--- /dev/null
+++ b/src/rglfw.c
@@ -0,0 +1,107 @@
+/**********************************************************************************************
+*
+* rglfw - raylib GLFW single file compilation
+*
+* This file includes latest GLFW sources (https://github.com/glfw/glfw) to be compiled together
+* with raylib for all supported platforms, this way, no external dependencies are required.
+*
+* LICENSE: zlib/libpng
+*
+* Copyright (c) 2017 Ramon Santamaria (@raysan5)
+*
+* 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_BUILD_DLL // To build shared version
+//http://www.glfw.org/docs/latest/compile.html#compile_manual
+
+#ifdef _WIN32
+ #define _GLFW_WIN32
+#endif
+#ifdef __linux__
+ #define _GLFW_X11
+#endif
+#ifdef __FreeBSD__
+ #define _GLFW_X11
+#endif
+#ifdef __APPLE__
+ #define _GLFW_COCOA
+ #define _GLFW_USE_CHDIR // To chdir to the Resources subdirectory of the application bundle during glfwInit
+ #define _GLFW_USE_MENUBAR // To create and populate the menu bar when the first window is created
+ #define _GLFW_USE_RETINA // To have windows use the full resolution of Retina displays
+#endif
+
+// NOTE: _GLFW_WAYLAND and _GLFW_MIR experimental platforms not supported at this moment
+
+#include "external/glfw/src/context.c"
+#include "external/glfw/src/init.c"
+#include "external/glfw/src/input.c"
+#include "external/glfw/src/monitor.c"
+#include "external/glfw/src/vulkan.c"
+#include "external/glfw/src/window.c"
+
+#ifdef _WIN32
+ #include "external/glfw/src/win32_init.c"
+ #include "external/glfw/src/win32_joystick.c"
+ #include "external/glfw/src/win32_monitor.c"
+ #include "external/glfw/src/win32_time.c"
+ #include "external/glfw/src/win32_thread.c"
+ #include "external/glfw/src/win32_window.c"
+ #include "external/glfw/src/wgl_context.c"
+ #include "external/glfw/src/egl_context.c"
+ #include "external/glfw/src/osmesa_context.c"
+#endif
+
+#ifdef __linux__
+ #include "external/glfw/src/x11_init.c"
+ #include "external/glfw/src/x11_monitor.c"
+ #include "external/glfw/src/x11_window.c"
+ #include "external/glfw/src/xkb_unicode.c"
+ #include "external/glfw/src/linux_joystick.c"
+ #include "external/glfw/src/posix_time.c"
+ #include "external/glfw/src/posix_thread.c"
+ #include "external/glfw/src/glx_context.c"
+ #include "external/glfw/src/egl_context.c"
+ #include "external/glfw/src/osmesa_context.c"
+#endif
+
+#ifdef __FreeBSD__
+ #include "external/glfw/src/x11_init.c"
+ #include "external/glfw/src/x11_monitor.c"
+ #include "external/glfw/src/x11_window.c"
+ #include "external/glfw/src/xkb_unicode.c"
+ // TODO: Joistick implementation
+ #include "external/glfw/src/null_joystick.c"
+ #include "external/glfw/src/posix_time.c"
+ #include "external/glfw/src/posix_thread.c"
+ #include "external/glfw/src/glx_context.c"
+ #include "external/glfw/src/egl_context.c"
+ #include "external/glfw/src/osmesa_context.c"
+#endif
+
+#ifdef __APPLE__
+ #include "external/glfw/src/cocoa_init.m"
+ #include "external/glfw/src/cocoa_joystick.m"
+ #include "external/glfw/src/cocoa_monitor.m"
+ #include "external/glfw/src/cocoa_window.m"
+ #include "external/glfw/src/cocoa_time.c"
+ #include "external/glfw/src/posix_thread.c"
+ #include "external/glfw/src/nsgl_context.m"
+ #include "external/glfw/src/egl_context.c"
+ #include "external/glfw/src/osmesa_context.c"
+#endif
diff --git a/src/rlgl.c b/src/rlgl.c
index 9e563ced..6ae7df4c 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -170,6 +170,11 @@
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#endif
+#if defined(GRAPHICS_API_OPENGL_21)
+ #define GL_LUMINANCE 0x1909
+ #define GL_LUMINANCE_ALPHA 0x190A
+#endif
+
#if defined(GRAPHICS_API_OPENGL_ES2)
#define glClearDepth glClearDepthf
#define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER
@@ -227,7 +232,7 @@ typedef struct DrawCall {
typedef struct VrStereoConfig {
RenderTexture2D stereoFbo; // VR stereo rendering framebuffer
Shader distortionShader; // VR stereo rendering distortion shader
- //Rectangle eyesViewport[2]; // VR stereo rendering eyes viewports
+ Rectangle eyesViewport[2]; // VR stereo rendering eyes viewports
Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
} VrStereoConfig;
@@ -262,7 +267,9 @@ static Vector3 *tempBuffer;
static int tempBufferCount = 0;
static bool useTempBuffer = false;
-// Shader Programs
+// Shaders
+static unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program)
+static unsigned int defaultFShaderId; // Default fragment shader Id (used by default shader program)
static Shader defaultShader; // Basic shader, support vertex color and diffuse texture
static Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
@@ -319,7 +326,9 @@ static int screenHeight; // Default framebuffer height
//----------------------------------------------------------------------------------
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
static void LoadTextureCompressed(unsigned char *data, int width, int height, int compressedFormat, int mipmapCount);
-static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShaderStr); // Load custom shader strings and return program id
+
+static unsigned int CompileShader(const char *shaderStr, int type); // Compile custom shader and return shader id
+static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program
static Shader LoadShaderDefault(void); // Load default shader (just vertex positioning and texture coloring)
static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
@@ -1378,7 +1387,40 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
glBindTexture(GL_TEXTURE_2D, id);
-#if defined(GRAPHICS_API_OPENGL_33)
+#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2)
+ // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
+ switch (format)
+ {
+ case UNCOMPRESSED_GRAYSCALE: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
+ case UNCOMPRESSED_GRAY_ALPHA: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
+ case UNCOMPRESSED_R5G6B5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break;
+ case UNCOMPRESSED_R8G8B8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
+ case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break;
+ case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
+ case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
+ #if defined(GRAPHICS_API_OPENGL_21)
+ case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mipmapCount); break;
+ case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, mipmapCount); break;
+ case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, mipmapCount); break;
+ case COMPRESSED_DXT5_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, mipmapCount); break;
+ #endif
+ #if defined(GRAPHICS_API_OPENGL_ES2)
+ case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // NOTE: Requires extension OES_texture_float
+ case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mipmapCount); break;
+ case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, mipmapCount); break;
+ case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, mipmapCount); break; // NOTE: Not supported by WebGL
+ case COMPRESSED_DXT5_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, mipmapCount); break; // NOTE: Not supported by WebGL
+ case COMPRESSED_ETC1_RGB: if (texCompETC1Supported) LoadTextureCompressed((unsigned char *)data, width, height, GL_ETC1_RGB8_OES, mipmapCount); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3
+ case COMPRESSED_ETC2_RGB: if (texCompETC2Supported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB8_ETC2, mipmapCount); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
+ case COMPRESSED_ETC2_EAC_RGBA: if (texCompETC2Supported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA8_ETC2_EAC, mipmapCount); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
+ case COMPRESSED_PVRT_RGB: if (texCompPVRTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, mipmapCount); break; // NOTE: Requires PowerVR GPU
+ case COMPRESSED_PVRT_RGBA: if (texCompPVRTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, mipmapCount); break; // NOTE: Requires PowerVR GPU
+ case COMPRESSED_ASTC_4x4_RGBA: if (texCompASTCSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, mipmapCount); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
+ case COMPRESSED_ASTC_8x8_RGBA: if (texCompASTCSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, mipmapCount); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
+ #endif
+ default: TraceLog(LOG_WARNING, "Texture format not supported"); break;
+ }
+#elif defined(GRAPHICS_API_OPENGL_33)
// NOTE: We define internal (GPU) format as GL_RGBA8 (probably BGRA8 in practice, driver takes care)
// NOTE: On embedded systems, we let the driver choose the best internal format
@@ -1431,33 +1473,6 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
case COMPRESSED_ASTC_8x8_RGBA: if (texCompASTCSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, mipmapCount); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
default: TraceLog(LOG_WARNING, "Texture format not recognized"); break;
}
-#elif defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_ES2)
- // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
- switch (format)
- {
- case UNCOMPRESSED_GRAYSCALE: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
- case UNCOMPRESSED_GRAY_ALPHA: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
- case UNCOMPRESSED_R5G6B5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break;
- case UNCOMPRESSED_R8G8B8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
- case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break;
- case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
- case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
-#if defined(GRAPHICS_API_OPENGL_ES2)
- case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // NOTE: Requires extension OES_texture_float
- case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mipmapCount); break;
- case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, mipmapCount); break;
- case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, mipmapCount); break; // NOTE: Not supported by WebGL
- case COMPRESSED_DXT5_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, mipmapCount); break; // NOTE: Not supported by WebGL
- case COMPRESSED_ETC1_RGB: if (texCompETC1Supported) LoadTextureCompressed((unsigned char *)data, width, height, GL_ETC1_RGB8_OES, mipmapCount); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3
- case COMPRESSED_ETC2_RGB: if (texCompETC2Supported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB8_ETC2, mipmapCount); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
- case COMPRESSED_ETC2_EAC_RGBA: if (texCompETC2Supported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA8_ETC2_EAC, mipmapCount); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
- case COMPRESSED_PVRT_RGB: if (texCompPVRTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, mipmapCount); break; // NOTE: Requires PowerVR GPU
- case COMPRESSED_PVRT_RGBA: if (texCompPVRTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, mipmapCount); break; // NOTE: Requires PowerVR GPU
- case COMPRESSED_ASTC_4x4_RGBA: if (texCompASTCSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, mipmapCount); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
- case COMPRESSED_ASTC_8x8_RGBA: if (texCompASTCSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, mipmapCount); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
-#endif
- default: TraceLog(LOG_WARNING, "Texture format not supported"); break;
- }
#endif
// Texture parameters configuration
@@ -1575,10 +1590,10 @@ RenderTexture2D rlLoadRenderTexture(int width, int height)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
-#if defined(GRAPHICS_API_OPENGL_33)
- #define USE_DEPTH_TEXTURE
-#else
+#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2)
#define USE_DEPTH_RENDERBUFFER
+#else
+ #define USE_DEPTH_TEXTURE
#endif
#if defined(USE_DEPTH_RENDERBUFFER)
@@ -1937,17 +1952,17 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
// Upload to shader material.colDiffuse
if (material.shader.locs[LOC_COLOR_DIFFUSE] != -1)
- glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.r/255,
- (float)material.maps[MAP_DIFFUSE].color.g/255,
- (float)material.maps[MAP_DIFFUSE].color.b/255,
- (float)material.maps[MAP_DIFFUSE].color.a/255);
+ glUniform4f(material.shader.locs[LOC_COLOR_DIFFUSE], (float)material.maps[MAP_DIFFUSE].color.r/255.0f,
+ (float)material.maps[MAP_DIFFUSE].color.g/255.0f,
+ (float)material.maps[MAP_DIFFUSE].color.b/255.0f,
+ (float)material.maps[MAP_DIFFUSE].color.a/255.0f);
// Upload to shader material.colSpecular (if available)
if (material.shader.locs[LOC_COLOR_SPECULAR] != -1)
- glUniform4f(material.shader.locs[LOC_COLOR_SPECULAR], (float)material.maps[MAP_SPECULAR].color.r/255,
- (float)material.maps[MAP_SPECULAR].color.g/255,
- (float)material.maps[MAP_SPECULAR].color.b/255,
- (float)material.maps[MAP_SPECULAR].color.a/255);
+ glUniform4f(material.shader.locs[LOC_COLOR_SPECULAR], (float)material.maps[MAP_SPECULAR].color.r/255.0f,
+ (float)material.maps[MAP_SPECULAR].color.g/255.0f,
+ (float)material.maps[MAP_SPECULAR].color.b/255.0f,
+ (float)material.maps[MAP_SPECULAR].color.a/255.0f);
if (material.shader.locs[LOC_MATRIX_VIEW] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_VIEW], modelview);
if (material.shader.locs[LOC_MATRIX_PROJECTION] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_PROJECTION], projection);
@@ -2202,7 +2217,7 @@ void *rlReadTexturePixels(Texture2D texture)
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
glBindTexture(GL_TEXTURE_2D, 0);
- // Attach our texture to FBO -> Texture must be RGB
+ // Attach our texture to FBO -> Texture must be RGBA
// NOTE: Previoust attached texture is automatically detached
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.id, 0);
@@ -2222,32 +2237,30 @@ void *rlReadTexturePixels(Texture2D texture)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glViewport(0, 0, width, height);
- //glMatrixMode(GL_PROJECTION);
- //glLoadIdentity();
- rlOrtho(0.0, width, height, 0.0, 0.0, 1.0);
- //glMatrixMode(GL_MODELVIEW);
- //glLoadIdentity();
//glDisable(GL_TEXTURE_2D);
- //glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
+ //glDisable(GL_BLEND);
+
+ glViewport(0, 0, texture.width, texture.height);
+ rlOrtho(0.0, texture.width, texture.height, 0.0, 0.0, 1.0);
- Model quad;
- //quad.mesh = GenMeshQuad(width, height);
- quad.transform = MatrixIdentity();
- quad.shader = defaultShader;
-
- DrawModel(quad, (Vector3){ 0.0f, 0.0f, 0.0f }, 1.0f, WHITE);
-
- pixels = (unsigned char *)malloc(texture.width*texture.height*3*sizeof(unsigned char));
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glUseProgram(GetShaderDefault().id);
+ glBindTexture(GL_TEXTURE_2D, texture.id);
+ GenDrawQuad();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glUseProgram(0);
+
+ pixels = (unsigned char *)malloc(texture.width*texture.height*4*sizeof(unsigned char));
- glReadPixels(0, 0, texture.width, texture.height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+ glReadPixels(0, 0, texture.width, texture.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Bind framebuffer 0, which means render to back buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- UnloadModel(quad);
+
+ // Reset viewport dimensions to default
+ glViewport(0, 0, screenWidth, screenHeight);
+
#endif // GET_TEXTURE_FBO_OPTION
// Clean up temporal fbo
@@ -2342,33 +2355,47 @@ char *LoadText(const char *fileName)
}
// Load shader from files and bind default locations
+// NOTE: If shader string is NULL, using default vertex/fragment shaders
Shader LoadShader(char *vsFileName, char *fsFileName)
{
Shader shader = { 0 };
+
+ // NOTE: All locations must be reseted to -1 (no location)
+ for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Shaders loading from external text file
- char *vShaderStr = LoadText(vsFileName);
- char *fShaderStr = LoadText(fsFileName);
- if ((vShaderStr != NULL) && (fShaderStr != NULL))
- {
- shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
-
- // After shader loading, we TRY to set default location names
- if (shader.id > 0) SetShaderDefaultLocations(&shader);
+ unsigned int vertexShaderId, fragmentShaderId;
- // Shader strings must be freed
+ if (vsFileName == NULL) vertexShaderId = defaultVShaderId;
+ else
+ {
+ char *vShaderStr = LoadText(vsFileName);
+ vertexShaderId = CompileShader(vShaderStr, GL_VERTEX_SHADER);
free(vShaderStr);
+ }
+
+ if (fsFileName == NULL) fragmentShaderId = defaultVShaderId;
+ else
+ {
+ char* fShaderStr = LoadText(fsFileName);
+ fragmentShaderId = CompileShader(fShaderStr, GL_FRAGMENT_SHADER);
free(fShaderStr);
}
+ shader.id = LoadShaderProgram(vertexShaderId, fragmentShaderId);
+
+ if (vertexShaderId != defaultVShaderId) glDeleteShader(vertexShaderId);
+ if (fragmentShaderId != defaultFShaderId) glDeleteShader(fragmentShaderId);
+
if (shader.id == 0)
{
TraceLog(LOG_WARNING, "Custom shader could not be loaded");
shader = defaultShader;
}
+ // After shader loading, we TRY to set default location names
+ if (shader.id > 0) SetShaderDefaultLocations(&shader);
// Get available shader uniforms
// NOTE: This information is useful for debug...
@@ -2393,7 +2420,6 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
TraceLog(LOG_DEBUG, "[SHDR ID %i] Active uniform [%s] set at location: %i", shader.id, name, location);
}
-
#endif
return shader;
@@ -2443,7 +2469,7 @@ int GetShaderLocation(Shader shader, const char *uniformName)
}
// Set shader uniform value (float)
-void SetShaderValue(Shader shader, int uniformLoc, float *value, int size)
+void SetShaderValue(Shader shader, int uniformLoc, const float *value, int size)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
@@ -2459,7 +2485,7 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size)
}
// Set shader uniform value (int)
-void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size)
+void SetShaderValuei(Shader shader, int uniformLoc, const int *value, int size)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
@@ -2900,11 +2926,15 @@ void InitVrSimulator(VrDeviceInfo info)
vrConfig.stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight);
#if defined(SUPPORT_DISTORTION_SHADER)
- // Load distortion shader (initialized by default with Oculus Rift CV1 parameters)
- vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr);
+ // Load distortion shader
+ unsigned int vertexShaderId = CompileShader(distortionVShaderStr, GL_VERTEX_SHADER);
+ unsigned int fragmentShaderId = CompileShader(distortionFShaderStr, GL_FRAGMENT_SHADER);
+
+ vrConfig.distortionShader.id = LoadShaderProgram(vertexShaderId, fragmentShaderId);
if (vrConfig.distortionShader.id > 0) SetShaderDefaultLocations(&vrConfig.distortionShader);
#endif
+ // Set VR configutarion parameters, including distortion shader
SetStereoConfig(info);
vrSimulatorReady = true;
@@ -2929,18 +2959,6 @@ void CloseVrSimulator(void)
#endif
}
-// TODO: Review VR system to be more flexible,
-// move distortion shader to user side,
-// SetStereoConfig() must be reviewed...
-/*
-// Set VR view distortion shader
-void SetVrDistortionShader(Shader shader)
-{
- vrConfig.distortionShader = shader;
- SetStereoConfig(info);
-}
-*/
-
// Detect if VR simulator is running
bool IsVrSimulatorReady(void)
{
@@ -2951,6 +2969,15 @@ bool IsVrSimulatorReady(void)
#endif
}
+// Set VR distortion shader for stereoscopic rendering
+// TODO: Review VR system to be more flexible, move distortion shader to user side
+void SetVrDistortionShader(Shader shader)
+{
+ vrConfig.distortionShader = shader;
+
+ //SetStereoConfig(info); // TODO: Must be reviewed to set new distortion shader uniform values...
+}
+
// Enable/Disable VR experience (device or simulator)
void ToggleVrMode(void)
{
@@ -3115,45 +3142,29 @@ static void LoadTextureCompressed(unsigned char *data, int width, int height, in
}
}
-// Load custom shader strings and return program id
-static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShaderStr)
+// Compile custom shader and return shader id
+static unsigned int CompileShader(const char *shaderStr, int type)
{
- unsigned int program = 0;
-
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- GLuint vertexShader;
- GLuint fragmentShader;
-
- vertexShader = glCreateShader(GL_VERTEX_SHADER);
- fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
-
- const char *pvs = vShaderStr;
- const char *pfs = fShaderStr;
-
- glShaderSource(vertexShader, 1, &pvs, NULL);
- glShaderSource(fragmentShader, 1, &pfs, NULL);
+ unsigned int shader = glCreateShader(type);
+ glShaderSource(shader, 1, &shaderStr, NULL);
GLint success = 0;
-
- glCompileShader(vertexShader);
-
- glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (success != GL_TRUE)
{
- TraceLog(LOG_WARNING, "[VSHDR ID %i] Failed to compile vertex shader...", vertexShader);
-
+ TraceLog(LOG_WARNING, "[SHDR ID %i] Failed to compile shader...", shader);
int maxLength = 0;
int length;
-
- glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
#ifdef _MSC_VER
char *log = malloc(maxLength);
#else
char log[maxLength];
#endif
- glGetShaderInfoLog(vertexShader, maxLength, &length, log);
+ glGetShaderInfoLog(shader, maxLength, &length, log);
TraceLog(LOG_INFO, "%s", log);
@@ -3161,40 +3172,23 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade
free(log);
#endif
}
- else TraceLog(LOG_INFO, "[VSHDR ID %i] Vertex shader compiled successfully", vertexShader);
-
- glCompileShader(fragmentShader);
-
- glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
-
- if (success != GL_TRUE)
- {
- TraceLog(LOG_WARNING, "[FSHDR ID %i] Failed to compile fragment shader...", fragmentShader);
-
- int maxLength = 0;
- int length;
-
- glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
+ else TraceLog(LOG_INFO, "[SHDR ID %i] Shader compiled successfully", shader);
-#ifdef _MSC_VER
- char *log = malloc(maxLength);
-#else
- char log[maxLength];
-#endif
- glGetShaderInfoLog(fragmentShader, maxLength, &length, log);
+ return shader;
+}
- TraceLog(LOG_INFO, "%s", log);
+// Load custom shader strings and return program id
+static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
+{
+ unsigned int program = 0;
-#ifdef _MSC_VER
- free(log);
-#endif
- }
- else TraceLog(LOG_INFO, "[FSHDR ID %i] Fragment shader compiled successfully", fragmentShader);
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ GLint success = 0;
program = glCreateProgram();
- glAttachShader(program, vertexShader);
- glAttachShader(program, fragmentShader);
+ glAttachShader(program, vShaderId);
+ glAttachShader(program, fShaderId);
// NOTE: Default attribute shader locations must be binded before linking
glBindAttribLocation(program, 0, DEFAULT_ATTRIB_POSITION_NAME);
@@ -3238,9 +3232,6 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade
program = 0;
}
else TraceLog(LOG_INFO, "[SHDR ID %i] Shader program loaded successfully", program);
-
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
#endif
return program;
}
@@ -3250,10 +3241,13 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade
// NOTE: This shader program is used for batch buffers (lines, triangles, quads)
static Shader LoadShaderDefault(void)
{
- Shader shader;
+ Shader shader = { 0 };
+
+ // NOTE: All locations must be reseted to -1 (no location)
+ for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;
// Vertex shader directly defined, no external file required
- char vDefaultShaderStr[] =
+ char defaultVShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
@@ -3282,7 +3276,7 @@ static Shader LoadShaderDefault(void)
"} \n";
// Fragment shader directly defined, no external file required
- char fDefaultShaderStr[] =
+ char defaultFShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
@@ -3311,22 +3305,29 @@ static Shader LoadShaderDefault(void)
#endif
"} \n";
- shader.id = LoadShaderProgram(vDefaultShaderStr, fDefaultShaderStr);
+ // NOTE: Compiled vertex/fragment shaders are kept for re-use
+ defaultVShaderId = CompileShader(defaultVShaderStr, GL_VERTEX_SHADER); // Compile default vertex shader
+ defaultFShaderId = CompileShader(defaultFShaderStr, GL_FRAGMENT_SHADER); // Compile default fragment shader
+
+ shader.id = LoadShaderProgram(defaultVShaderId, defaultFShaderId);
if (shader.id > 0)
{
TraceLog(LOG_INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id);
-
- // Set default shader locations
- // Get handles to GLSL input attibute locations
+
+ // Set default shader locations: attributes locations
shader.locs[LOC_VERTEX_POSITION] = glGetAttribLocation(shader.id, "vertexPosition");
shader.locs[LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(shader.id, "vertexTexCoord");
shader.locs[LOC_VERTEX_COLOR] = glGetAttribLocation(shader.id, "vertexColor");
- // Get handles to GLSL uniform locations
+ // Set default shader locations: uniform locations
shader.locs[LOC_MATRIX_MVP] = glGetUniformLocation(shader.id, "mvp");
shader.locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader.id, "colDiffuse");
shader.locs[LOC_MAP_DIFFUSE] = glGetUniformLocation(shader.id, "texture0");
+
+ // NOTE: We could also use below function but in case DEFAULT_ATTRIB_* points are
+ // changed for external custom shaders, we just use direct bindings above
+ //SetShaderDefaultLocations(&shader);
}
else TraceLog(LOG_WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id);
@@ -3361,8 +3362,8 @@ static void SetShaderDefaultLocations(Shader *shader)
// Get handles to GLSL uniform locations (fragment shader)
shader->locs[LOC_COLOR_DIFFUSE] = glGetUniformLocation(shader->id, "colDiffuse");
shader->locs[LOC_MAP_DIFFUSE] = glGetUniformLocation(shader->id, "texture0");
- shader->locs[LOC_MAP_NORMAL] = glGetUniformLocation(shader->id, "texture1");
- shader->locs[LOC_MAP_SPECULAR] = glGetUniformLocation(shader->id, "texture2");
+ shader->locs[LOC_MAP_SPECULAR] = glGetUniformLocation(shader->id, "texture1");
+ shader->locs[LOC_MAP_NORMAL] = glGetUniformLocation(shader->id, "texture2");
}
// Unload default shader
@@ -3370,10 +3371,10 @@ static void UnloadShaderDefault(void)
{
glUseProgram(0);
- //glDetachShader(defaultShader, vertexShader);
- //glDetachShader(defaultShader, fragmentShader);
- //glDeleteShader(vertexShader); // Already deleted on shader compilation
- //glDeleteShader(fragmentShader); // Already deleted on shader compilation
+ glDetachShader(defaultShader.id, defaultVShaderId);
+ glDetachShader(defaultShader.id, defaultFShaderId);
+ glDeleteShader(defaultVShaderId);
+ glDeleteShader(defaultFShaderId);
glDeleteProgram(defaultShader.id);
}
@@ -4023,8 +4024,8 @@ static void SetStereoConfig(VrDeviceInfo hmd)
vrConfig.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
// Compute eyes Viewports
- //vrConfig.eyesViewport[0] = (Rectangle){ 0, 0, hmd.hResolution/2, hmd.vResolution };
- //vrConfig.eyesViewport[1] = (Rectangle){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution };
+ vrConfig.eyesViewport[0] = (Rectangle){ 0, 0, hmd.hResolution/2, hmd.vResolution };
+ vrConfig.eyesViewport[1] = (Rectangle){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution };
}
// Set internal projection and modelview matrix depending on eyes tracking data
diff --git a/src/rlgl.h b/src/rlgl.h
index 3f06a697..2e67c699 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -145,56 +145,6 @@ typedef unsigned char byte;
// Boolean type
typedef enum { false, true } bool;
#endif
-
- // Shader location point type
- typedef enum {
- LOC_VERTEX_POSITION = 0,
- LOC_VERTEX_TEXCOORD01,
- LOC_VERTEX_TEXCOORD02,
- LOC_VERTEX_NORMAL,
- LOC_VERTEX_TANGENT,
- LOC_VERTEX_COLOR,
- LOC_MATRIX_MVP,
- LOC_MATRIX_MODEL,
- LOC_MATRIX_VIEW,
- LOC_MATRIX_PROJECTION,
- LOC_VECTOR_VIEW,
- LOC_COLOR_DIFFUSE,
- LOC_COLOR_SPECULAR,
- LOC_COLOR_AMBIENT,
- LOC_MAP_ALBEDO, // LOC_MAP_DIFFUSE
- LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
- LOC_MAP_NORMAL,
- LOC_MAP_ROUGHNESS,
- LOC_MAP_OCCUSION,
- LOC_MAP_EMISSION,
- LOC_MAP_HEIGHT,
- LOC_MAP_CUBEMAP,
- LOC_MAP_IRRADIANCE,
- LOC_MAP_PREFILTER,
- LOC_MAP_BRDF
- } ShaderLocationIndex;
-
- #define LOC_MAP_DIFFUSE LOC_MAP_ALBEDO
- #define LOC_MAP_SPECULAR LOC_MAP_METALNESS
-
- // Material map type
- typedef enum {
- MAP_ALBEDO = 0, // MAP_DIFFUSE
- MAP_METALNESS = 1, // MAP_SPECULAR
- MAP_NORMAL = 2,
- MAP_ROUGHNESS = 3,
- MAP_OCCLUSION,
- MAP_EMISSION,
- MAP_HEIGHT,
- MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MAP_BRDF
- } TexmapIndex;
-
- #define MAP_DIFFUSE MAP_ALBEDO
- #define MAP_SPECULAR MAP_METALNESS
// Color type, RGBA (32bit)
typedef struct Color {
@@ -204,6 +154,14 @@ typedef unsigned char byte;
unsigned char a;
} Color;
+ // Rectangle type
+ typedef struct Rectangle {
+ int x;
+ int y;
+ int width;
+ int height;
+ } Rectangle;
+
// Texture2D type
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
@@ -341,6 +299,56 @@ typedef unsigned char byte;
BLEND_MULTIPLIED
} BlendMode;
+ // Shader location point type
+ typedef enum {
+ LOC_VERTEX_POSITION = 0,
+ LOC_VERTEX_TEXCOORD01,
+ LOC_VERTEX_TEXCOORD02,
+ LOC_VERTEX_NORMAL,
+ LOC_VERTEX_TANGENT,
+ LOC_VERTEX_COLOR,
+ LOC_MATRIX_MVP,
+ LOC_MATRIX_MODEL,
+ LOC_MATRIX_VIEW,
+ LOC_MATRIX_PROJECTION,
+ LOC_VECTOR_VIEW,
+ LOC_COLOR_DIFFUSE,
+ LOC_COLOR_SPECULAR,
+ LOC_COLOR_AMBIENT,
+ LOC_MAP_ALBEDO, // LOC_MAP_DIFFUSE
+ LOC_MAP_METALNESS, // LOC_MAP_SPECULAR
+ LOC_MAP_NORMAL,
+ LOC_MAP_ROUGHNESS,
+ LOC_MAP_OCCUSION,
+ LOC_MAP_EMISSION,
+ LOC_MAP_HEIGHT,
+ LOC_MAP_CUBEMAP,
+ LOC_MAP_IRRADIANCE,
+ LOC_MAP_PREFILTER,
+ LOC_MAP_BRDF
+ } ShaderLocationIndex;
+
+ #define LOC_MAP_DIFFUSE LOC_MAP_ALBEDO
+ #define LOC_MAP_SPECULAR LOC_MAP_METALNESS
+
+ // Material map type
+ typedef enum {
+ MAP_ALBEDO = 0, // MAP_DIFFUSE
+ MAP_METALNESS = 1, // MAP_SPECULAR
+ MAP_NORMAL = 2,
+ MAP_ROUGHNESS = 3,
+ MAP_OCCLUSION,
+ MAP_EMISSION,
+ MAP_HEIGHT,
+ MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_PREFILTER, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MAP_BRDF
+ } TexmapIndex;
+
+ #define MAP_DIFFUSE MAP_ALBEDO
+ #define MAP_SPECULAR MAP_METALNESS
+
// VR Head Mounted Display devices
typedef enum {
HMD_DEFAULT_DEVICE = 0,
diff --git a/src/shader_distortion.h b/src/shader_distortion.h
index 7a2c994b..3b37c630 100644
--- a/src/shader_distortion.h
+++ b/src/shader_distortion.h
@@ -1,6 +1,6 @@
// Vertex shader definition to embed, no external file required
-static const char vDistortionShaderStr[] =
+static const char distortionVShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
@@ -29,7 +29,7 @@ static const char vDistortionShaderStr[] =
"} \n";
// Fragment shader definition to embed, no external file required
-static const char fDistortionShaderStr[] =
+static const char distortionFShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
diff --git a/src/text.c b/src/text.c
index 465e4546..8db2fc9f 100644
--- a/src/text.c
+++ b/src/text.c
@@ -872,14 +872,25 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in
// NOTE: We try reading up to 16 MB of elements of 1 byte
fread(ttfBuffer, 1, MAX_TTF_SIZE*1024*1024, ttfFile);
-
+
+ // Find font baseline (vertical origin of the font)
+ // NOTE: This value is required because y-offset depends on it!
+ stbtt_fontinfo fontInfo;
+ int ascent, baseline;
+ float scale;
+
+ stbtt_InitFont(&fontInfo, ttfBuffer, 0);
+ scale = stbtt_ScaleForPixelHeight(&fontInfo, fontSize);
+ stbtt_GetFontVMetrics(&fontInfo, &ascent, 0, 0);
+ baseline = (int)(ascent*scale);
+
if (fontChars[0] != 32) TraceLog(LOG_WARNING, "TTF spritefont loading: first character is not SPACE(32) character");
- // NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image...
+ // NOTE: Using stb_truetype crappy packing method, no guarantee the font fits the image...
// TODO: Replace this function by a proper packing method and support random chars order,
// we already receive a list (fontChars) with the ordered expected characters
int result = stbtt_BakeFontBitmap(ttfBuffer, 0, fontSize, dataBitmap, textureSize, textureSize, fontChars[0], charsCount, charData);
-
+
//if (result > 0) TraceLog(LOG_INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result);
if (result < 0) TraceLog(LOG_WARNING, "TTF spritefont loading: Not all the characters fit in the font");
@@ -924,7 +935,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in
font.chars[i].rec.height = (int)charData[i].y1 - (int)charData[i].y0;
font.chars[i].offsetX = charData[i].xoff;
- font.chars[i].offsetY = charData[i].yoff;
+ font.chars[i].offsetY = baseline + charData[i].yoff;
font.chars[i].advanceX = (int)charData[i].xadvance;
}
diff --git a/src/textures.c b/src/textures.c
index b9fc5c19..090de24b 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -58,6 +58,8 @@
#define SUPPORT_FILEFORMAT_PNG
#define SUPPORT_FILEFORMAT_DDS
#define SUPPORT_FILEFORMAT_HDR
+#define SUPPORT_FILEFORMAT_KTX
+#define SUPPORT_FILEFORMAT_ASTC
#define SUPPORT_IMAGE_MANIPULATION
#define SUPPORT_IMAGE_GENERATION
//-------------------------------------------------
@@ -536,14 +538,13 @@ Image GetTextureData(Texture2D texture)
{
image.width = texture.width;
image.height = texture.height;
+ image.format = texture.format;
image.mipmaps = 1;
- if (rlGetVersion() == OPENGL_ES_20)
- {
- // NOTE: Data retrieved on OpenGL ES 2.0 comes as RGBA (from framebuffer)
- image.format = UNCOMPRESSED_R8G8B8A8;
- }
- else image.format = texture.format;
+ // NOTE: Data retrieved on OpenGL ES 2.0 should be RGBA
+ // coming from FBO color buffer, but it seems original
+ // texture format is retrieved on RPI... weird...
+ //image.format = UNCOMPRESSED_R8G8B8A8;
TraceLog(LOG_INFO, "Texture pixel data obtained successfully");
}
@@ -622,9 +623,9 @@ void ImageFormat(Image *image, int newFormat)
for (int i = 0; i < image->width*image->height; i++)
{
- r = (unsigned char)(round((float)pixels[k].r*31/255));
- g = (unsigned char)(round((float)pixels[k].g*63/255));
- b = (unsigned char)(round((float)pixels[k].b*31/255));
+ r = (unsigned char)(round((float)pixels[i].r*31.0f/255));
+ g = (unsigned char)(round((float)pixels[i].g*63.0f/255));
+ b = (unsigned char)(round((float)pixels[i].b*31.0f/255));
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
}
@@ -655,9 +656,9 @@ void ImageFormat(Image *image, int newFormat)
for (int i = 0; i < image->width*image->height; i++)
{
- r = (unsigned char)(round((float)pixels[i].r*31/255));
- g = (unsigned char)(round((float)pixels[i].g*31/255));
- b = (unsigned char)(round((float)pixels[i].b*31/255));
+ r = (unsigned char)(round((float)pixels[i].r*31.0f/255));
+ g = (unsigned char)(round((float)pixels[i].g*31.0f/255));
+ b = (unsigned char)(round((float)pixels[i].b*31.0f/255));
a = (pixels[i].a > ALPHA_THRESHOLD) ? 1 : 0;
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a;
@@ -675,12 +676,12 @@ void ImageFormat(Image *image, int newFormat)
for (int i = 0; i < image->width*image->height; i++)
{
- r = (unsigned char)(round((float)pixels[i].r*15/255));
- g = (unsigned char)(round((float)pixels[i].g*15/255));
- b = (unsigned char)(round((float)pixels[i].b*15/255));
- a = (unsigned char)(round((float)pixels[i].a*15/255));
-
- ((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a;
+ r = (unsigned char)(round((float)pixels[i].r*15.0f/255));
+ g = (unsigned char)(round((float)pixels[i].g*15.0f/255));
+ b = (unsigned char)(round((float)pixels[i].b*15.0f/255));
+ a = (unsigned char)(round((float)pixels[i].a*15.0f/255));
+
+ ((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a;
}
} break;
@@ -801,7 +802,7 @@ void ImageToPOT(Image *image, Color fillColor)
// Copy an image to a new image
Image ImageCopy(Image image)
{
- Image newImage;
+ Image newImage = { 0 };
int byteSize = image.width*image.height;
@@ -1032,6 +1033,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
+ dstCol.a = ((srcCol.a*(srcCol.a - dstCol.a)) >> 8) + dstCol.a;
dstPixels[j*dst->width + i] = dstCol;
@@ -1067,6 +1069,8 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
int posX = 0;
Vector2 imSize = MeasureTextEx(font, text, font.baseSize, spacing);
+
+ TraceLog(LOG_WARNING, "Text Image size: %f, %f", imSize.x, imSize.y);
// NOTE: glGetTexImage() not available in OpenGL ES
Image imFont = GetTextureData(font.texture);
@@ -1074,31 +1078,22 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
ImageFormat(&imFont, UNCOMPRESSED_R8G8B8A8); // Convert to 32 bit for color tint
ImageColorTint(&imFont, tint); // Apply color tint to font
- Color *fontPixels = GetImageData(imFont);
-
// Create image to store text
- // NOTE: Pixels are initialized to BLANK color (0, 0, 0, 0)
- Color *pixels = (Color *)calloc((int)imSize.x*(int)imSize.y, sizeof(Color));
+ Image imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
for (int i = 0; i < length; i++)
{
- Rectangle letterRec = font.chars[(int)text[i] - 32].rec;
-
- for (int y = letterRec.y; y < (letterRec.y + letterRec.height); y++)
- {
- for (int x = posX; x < (posX + letterRec.width); x++)
- {
- pixels[(y - letterRec.y)*(int)imSize.x + x] = fontPixels[y*font.texture.width + (x - posX + letterRec.x)];
- }
- }
+ CharInfo letter = font.chars[(int)text[i] - 32];
+
+ ImageDraw(&imText, imFont, letter.rec, (Rectangle){ posX + letter.offsetX,
+ letter.offsetY, letter.rec.width, letter.rec.height });
- posX += letterRec.width + spacing;
+ if (letter.advanceX == 0) posX += letter.rec.width + spacing;
+ else posX += letter.advanceX + spacing;
}
UnloadImage(imFont);
- Image imText = LoadImageEx(pixels, (int)imSize.x, (int)imSize.y);
-
// Scale image depending on text size
if (fontSize > imSize.y)
{
@@ -1110,9 +1105,6 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
}
- free(pixels);
- free(fontPixels);
-
return imText;
}
@@ -1452,6 +1444,20 @@ void ImageColorBrightness(Image *image, int brightness)
#endif // SUPPORT_IMAGE_MANIPULATION
#if defined(SUPPORT_IMAGE_GENERATION)
+// Generate image: plain color
+Image GenImageColor(int width, int height, Color color)
+{
+ Color *pixels = (Color *)calloc(width*height, sizeof(Color));
+
+ for (int i = 0; i < width*height; i++) pixels[i] = color;
+
+ Image image = LoadImageEx(pixels, width, height);
+
+ free(pixels);
+
+ return image;
+}
+
// Generate image: vertical gradient
Image GenImageGradientV(int width, int height, Color top, Color bottom)
{
diff --git a/utils.cmake b/utils.cmake
index c902f60e..43b479da 100644
--- a/utils.cmake
+++ b/utils.cmake
@@ -1,49 +1,58 @@
# All sorts of things that we need cross project
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 2.8.0)
-# Detect linux
-if(UNIX AND NOT APPLE)
- set(LINUX TRUE)
+if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+ set(LINUX TRUE)
endif()
-# Need GLFW 3.2.1
-find_package(glfw3 3.2.1 REQUIRED)
-
-
# Linking for OS X -framework options
# Will do nothing on other OSes
-function(link_os_x_frameworks binary)
- if(APPLE)
- find_library(OPENGL_LIBRARY OpenGL)
- find_library(OPENAL_LIBRARY OpenAL)
- find_library(COCOA_LIBRARY Cocoa)
-
- set(OSX_FRAMEWORKS ${OPENGL_LIBRARY} ${OPENAL_LIBRARY} ${COCOA_LIBRARY})
- target_link_libraries(${binary} ${OSX_FRAMEWORKS})
- endif()
-endfunction()
+if(APPLE)
+ find_library(OPENGL_LIBRARY OpenGL)
+ find_library(OPENAL_LIBRARY OpenAL)
+ find_library(COCOA_LIBRARY Cocoa)
+ find_library(IOKIT_LIBRARY IOKit)
+ find_library(COREFOUNDATION_LIBRARY CoreFoundation)
+ find_library(COREVIDEO_LIBRARY CoreVideo)
+
+ set(LIBS_PRIVATE ${OPENGL_LIBRARY} ${OPENAL_LIBRARY} ${COCOA_LIBRARY}
+ ${IOKIT_LIBRARY} ${COREFOUNDATION_LIBRARY} ${COREVIDEO_LIBRARY})
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL Linux)
+ # Elsewhere (such as Linux), need `-lopenal -lGL`, etc...
+ set(LIBS_PRIVATE
+ m pthread dl
+ openal
+ GL
+ X11 Xrandr Xinerama Xi Xxf86vm Xcursor) # X11 stuff
+endif()
+if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ find_package(OpenGL REQUIRED)
+ find_package(OpenAL REQUIRED)
+ include_directories(${OPENGL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR})
+
+ find_package(X11 REQUIRED)
+ find_library(OpenAL REQUIRED)
+ find_library(pthread NAMES pthread)
+ find_library(Xrandr NAMES Xrandr)
+ find_library(Xi NAMES Xi)
+ find_library(Xinerama NAMES Xinerama)
+ find_library(Xxf86vm NAMES Xxf86vm)
+ find_library(Xcursor NAMES Xcursor)
+
+ set(LIBS_PRIVATE m ${pthread} ${OPENAL_LIBRARY} ${X11_LIBRARIES} ${Xrandr} ${Xinerama} ${Xi} ${Xxf86vm} ${Xcursor})
+endif()
+
+# TODO Support Windows
# Do the linking for executables that are meant to link raylib
function(link_libraries_to_executable executable)
- # Link the libraries
- if(APPLE)
- # OS X, we use frameworks
- link_os_x_frameworks(${executable})
- elseif(LINUX)
- # Elsewhere (such as Linux), need `-lopenal -lGL`, etc...
- target_link_libraries(${executable} m pthread dl)
- target_link_libraries(${executable} openal)
- target_link_libraries(${executable} GL)
- target_link_libraries(${executable} X11 Xrandr Xinerama Xi Xxf86vm Xcursor) # X11 stuff
- else()
- # TODO windows
- endif()
-
- # Add in GLFW as a linking target
- target_link_libraries(${executable} glfw)
-
# And raylib
target_link_libraries(${executable} raylib)
+
+ # Link the libraries
+ target_link_libraries(${executable} ${LIBS_PRIVATE})
endfunction()