diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ad321d9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,93 @@ +* text=auto + +*.txt text +*.md text + +#sources +*.c text +*.cc text +*.cxx text +*.cpp text +*.c++ text +*.hpp text +*.h text +*.h++ text +*.hh text + +# Compiled Object files +*.slo binary +*.lo binary +*.o binary +*.obj binary + +# Precompiled Headers +*.gch binary +*.pch binary + +# Compiled Dynamic libraries +*.so binary +*.dylib binary +*.dll binary + +# Compiled Static libraries +*.lai binary +*.la binary +*.a binary +*.lib binary + +# Executables +*.exe binary +*.out binary +*.app binary + +############################################################################### +# +# Visual Studio +# +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just comment the entries below and +# uncomment the group further below +############################################################################### + +*.sln text eol=crlf +*.csproj text eol=crlf +*.vbproj text eol=crlf +*.vcxproj text eol=crlf +*.vcproj text eol=crlf +*.dbproj text eol=crlf +*.fsproj text eol=crlf +*.lsproj text eol=crlf +*.wixproj text eol=crlf +*.modelproj text eol=crlf +*.sqlproj text eol=crlf +*.wmaproj text eol=crlf + +*.xproj test eol=crlf +*.props text eol=crlf +*.filters text eol=crlf +*.vcxitems text eol=crlf + + +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +#*.xproj merge=binary +#*.props merge=binary +#*.filters merge=binary +#*.vcxitems merge=binary diff --git a/.gitignore b/.gitignore index 1bcf136..6834f7c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ -bin/ -build/ -*.txt.user +bin +build +libglfw3.a +libglfw3_d.a +libsb7_d.a diff --git a/CMakeLists.txt b/CMakeLists.txt index 580758a..26af20e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 3.0) project (superbible7) @@ -22,6 +22,10 @@ set (CMAKE_DEBUG_POSTFIX "_d") if(WIN32) set(COMMON_LIBS sb7 optimized glfw3 debug glfw3_d ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES}) +elseif(APPLE) + set(COMMON_LIBS sb7 glfw3 ${OPENGL_LIBRARIES} + "-framework Cocoa -framework IOKit" + "-framework CoreFoundation -framework CoreVideo") elseif (UNIX) find_package(PkgConfig REQUIRED) pkg_check_modules(GLFW REQUIRED glfw3) @@ -91,13 +95,13 @@ set(EXAMPLES noperspective normalviewer objectexploder - ompparticles +# ompparticles packetbuffer perpixelgloss phonglighting polygonsmooth prefixsum - pmbfractal +# pmbfractal pmbstreaming prefixsum2d programinfo diff --git a/HOWTOBUILD.txt b/HOWTOBUILD.txt index 5fd5296..a058445 100644 --- a/HOWTOBUILD.txt +++ b/HOWTOBUILD.txt @@ -40,6 +40,20 @@ Open the resulting superbible7.sln project in Visual Studio. The examples will build into the `bin` directory. +Windows / CodeBlocks + MINGW32 +------------------------------ + +The basic process is the same. CodeBlocks does not recognize build configurations, so simply build with +the default config and copy `glwf3.lib` and skip `glfw3_d.lib`. + +By default, CodeBlocks/MINGW32 does not come with OpenMP, so you may want to comment out (using `#`) +building of `ompparticles` and `pmbfractals` or manually install OpenMP. + +C++11 is not the default language standard as of CodeBlocks 16.01. The use of the `M_PI` macro is not +strict C++11, so the compiler needs to be instructed to relax that requirement. To achieve this, add +the following to the `CMAKE_CXX_FLAGS` when configuring: + `-std=c++11 -U__STRICT_ANSI__ -D_USE_MATH_DEFINES` + Linux ----- diff --git a/extern/glfw-3.2.1/.appveyor.yml b/extern/glfw-3.2.1/.appveyor.yml new file mode 100644 index 0000000..ae658cc --- /dev/null +++ b/extern/glfw-3.2.1/.appveyor.yml @@ -0,0 +1,22 @@ +branches: + only: + - ci + - master +skip_tags: true +environment: + matrix: + - BUILD_SHARED_LIBS: ON + - BUILD_SHARED_LIBS: OFF +matrix: + fast_finish: true +build_script: + - mkdir build + - cd build + - cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% .. + - cmake --build . +notifications: + - provider: Email + to: + - ci@glfw.org + - on_build_failure: true + - on_build_success: false diff --git a/extern/glfw-3.2.1/.github/CONTRIBUTING.md b/extern/glfw-3.2.1/.github/CONTRIBUTING.md new file mode 100644 index 0000000..672264d --- /dev/null +++ b/extern/glfw-3.2.1/.github/CONTRIBUTING.md @@ -0,0 +1,346 @@ +# Contribution Guide + +## Contents + +- [Asking a question](#asking-a-question) +- [Reporting a bug](#reporting-a-bug) + - [Reporting a compile or link bug](#reporting-a-compile-or-link-bug) + - [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug) + - [Reporting a context creation bug](#reporting-a-context-creation-bug) + - [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug) + - [Reporting an input or event bug](#reporting-an-input-or-event-bug) + - [Reporting some other library bug](#reporting-some-other-library-bug) + - [Reporting a documentation bug](#reporting-a-documentation-bug) + - [Reporting a website bug](#reporting-a-website-bug) +- [Requesting a feature](#requesting-a-feature) +- [Contributing a bug fix](#contributing-a-bug-fix) +- [Contributing a feature](#contributing-a-feature) + + +## Asking a question + +Questions about how to use GLFW should be asked either in the [support +section](http://discourse.glfw.org/c/support) of the forum, under the [Stack +Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game +Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on +Stack Exchange or in the IRC channel `#glfw` on +[Freenode](http://freenode.net/). + +Questions about the design or implementation of GLFW or about future plans +should be asked in the [dev section](http://discourse.glfw.org/c/dev) of the +forum or in the IRC channel. Please don't open a GitHub issue to discuss design +questions without first checking with a maintainer. + + +## Reporting a bug + +If GLFW is behaving unexpectedly at run-time, start by setting an [error +callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling). +GLFW will often tell you the cause of an error via this callback. If it +doesn't, that might be a separate bug. + +If GLFW is crashing or triggering asserts, make sure that all your object +handles and other pointers are valid. + +For bugs where it makes sense, a [Short, Self Contained, Correct (Compilable), +Example](http://www.sscce.org/) is absolutely invaluable. Just put it inline in +the body text. Note that if the bug is reproducible with one of the test +programs that come with GLFW, just mention that instead. + +__Don't worry about adding too much information__. Unimportant information can +be abbreviated or removed later, but missing information can stall bug fixing, +especially when your schedule doesn't align with that of the maintainer. + +There are issue labels for both platforms and GPU manufacturers, so there is no +need to mention these in the subject line. If you do, it will be removed when +the issue is labeled. + +If your bug is already reported, please add any new information you have, or if +it already has everything, give it a :+1:. + + +### Reporting a compile or link bug + +__Note:__ GLFW needs many system APIs to do its job, which on some platforms +means linking to many system libraries. If you are using GLFW as a static +library, that means your application needs to link to these in addition to GLFW. + +__Note:__ Check the [Compiling +GLFW](http://www.glfw.org/docs/latest/compile.html) guide and or [Building +applications](http://www.glfw.org/docs/latest/build.html) guide for before +opening an issue of this kind. Most issues are caused by a missing package or +linker flag. + +Always include the __operating system name and version__ (e.g. `Windows +7 64-bit` or `Ubuntu 15.10`) and the __compiler name and version__ (e.g. `Visual +C++ 2015 Update 2`). If you are using an official release of GLFW, +include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the +__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. + +Please also include the __complete build log__ from your compiler and linker, +even if it's long. It can always be shortened later, if necessary. + + +#### Quick template + +``` +OS and version: +Compiler version: +Release or commit: +Build log: +``` + + +### Reporting a segfault or other crash bug + +Always include the __operating system name and version__ (e.g. `Windows +7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, +include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the +__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. + +Please also include any __error messages__ provided to your application via the +[error +callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and +the __full call stack__ of the crash, or if the crash does not occur in debug +mode, mention that instead. + + +#### Quick template + +``` +OS and version: +Release or commit: +Error messages: +Call stack: +``` + + +### Reporting a context creation bug + +__Note:__ Windows ships with graphics drivers that do not support OpenGL. If +GLFW says that your machine lacks support for OpenGL, it very likely does. +Install drivers from the computer manufacturer or graphics card manufacturer +([Nvidia](http://www.geforce.com/drivers), +[AMD](http://support.amd.com/en-us/download), +[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to +fix this. + +__Note:__ AMD only supports OpenGL ES on Windows via EGL. See the +[GLFW\_CONTEXT\_CREATION\_API](http://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx) +hint for how to select EGL. + +Please verify that context creation also fails with the `glfwinfo` tool before +reporting it as a bug. This tool is included in the GLFW source tree as +`tests/glfwinfo.c` and is built along with the library. It has switches for all +GLFW context and framebuffer hints. Run `glfwinfo -h` for a complete list. + +Always include the __operating system name and version__ (e.g. `Windows +7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, +include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the +__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. + +Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime +/dev/js XI Xf86vm`), as described +[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string), the +__GPU model and driver version__ (e.g. `GeForce GTX660 with 352.79`), and the +__output of `glfwinfo`__ (with switches matching any hints you set in your +code) when reporting this kind of bug. If this tool doesn't run on the machine, +mention that instead. + + +#### Quick template + +``` +OS and version: +GPU and driver: +Release or commit: +Version string: +glfwinfo output: +``` + + +### Reporting a monitor or video mode bug + +__Note:__ On headless systems on some platforms, no monitors are reported. This +causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are +prepared for. + +__Note:__ Some third-party tools report more video modes than are approved of +by the OS. For safety and compatibility, GLFW only reports video modes the OS +wants programs to use. This is not a bug. + +The `monitors` tool is included in the GLFW source tree as `tests/monitors.c` +and is built along with the library. It lists all information GLFW provides +about monitors it detects. + +Always include the __operating system name and version__ (e.g. `Windows +7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, +include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the +__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. + +Please also include any __error messages__ provided to your application via the +[error +callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and +the __output of `monitors`__ when reporting this kind of bug. If this tool +doesn't run on the machine, mention this instead. + + +#### Quick template + +``` +OS and version: +Release or commit: +Error messages: +monitors output: +``` + + +### Reporting an input or event bug + +__Note:__ The exact ordering of related window events will sometimes differ. + +__Note:__ Window moving and resizing (by the user) will block the main thread on some +platforms. This is not a bug. Set a [refresh +callback](http://www.glfw.org/docs/latest/window.html#window_refresh) if you +want to keep the window contents updated during a move or size operation. + +The `events` tool is included in the GLFW source tree as `tests/events.c` and is +built along with the library. It prints all information provided to every +callback supported by GLFW as events occur. Each event is listed with the time +and a unique number to make discussions about event logs easier. The tool has +command-line options for creating multiple windows and full screen windows. + +Always include the __operating system name and version__ (e.g. `Windows +7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, +include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the +__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. + +Please also include any __error messages__ provided to your application via the +[error +callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and +if relevant, the __output of `events`__ when reporting this kind of bug. If +this tool doesn't run on the machine, mention this instead. + + +#### Quick template + +``` +OS and version: +Release or commit: +Error messages: +events output: +``` + + +### Reporting some other library bug + +Always include the __operating system name and version__ (e.g. `Windows +7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, +include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the +__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. + +Please also include any __error messages__ provided to your application via the +[error +callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling), if +relevant. + + +#### Quick template + +``` +OS and version: +Release or commit: +Error messages: +``` + + +### Reporting a documentation bug + +If you found a bug in the documentation, including this file, then it's fine to +just link to that web page or mention that source file. You don't need to match +the source to the output or vice versa. + + +### Reporting a website bug + +If the bug is in the documentation (anything under `/docs/`) then please see the +section above. Bugs in the rest of the site are reported to to the [website +source repository](https://github.com/glfw/website/issues). + + +## Requesting a feature + +Please explain why you need the feature and how you intend to use it. If you +have a specific API design in mind, please add that as well. If you have or are +planning to write code for the feature, see the section below. + +If there already is a request for the feature you need, add your specific use +case unless it is already mentioned. If it is, give it a :+1:. + + +## Contributing a bug fix + +__Note:__ You must have all necessary [intellectual +property rights](https://en.wikipedia.org/wiki/Intellectual_property) to any +code you contribute. If you did not write the code yourself, you must explain +where it came from and under what license you received it. Even code using the +same license as GLFW may not be copied without attribution. + +__There is no preferred patch size__. A one character fix is just as welcome as +a thousand line one, if that is the appropriate size for the fix. + +In addition to the code, a complete bug fix includes: + +- Change log entry in `README.md`, describing the incorrect behavior +- Credits entries for all authors of the bug fix + +Bug fixes will not be rejected because they don't include all the above parts, +but please keep in mind that maintainer time is finite and that there are many +other bugs and features to work on. + +If the patch fixes a bug introduced after the last release, it should not get +a change log entry. + + +## Contributing a feature + +__Note:__ You must have all necessary rights to any code you contribute. If you +did not write the code yourself, you must explain where it came from and under +what license. Even code using the same license as GLFW may not be copied +without attribution. + +__There is no preferred patch size__. A one character change is just as welcome +as one adding a thousand line one, if that is the appropriate size for the +feature. + +In addition to the code, a complete feature includes: + +- Change log entry in `README.md`, listing all new symbols +- News page entry, briefly describing the feature +- Guide documentation, with minimal examples, in the relevant guide +- Reference documentation, with all applicable tags +- Cross-references and mentions in appropriate places +- Credits entries for all authors of the feature + +If the feature requires platform-specific code, at minimum stubs must be added +for the new platform function to all supported and experimental platforms. + +If it adds a new callback, support for it must be added to `tests/event.c`. + +If it adds a new monitor property, support for it must be added to +`tests/monitor.c`. + +If it adds a new OpenGL, OpenGL ES or Vulkan option or extension, support +for it must be added to `tests/glfwinfo.c` and the behavior of the library when +the extension is missing documented in `docs/compat.dox`. + +Features will not be rejected because they don't include all the above parts, +but please keep in mind that maintainer time is finite and that there are many +other features and bugs to work on. + +Please also keep in mind that any part of the public API that has been included +in a release cannot be changed until the next _major_ version. Features can be +added and existing parts can sometimes be overloaded (in the general sense of +doing more things, not in the C++ sense), but code written to the API of one +minor release should both compile and run on subsequent minor releases. + diff --git a/extern/glfw-3.2.1/.travis.yml b/extern/glfw-3.2.1/.travis.yml new file mode 100644 index 0000000..ff1c6c3 --- /dev/null +++ b/extern/glfw-3.2.1/.travis.yml @@ -0,0 +1,30 @@ +language: c +compiler: clang +branches: + only: + - ci + - master +os: + - linux + - osx +sudo: false +addons: + apt: + sources: + - kubuntu-backports + packages: + - cmake +env: + - BUILD_SHARED_LIBS=ON + - BUILD_SHARED_LIBS=OFF +script: + - mkdir build + - cd build + - cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} .. + - cmake --build . +notifications: + email: + recipients: + - ci@glfw.org + on_success: never + on_failure: always diff --git a/extern/glfw-3.2.1/CMake/MacOSXBundleInfo.plist.in b/extern/glfw-3.2.1/CMake/MacOSXBundleInfo.plist.in new file mode 100644 index 0000000..684ad79 --- /dev/null +++ b/extern/glfw-3.2.1/CMake/MacOSXBundleInfo.plist.in @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ???? + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + LSRequiresCarbon + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + NSHighResolutionCapable + + + diff --git a/extern/glfw-3.2.1/CMake/amd64-mingw32msvc.cmake b/extern/glfw-3.2.1/CMake/amd64-mingw32msvc.cmake new file mode 100644 index 0000000..705e251 --- /dev/null +++ b/extern/glfw-3.2.1/CMake/amd64-mingw32msvc.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win64 +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "amd64-mingw32msvc-gcc") +SET(CMAKE_CXX_COMPILER "amd64-mingw32msvc-g++") +SET(CMAKE_RC_COMPILER "amd64-mingw32msvc-windres") +SET(CMAKE_RANLIB "amd64-mingw32msvc-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/amd64-mingw32msvc") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/extern/glfw-3.2.1/CMake/i586-mingw32msvc.cmake b/extern/glfw-3.2.1/CMake/i586-mingw32msvc.cmake new file mode 100644 index 0000000..393ddbd --- /dev/null +++ b/extern/glfw-3.2.1/CMake/i586-mingw32msvc.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "i586-mingw32msvc-gcc") +SET(CMAKE_CXX_COMPILER "i586-mingw32msvc-g++") +SET(CMAKE_RC_COMPILER "i586-mingw32msvc-windres") +SET(CMAKE_RANLIB "i586-mingw32msvc-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/i586-mingw32msvc") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/extern/glfw-3.2.1/CMake/i686-pc-mingw32.cmake b/extern/glfw-3.2.1/CMake/i686-pc-mingw32.cmake new file mode 100644 index 0000000..9a46aef --- /dev/null +++ b/extern/glfw-3.2.1/CMake/i686-pc-mingw32.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "i686-pc-mingw32-gcc") +SET(CMAKE_CXX_COMPILER "i686-pc-mingw32-g++") +SET(CMAKE_RC_COMPILER "i686-pc-mingw32-windres") +SET(CMAKE_RANLIB "i686-pc-mingw32-ranlib") + +#Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/opt/mingw/usr/i686-pc-mingw32") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/extern/glfw-3.2.1/CMake/i686-w64-mingw32.cmake b/extern/glfw-3.2.1/CMake/i686-w64-mingw32.cmake new file mode 100644 index 0000000..9bd6093 --- /dev/null +++ b/extern/glfw-3.2.1/CMake/i686-w64-mingw32.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc") +SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++") +SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres") +SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/extern/glfw-3.2.1/CMake/modules/FindMir.cmake b/extern/glfw-3.2.1/CMake/modules/FindMir.cmake new file mode 100644 index 0000000..b1a495b --- /dev/null +++ b/extern/glfw-3.2.1/CMake/modules/FindMir.cmake @@ -0,0 +1,18 @@ +# Try to find Mir on a Unix system +# +# This will define: +# +# MIR_LIBRARIES - Link these to use Wayland +# MIR_INCLUDE_DIR - Include directory for Wayland +# +# Copyright (c) 2014 Brandon Schaefer + +if (NOT WIN32) + + find_package (PkgConfig) + pkg_check_modules (PKG_MIR QUIET mirclient) + + set (MIR_INCLUDE_DIR ${PKG_MIR_INCLUDE_DIRS}) + set (MIR_LIBRARIES ${PKG_MIR_LIBRARIES}) + +endif () diff --git a/extern/glfw-3.2.1/CMake/modules/FindVulkan.cmake b/extern/glfw-3.2.1/CMake/modules/FindVulkan.cmake new file mode 100644 index 0000000..d3a664a --- /dev/null +++ b/extern/glfw-3.2.1/CMake/modules/FindVulkan.cmake @@ -0,0 +1,34 @@ +# Find Vulkan +# +# VULKAN_INCLUDE_DIR +# VULKAN_LIBRARY +# VULKAN_FOUND + +if (WIN32) + find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS + "$ENV{VULKAN_SDK}/Include" + "$ENV{VK_SDK_PATH}/Include") + if (CMAKE_CL_64) + find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS + "$ENV{VULKAN_SDK}/Bin" + "$ENV{VK_SDK_PATH}/Bin") + find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS + "$ENV{VULKAN_SDK}/Bin" + "$ENV{VK_SDK_PATH}/Bin") + else() + find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS + "$ENV{VULKAN_SDK}/Bin32" + "$ENV{VK_SDK_PATH}/Bin32") + endif() +else() + find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS + "$ENV{VULKAN_SDK}/include") + find_library(VULKAN_LIBRARY NAMES vulkan HINTS + "$ENV{VULKAN_SDK}/lib") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR) + +mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY VULKAN_STATIC_LIBRARY) + diff --git a/extern/glfw-3.2.1/CMake/modules/FindWaylandProtocols.cmake b/extern/glfw-3.2.1/CMake/modules/FindWaylandProtocols.cmake new file mode 100644 index 0000000..8eb83f2 --- /dev/null +++ b/extern/glfw-3.2.1/CMake/modules/FindWaylandProtocols.cmake @@ -0,0 +1,26 @@ +find_package(PkgConfig) + +pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION}) + +execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols + OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR + RESULT_VARIABLE _pkgconfig_failed) +if (_pkgconfig_failed) + message(FATAL_ERROR "Missing wayland-protocols pkgdatadir") +endif() + +string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}") + +find_package_handle_standard_args(WaylandProtocols + FOUND_VAR + WaylandProtocols_FOUND + REQUIRED_VARS + WaylandProtocols_PKGDATADIR + VERSION_VAR + WaylandProtocols_VERSION + HANDLE_COMPONENTS +) + +set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND}) +set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR}) +set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION}) diff --git a/extern/glfw-3.2.1/CMake/modules/FindXKBCommon.cmake b/extern/glfw-3.2.1/CMake/modules/FindXKBCommon.cmake new file mode 100644 index 0000000..0f571ee --- /dev/null +++ b/extern/glfw-3.2.1/CMake/modules/FindXKBCommon.cmake @@ -0,0 +1,34 @@ +# - Try to find XKBCommon +# Once done, this will define +# +# XKBCOMMON_FOUND - System has XKBCommon +# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories +# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon +# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon + +find_package(PkgConfig) +pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon) +set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER}) + +find_path(XKBCOMMON_INCLUDE_DIR + NAMES xkbcommon/xkbcommon.h + HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS} +) + +find_library(XKBCOMMON_LIBRARY + NAMES xkbcommon + HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS} +) + +set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY}) +set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS}) +set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(XKBCommon DEFAULT_MSG + XKBCOMMON_LIBRARY + XKBCOMMON_INCLUDE_DIR +) + +mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR) + diff --git a/extern/glfw-3.2.1/CMake/x86_64-w64-mingw32.cmake b/extern/glfw-3.2.1/CMake/x86_64-w64-mingw32.cmake new file mode 100644 index 0000000..84b2c70 --- /dev/null +++ b/extern/glfw-3.2.1/CMake/x86_64-w64-mingw32.cmake @@ -0,0 +1,13 @@ +# Define the environment for cross compiling from Linux to Win32 +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) +SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc") +SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++") +SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres") +SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib") + +# Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/extern/glfw-3.2.1/CMakeLists.txt b/extern/glfw-3.2.1/CMakeLists.txt new file mode 100644 index 0000000..b1476bd --- /dev/null +++ b/extern/glfw-3.2.1/CMakeLists.txt @@ -0,0 +1,419 @@ +set(CMAKE_LEGACY_CYGWIN_WIN32 OFF) + +project(GLFW C) + +cmake_minimum_required(VERSION 2.8.12) + +if (NOT CMAKE_VERSION VERSION_LESS "3.0") + # Until all major package systems have moved to CMake 3, + # we stick with the older INSTALL_NAME_DIR mechanism + cmake_policy(SET CMP0042 OLD) +endif() + +set(GLFW_VERSION_MAJOR "3") +set(GLFW_VERSION_MINOR "2") +set(GLFW_VERSION_PATCH "1") +set(GLFW_VERSION_EXTRA "") +set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") +set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") +set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64") + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +option(BUILD_SHARED_LIBS "Build shared libraries" OFF) +option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) +option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) +option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) +option(GLFW_INSTALL "Generate installation target" ON) +option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF) +option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) + +if (WIN32) + option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF) +endif() + +if (APPLE) + option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON) + option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON) + option(GLFW_USE_RETINA "Use the full resolution of Retina displays" ON) +endif() + +if (UNIX AND NOT APPLE) + option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF) + option(GLFW_USE_MIR "Use Mir for window creation" OFF) +endif() + +if (MSVC) + option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON) +endif() + +if (BUILD_SHARED_LIBS) + set(_GLFW_BUILD_DLL 1) +endif() + +if (BUILD_SHARED_LIBS AND UNIX) + # On Unix-like systems, shared libraries can use the soname system. + set(GLFW_LIB_NAME glfw) +else() + set(GLFW_LIB_NAME glfw3) +endif() + +if (GLFW_VULKAN_STATIC) + set(_GLFW_VULKAN_STATIC 1) +endif() + +list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") + +find_package(Threads REQUIRED) +find_package(Vulkan) + +if (GLFW_BUILD_DOCS) + set(DOXYGEN_SKIP_DOT TRUE) + find_package(Doxygen) +endif() + +#-------------------------------------------------------------------- +# Set compiler specific flags +#-------------------------------------------------------------------- +if (MSVC) + if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) + foreach (flag CMAKE_C_FLAGS + CMAKE_C_FLAGS_DEBUG + CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL + CMAKE_C_FLAGS_RELWITHDEBINFO) + + if (${flag} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}") + endif() + if (${flag} MATCHES "/MDd") + string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}") + endif() + + endforeach() + endif() +endif() + +if (MINGW) + # Workaround for legacy MinGW not providing XInput and DirectInput + include(CheckIncludeFile) + + check_include_file(dinput.h DINPUT_H_FOUND) + check_include_file(xinput.h XINPUT_H_FOUND) + if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND) + list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw") + endif() + + # Enable link-time exploit mitigation features enabled by default on MSVC + include(CheckCCompilerFlag) + + # Compatibility with data execution prevention (DEP) + set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat") + check_c_compiler_flag("" _GLFW_HAS_DEP) + if (_GLFW_HAS_DEP) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}") + endif() + + # Compatibility with address space layout randomization (ASLR) + set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase") + check_c_compiler_flag("" _GLFW_HAS_ASLR) + if (_GLFW_HAS_ASLR) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}") + endif() + + # Compatibility with 64-bit address space layout randomization (ASLR) + set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va") + check_c_compiler_flag("" _GLFW_HAS_64ASLR) + if (_GLFW_HAS_64ASLR) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}") + endif() +endif() + +#-------------------------------------------------------------------- +# Detect and select backend APIs +#-------------------------------------------------------------------- +if (WIN32) + set(_GLFW_WIN32 1) + message(STATUS "Using Win32 for window creation") +elseif (APPLE) + set(_GLFW_COCOA 1) + message(STATUS "Using Cocoa for window creation") +elseif (UNIX) + if (GLFW_USE_WAYLAND) + set(_GLFW_WAYLAND 1) + message(STATUS "Using Wayland for window creation") + elseif (GLFW_USE_MIR) + set(_GLFW_MIR 1) + message(STATUS "Using Mir for window creation") + else() + set(_GLFW_X11 1) + message(STATUS "Using X11 for window creation") + endif() +else() + message(FATAL_ERROR "No supported platform was detected") +endif() + +#-------------------------------------------------------------------- +# Add Vulkan static library if requested +#-------------------------------------------------------------------- +if (GLFW_VULKAN_STATIC) + if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY) + list(APPEND glfw_LIBRARIES ${VULKAN_STATIC_LIBRARY}) + else() + if (BUILD_SHARED_LIBS OR GLFW_BUILD_EXAMPLES OR GLFW_BUILD_TESTS) + message(FATAL_ERROR "Vulkan loader static library not found") + else() + message(WARNING "Vulkan loader static library not found") + endif() + endif() +endif() + +#-------------------------------------------------------------------- +# Find and add Unix math and time libraries +#-------------------------------------------------------------------- +if (UNIX AND NOT APPLE) + find_library(RT_LIBRARY rt) + mark_as_advanced(RT_LIBRARY) + if (RT_LIBRARY) + list(APPEND glfw_LIBRARIES "${RT_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lrt") + endif() + + find_library(MATH_LIBRARY m) + mark_as_advanced(MATH_LIBRARY) + if (MATH_LIBRARY) + list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}") + list(APPEND glfw_PKG_LIBS "-lm") + endif() + + if (CMAKE_DL_LIBS) + list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}") + list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}") + endif() +endif() + +#-------------------------------------------------------------------- +# Use Win32 for window creation +#-------------------------------------------------------------------- +if (_GLFW_WIN32) + + list(APPEND glfw_PKG_LIBS "-lgdi32") + + if (GLFW_USE_HYBRID_HPG) + set(_GLFW_USE_HYBRID_HPG 1) + endif() +endif() + +#-------------------------------------------------------------------- +# Use X11 for window creation +#-------------------------------------------------------------------- +if (_GLFW_X11) + + find_package(X11 REQUIRED) + + list(APPEND glfw_PKG_DEPS "x11") + + # Set up library and include paths + list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") + + # Check for XRandR (modern resolution switching and gamma control) + if (NOT X11_Xrandr_FOUND) + message(FATAL_ERROR "The RandR library and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}") + list(APPEND glfw_PKG_DEPS "xrandr") + + # Check for Xinerama (legacy multi-monitor support) + if (NOT X11_Xinerama_FOUND) + message(FATAL_ERROR "The Xinerama library and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIRS "${X11_Xinerama_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_Xinerama_LIB}") + list(APPEND glfw_PKG_DEPS "xinerama") + + # Check for Xf86VidMode (fallback gamma control) + if (X11_xf86vmode_FOUND) + list(APPEND glfw_INCLUDE_DIRS "${X11_xf86vmode_INCLUDE_PATH}") + list(APPEND glfw_PKG_DEPS "xxf86vm") + + if (X11_Xxf86vm_LIB) + list(APPEND glfw_LIBRARIES "${X11_Xxf86vm_LIB}") + else() + # Backwards compatibility (see CMake bug 0006976) + list(APPEND glfw_LIBRARIES Xxf86vm) + endif() + + set(_GLFW_HAS_XF86VM TRUE) + endif() + + # Check for Xkb (X keyboard extension) + if (NOT X11_Xkb_FOUND) + message(FATAL_ERROR "The X keyboard extension headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIR "${X11_Xkb_INCLUDE_PATH}") + + # Check for Xcursor + if (NOT X11_Xcursor_FOUND) + message(FATAL_ERROR "The Xcursor libraries and headers were not found") + endif() + + list(APPEND glfw_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}") + list(APPEND glfw_LIBRARIES "${X11_Xcursor_LIB}") + list(APPEND glfw_PKG_DEPS "xcursor") + +endif() + +#-------------------------------------------------------------------- +# Use Wayland for window creation +#-------------------------------------------------------------------- +if (_GLFW_WAYLAND) + find_package(ECM REQUIRED NO_MODULE) + list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + + find_package(Wayland REQUIRED) + find_package(WaylandScanner REQUIRED) + find_package(WaylandProtocols 1.1 REQUIRED) + + list(APPEND glfw_PKG_DEPS "wayland-egl") + + list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") + + find_package(XKBCommon REQUIRED) + list(APPEND glfw_PKG_DEPS "xkbcommon") + list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") + list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") +endif() + +#-------------------------------------------------------------------- +# Use Mir for window creation +#-------------------------------------------------------------------- +if (_GLFW_MIR) + find_package(Mir REQUIRED) + list(APPEND glfw_PKG_DEPS "mirclient") + + list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIR}") + list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") + + find_package(XKBCommon REQUIRED) + list(APPEND glfw_PKG_DEPS "xkbcommon") + list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}") + list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") +endif() + +#-------------------------------------------------------------------- +# Use Cocoa for window creation and NSOpenGL for context creation +#-------------------------------------------------------------------- +if (_GLFW_COCOA) + + if (GLFW_USE_MENUBAR) + set(_GLFW_USE_MENUBAR 1) + endif() + + if (GLFW_USE_CHDIR) + set(_GLFW_USE_CHDIR 1) + endif() + + if (GLFW_USE_RETINA) + set(_GLFW_USE_RETINA 1) + endif() + + # Set up library and include paths + find_library(COCOA_FRAMEWORK Cocoa) + find_library(IOKIT_FRAMEWORK IOKit) + find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) + find_library(CORE_VIDEO_FRAMEWORK CoreVideo) + mark_as_advanced(COCOA_FRAMEWORK + IOKIT_FRAMEWORK + CORE_FOUNDATION_FRAMEWORK + CORE_VIDEO_FRAMEWORK) + list(APPEND glfw_LIBRARIES "${COCOA_FRAMEWORK}" + "${IOKIT_FRAMEWORK}" + "${CORE_FOUNDATION_FRAMEWORK}" + "${CORE_VIDEO_FRAMEWORK}") + + set(glfw_PKG_DEPS "") + set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo") +endif() + +#-------------------------------------------------------------------- +# Export GLFW library dependencies +#-------------------------------------------------------------------- +foreach(arg ${glfw_PKG_DEPS}) + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}") +endforeach() +foreach(arg ${glfw_PKG_LIBS}) + set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}") +endforeach() + +#-------------------------------------------------------------------- +# Create generated files +#-------------------------------------------------------------------- +include(CMakePackageConfigHelpers) + +set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3") + +configure_package_config_file(src/glfw3Config.cmake.in + src/glfw3Config.cmake + INSTALL_DESTINATION "${GLFW_CONFIG_PATH}" + NO_CHECK_REQUIRED_COMPONENTS_MACRO) + +write_basic_package_version_file(src/glfw3ConfigVersion.cmake + VERSION ${GLFW_VERSION_FULL} + COMPATIBILITY SameMajorVersion) + +configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY) + +configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY) + +#-------------------------------------------------------------------- +# Add subdirectories +#-------------------------------------------------------------------- +add_subdirectory(src) + +if (GLFW_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +if (GLFW_BUILD_TESTS) + add_subdirectory(tests) +endif() + +if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS) + add_subdirectory(docs) +endif() + +#-------------------------------------------------------------------- +# Install files other than the library +# The library is installed by src/CMakeLists.txt +#-------------------------------------------------------------------- +if (GLFW_INSTALL) + install(DIRECTORY include/GLFW DESTINATION include + FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h) + + install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" + "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake" + DESTINATION "${GLFW_CONFIG_PATH}") + + install(EXPORT glfwTargets FILE glfw3Targets.cmake + EXPORT_LINK_INTERFACE_LIBRARIES + DESTINATION "${GLFW_CONFIG_PATH}") + install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" + DESTINATION "lib${LIB_SUFFIX}/pkgconfig") + + # Only generate this target if no higher-level project already has + if (NOT TARGET uninstall) + configure_file(cmake_uninstall.cmake.in + cmake_uninstall.cmake IMMEDIATE @ONLY) + + add_custom_target(uninstall + "${CMAKE_COMMAND}" -P + "${GLFW_BINARY_DIR}/cmake_uninstall.cmake") + endif() +endif() + diff --git a/extern/glfw-3.2.1/COPYING.txt b/extern/glfw-3.2.1/COPYING.txt new file mode 100644 index 0000000..ad16462 --- /dev/null +++ b/extern/glfw-3.2.1/COPYING.txt @@ -0,0 +1,22 @@ +Copyright (c) 2002-2006 Marcus Geelnard +Copyright (c) 2006-2016 Camilla Berglund + +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/extern/glfw-3.2.1/README.md b/extern/glfw-3.2.1/README.md new file mode 100644 index 0000000..44e85fe --- /dev/null +++ b/extern/glfw-3.2.1/README.md @@ -0,0 +1,274 @@ +# 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 is licensed under the [zlib/libpng +license](https://opensource.org/licenses/Zlib). + +This is version 3.2.1, which adds support for statically linking the Vulkan +loader and fixes for a number of bugs that together affect all supported +platforms. + +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. + +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) 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 OS X 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 also [pre-compiled Windows +binaries](http://www.glfw.org/download.html) available for all compilers +supported on that platform. + +See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) in the +documentation for more information. + + +## Using GLFW + +See the [building application guide](http://www.glfw.org/docs/latest/build.html) +guide in the documentation for more information. + + +## System requirements + +GLFW supports Windows XP and later, OS X 10.7 Lion and later, and Linux and +other Unix-like systems with the X Window System. Experimental implementations +for the Wayland protocol and the Mir display server are available but not yet +officially supported. + +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 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 + - [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. + +The documentation is generated with [Doxygen](http://doxygen.org/). If CMake +does not find Doxygen, the documentation will not be generated when you build. + + +## 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 on-demand loading of Vulkan and context creation API libraries + - Added `_GLFW_VULKAN_STATIC` build macro to make the library use the Vulkan + loader linked statically into the application (#820) + - Bugfix: Single compilation unit builds failed due to naming conflicts (#783) + - Bugfix: The range checks for `glfwSetCursorPos` used the wrong minimum (#773) + - Bugfix: Defining `GLFW_INCLUDE_VULKAN` when compiling the library did not + fail with the expected error message (#823) + - Bugfix: Inherited value of `CMAKE_MODULE_PATH` was clobbered (#822) + - [Win32] Bugfix: `glfwSetClipboardString` created an unnecessary intermediate + copy of the string + - [Win32] Bugfix: Examples failed to build on Visual C++ 2010 due to C99 in + `linmath.h` (#785) + - [Win32] Bugfix: The first shown window ignored the `GLFW_MAXIMIZED` hint + when the process was provided a `STARTUPINFO` (#780) + - [Cocoa] Bugfix: Event processing would segfault on some machines due to + a previous distributed notification listener not being fully + removed (#817,#826) + - [Cocoa] Bugfix: Some include statements were duplicated (#838) + - [X11] Bugfix: Window size limits were ignored if the minimum or maximum size + was set to `GLFW_DONT_CARE` (#805) + - [X11] Bugfix: Input focus was set before window was visible, causing + `BadMatch` on some non-reparenting WMs (#789,#798) + - [X11] Bugfix: `glfwGetWindowPos` and `glfwSetWindowPos` operated on the + window frame instead of the client area (#800) + - [WGL] Added reporting of errors from `WGL_ARB_create_context` extension + - [GLX] Bugfix: Dynamically loaded entry points were not verified + - [EGL] Added `lib` prefix matching between EGL and OpenGL ES library binaries + - [EGL] Bugfix: Dynamically loaded entry points were not verified + + +## 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 + - artblanc + - arturo + - Matt Arsenault + - Keith Bauer + - John Bartholomew + - Niklas Behrens + - Niklas Bergström + - Doug Binks + - blanco + - Martin Capitanio + - Chi-kwan Chan + - Lambert Clara + - Andrew Corrigan + - Noel Cower + - Jarrod Davis + - Olivier Delannoy + - Paul R. Deppe + - Michael Dickens + - Роман Донченко + - Mario Dorn + - Jonathan Dummer + - Ralph Eastwood + - Siavash Eliasi + - Michael Fogleman + - Gerald Franz + - GeO4d + - Marcus Geelnard + - Eloi Marín Gratacós + - Stefan Gustavson + - Sylvain Hellegouarch + - Matthew Henry + - heromyth + - Lucas Hinderberger + - Paul Holden + - Warren Hu + - IntellectualKitty + - Aaron Jacobs + - Erik S. V. Jansson + - Toni Jovanoski + - Arseny Kapoulkine + - Osman Keskin + - Cameron King + - Peter Knut + - Christoph Kubisch + - Eric Larson + - Robin Leffmann + - Glenn Lewis + - Shane Liesegang + - Eyal Lotem + - Дмитри Малышев + - Martins Mozeiko + - Tristam MacDonald + - Hans Mackowiak + - Zbigniew Mandziejewicz + - Kyle McDonald + - David Medlock + - Bryce Mehring + - Jonathan Mercier + - Marcel Metz + - Jonathan Miller + - Kenneth Miller + - Bruce Mitchener + - Jack Moffitt + - Jeff Molofee + - Jon Morton + - Pierre Moulon + - Julian Møller + - Kamil Nowakowski + - Ozzy + - Andri Pálsson + - Peoro + - Braden Pellett + - Arturo J. Pérez + - Orson Peters + - Emmanuel Gil Peyrot + - Cyril Pichard + - Pieroman + - Philip Rideout + - Jorge Rodriguez + - Ed Ropple + - Aleksey Rybalkin + - Riku Salminen + - Brandon Schaefer + - Sebastian Schuberth + - Matt Sealey + - SephiRok + - Steve Sexton + - Systemcluster + - Yoshiki Shibukawa + - Dmitri Shuralyov + - Daniel Skorupski + - Bradley Smith + - Patrick Snape + - Julian Squires + - Johannes Stein + - Justin Stoecker + - Elviss Strazdins + - Nathan Sweet + - TTK-Bandit + - Sergey Tikhomirov + - Arthur Tombs + - Ioannis Tsakpinis + - Samuli Tuomola + - urraka + - Jari Vetoniemi + - Ricardo Vieira + - Nicholas Vitovitch + - Simon Voordouw + - Torsten Walluhn + - Patrick Walton + - Xo Wang + - Jay Weisskopf + - Frank Wille + - yuriks + - 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/extern/glfw-3.2.1/cmake_uninstall.cmake.in b/extern/glfw-3.2.1/cmake_uninstall.cmake.in new file mode 100644 index 0000000..4ea57b1 --- /dev/null +++ b/extern/glfw-3.2.1/cmake_uninstall.cmake.in @@ -0,0 +1,29 @@ + +if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") + +foreach (file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if (EXISTS "$ENV{DESTDIR}${file}") + exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + if (NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif() + elseif (IS_SYMLINK "$ENV{DESTDIR}${file}") + EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + if (NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"") + endif() + else() + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif() +endforeach() + diff --git a/extern/glfw-3.2.1/deps/KHR/khrplatform.h b/extern/glfw-3.2.1/deps/KHR/khrplatform.h new file mode 100644 index 0000000..c9e6f17 --- /dev/null +++ b/extern/glfw-3.2.1/deps/KHR/khrplatform.h @@ -0,0 +1,282 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/extern/glfw-3.2.1/deps/getopt.c b/extern/glfw-3.2.1/deps/getopt.c new file mode 100644 index 0000000..9743046 --- /dev/null +++ b/extern/glfw-3.2.1/deps/getopt.c @@ -0,0 +1,230 @@ +/* Copyright (c) 2012, Kim Gräsman + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Kim Gräsman nor the names of contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 KIM GRÄSMAN 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. + */ + +#include "getopt.h" + +#include +#include + +const int no_argument = 0; +const int required_argument = 1; +const int optional_argument = 2; + +char* optarg; +int optopt; +/* The variable optind [...] shall be initialized to 1 by the system. */ +int optind = 1; +int opterr; + +static char* optcursor = NULL; + +/* Implemented based on [1] and [2] for optional arguments. + optopt is handled FreeBSD-style, per [3]. + Other GNU and FreeBSD extensions are purely accidental. + +[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html +[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE +*/ +int getopt(int argc, char* const argv[], const char* optstring) { + int optchar = -1; + const char* optdecl = NULL; + + optarg = NULL; + opterr = 0; + optopt = 0; + + /* Unspecified, but we need it to avoid overrunning the argv bounds. */ + if (optind >= argc) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] is a null pointer, getopt() + shall return -1 without changing optind. */ + if (argv[optind] == NULL) + goto no_more_optchars; + + /* If, when getopt() is called *argv[optind] is not the character '-', + getopt() shall return -1 without changing optind. */ + if (*argv[optind] != '-') + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "-", + getopt() shall return -1 without changing optind. */ + if (strcmp(argv[optind], "-") == 0) + goto no_more_optchars; + + /* If, when getopt() is called argv[optind] points to the string "--", + getopt() shall return -1 after incrementing optind. */ + if (strcmp(argv[optind], "--") == 0) { + ++optind; + goto no_more_optchars; + } + + if (optcursor == NULL || *optcursor == '\0') + optcursor = argv[optind] + 1; + + optchar = *optcursor; + + /* FreeBSD: The variable optopt saves the last known option character + returned by getopt(). */ + optopt = optchar; + + /* The getopt() function shall return the next option character (if one is + found) from argv that matches a character in optstring, if there is + one that matches. */ + optdecl = strchr(optstring, optchar); + if (optdecl) { + /* [I]f a character is followed by a colon, the option takes an + argument. */ + if (optdecl[1] == ':') { + optarg = ++optcursor; + if (*optarg == '\0') { + /* GNU extension: Two colons mean an option takes an + optional arg; if there is text in the current argv-element + (i.e., in the same word as the option name itself, for example, + "-oarg"), then it is returned in optarg, otherwise optarg is set + to zero. */ + if (optdecl[2] != ':') { + /* If the option was the last character in the string pointed to by + an element of argv, then optarg shall contain the next element + of argv, and optind shall be incremented by 2. If the resulting + value of optind is greater than argc, this indicates a missing + option-argument, and getopt() shall return an error indication. + + Otherwise, optarg shall point to the string following the + option character in that element of argv, and optind shall be + incremented by 1. + */ + if (++optind < argc) { + optarg = argv[optind]; + } else { + /* If it detects a missing option-argument, it shall return the + colon character ( ':' ) if the first character of optstring + was a colon, or a question-mark character ( '?' ) otherwise. + */ + optarg = NULL; + optchar = (optstring[0] == ':') ? ':' : '?'; + } + } else { + optarg = NULL; + } + } + + optcursor = NULL; + } + } else { + /* If getopt() encounters an option character that is not contained in + optstring, it shall return the question-mark ( '?' ) character. */ + optchar = '?'; + } + + if (optcursor == NULL || *++optcursor == '\0') + ++optind; + + return optchar; + +no_more_optchars: + optcursor = NULL; + return -1; +} + +/* Implementation based on [1]. + +[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html +*/ +int getopt_long(int argc, char* const argv[], const char* optstring, + const struct option* longopts, int* longindex) { + const struct option* o = longopts; + const struct option* match = NULL; + int num_matches = 0; + size_t argument_name_length = 0; + const char* current_argument = NULL; + int retval = -1; + + optarg = NULL; + optopt = 0; + + if (optind >= argc) + return -1; + + if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0) + return getopt(argc, argv, optstring); + + /* It's an option; starts with -- and is longer than two chars. */ + current_argument = argv[optind] + 2; + argument_name_length = strcspn(current_argument, "="); + for (; o->name; ++o) { + if (strncmp(o->name, current_argument, argument_name_length) == 0) { + match = o; + ++num_matches; + } + } + + if (num_matches == 1) { + /* If longindex is not NULL, it points to a variable which is set to the + index of the long option relative to longopts. */ + if (longindex) + *longindex = (int) (match - longopts); + + /* If flag is NULL, then getopt_long() shall return val. + Otherwise, getopt_long() returns 0, and flag shall point to a variable + which shall be set to val if the option is found, but left unchanged if + the option is not found. */ + if (match->flag) + *(match->flag) = match->val; + + retval = match->flag ? 0 : match->val; + + if (match->has_arg != no_argument) { + optarg = strchr(argv[optind], '='); + if (optarg != NULL) + ++optarg; + + if (match->has_arg == required_argument) { + /* Only scan the next argv for required arguments. Behavior is not + specified, but has been observed with Ubuntu and Mac OSX. */ + if (optarg == NULL && ++optind < argc) { + optarg = argv[optind]; + } + + if (optarg == NULL) + retval = ':'; + } + } else if (strchr(argv[optind], '=')) { + /* An argument was provided to a non-argument option. + I haven't seen this specified explicitly, but both GNU and BSD-based + implementations show this behavior. + */ + retval = '?'; + } + } else { + /* Unknown option or ambiguous match. */ + retval = '?'; + } + + ++optind; + return retval; +} diff --git a/extern/glfw-3.2.1/deps/getopt.h b/extern/glfw-3.2.1/deps/getopt.h new file mode 100644 index 0000000..e1eb540 --- /dev/null +++ b/extern/glfw-3.2.1/deps/getopt.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2012, Kim Gräsman + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Kim Gräsman nor the names of contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 KIM GRÄSMAN 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 INCLUDED_GETOPT_PORT_H +#define INCLUDED_GETOPT_PORT_H + +#if defined(__cplusplus) +extern "C" { +#endif + +extern const int no_argument; +extern const int required_argument; +extern const int optional_argument; + +extern char* optarg; +extern int optind, opterr, optopt; + +struct option { + const char* name; + int has_arg; + int* flag; + int val; +}; + +int getopt(int argc, char* const argv[], const char* optstring); + +int getopt_long(int argc, char* const argv[], + const char* optstring, const struct option* longopts, int* longindex); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_GETOPT_PORT_H diff --git a/extern/glfw-3.2.1/deps/glad.c b/extern/glfw-3.2.1/deps/glad.c new file mode 100644 index 0000000..7886e60 --- /dev/null +++ b/extern/glfw-3.2.1/deps/glad.c @@ -0,0 +1,1555 @@ +#include +#include +#include +#include + +struct gladGLversionStruct GLVersion; + +static int has_ext(const char *ext) { +#if defined(GL_VERSION_3_0) || defined(GL_ES_VERSION_3_0) + if(GLVersion.major < 3 || glGetStringi == NULL) { +#endif + const char *extensions; + const char *loc; + const char *terminator; + extensions = (const char*) glGetString(GL_EXTENSIONS); + if(extensions == NULL || ext == NULL) { + return 0; + } + + while(1) { + loc = strstr(extensions, ext); + if(loc == NULL) { + return 0; + } + + terminator = loc + strlen(ext); + if((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) { + return 1; + } + extensions = terminator; + } +#if defined(GL_VERSION_3_0) || defined(GL_ES_VERSION_3_0) + } else { + GLint num_exts, index; + + glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts); + for(index = 0; index < num_exts; index++) { + if(strcmp((const char*) glGetStringi(GL_EXTENSIONS, index), ext) == 0) { + return 1; + } + } + } +#endif + + return 0; +} +int GLAD_GL_VERSION_1_0; +int GLAD_GL_VERSION_1_1; +int GLAD_GL_VERSION_1_2; +int GLAD_GL_VERSION_1_3; +int GLAD_GL_VERSION_1_4; +int GLAD_GL_VERSION_1_5; +int GLAD_GL_VERSION_2_0; +int GLAD_GL_VERSION_2_1; +int GLAD_GL_VERSION_3_0; +int GLAD_GL_VERSION_3_1; +int GLAD_GL_VERSION_3_2; +PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; +PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; +PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; +PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; +PFNGLVERTEX2FVPROC glad_glVertex2fv; +PFNGLINDEXIPROC glad_glIndexi; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +PFNGLRECTDVPROC glad_glRectdv; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; +PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; +PFNGLINDEXDPROC glad_glIndexd; +PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +PFNGLINDEXFPROC glad_glIndexf; +PFNGLLINEWIDTHPROC glad_glLineWidth; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +PFNGLGETMAPFVPROC glad_glGetMapfv; +PFNGLINDEXSPROC glad_glIndexs; +PFNGLCOMPILESHADERPROC glad_glCompileShader; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; +PFNGLINDEXFVPROC glad_glIndexfv; +PFNGLFOGIVPROC glad_glFogiv; +PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; +PFNGLLIGHTMODELIVPROC glad_glLightModeliv; +PFNGLCOLOR4UIPROC glad_glColor4ui; +PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; +PFNGLFOGFVPROC glad_glFogfv; +PFNGLENABLEIPROC glad_glEnablei; +PFNGLVERTEX4IVPROC glad_glVertex4iv; +PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; +PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; +PFNGLCREATESHADERPROC glad_glCreateShader; +PFNGLISBUFFERPROC glad_glIsBuffer; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +PFNGLVERTEX4FVPROC glad_glVertex4fv; +PFNGLBINDTEXTUREPROC glad_glBindTexture; +PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +PFNGLPOINTSIZEPROC glad_glPointSize; +PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +PFNGLCOLOR4BVPROC glad_glColor4bv; +PFNGLRASTERPOS2FPROC glad_glRasterPos2f; +PFNGLRASTERPOS2DPROC glad_glRasterPos2d; +PFNGLLOADIDENTITYPROC glad_glLoadIdentity; +PFNGLRASTERPOS2IPROC glad_glRasterPos2i; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +PFNGLCOLOR3BPROC glad_glColor3b; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +PFNGLEDGEFLAGPROC glad_glEdgeFlag; +PFNGLVERTEX3DPROC glad_glVertex3d; +PFNGLVERTEX3FPROC glad_glVertex3f; +PFNGLVERTEX3IPROC glad_glVertex3i; +PFNGLCOLOR3IPROC glad_glColor3i; +PFNGLUNIFORM3FPROC glad_glUniform3f; +PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +PFNGLCOLOR3SPROC glad_glColor3s; +PFNGLVERTEX3SPROC glad_glVertex3s; +PFNGLCOLORMASKIPROC glad_glColorMaski; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +PFNGLVERTEX2IVPROC glad_glVertex2iv; +PFNGLCOLOR3SVPROC glad_glColor3sv; +PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +PFNGLNORMALPOINTERPROC glad_glNormalPointer; +PFNGLVERTEX4SVPROC glad_glVertex4sv; +PFNGLPASSTHROUGHPROC glad_glPassThrough; +PFNGLFOGIPROC glad_glFogi; +PFNGLBEGINPROC glad_glBegin; +PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; +PFNGLCOLOR3UBVPROC glad_glColor3ubv; +PFNGLVERTEXPOINTERPROC glad_glVertexPointer; +PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +PFNGLDRAWARRAYSPROC glad_glDrawArrays; +PFNGLUNIFORM1UIPROC glad_glUniform1ui; +PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; +PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; +PFNGLLIGHTFVPROC glad_glLightfv; +PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +PFNGLCLEARPROC glad_glClear; +PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; +PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; +PFNGLISENABLEDPROC glad_glIsEnabled; +PFNGLSTENCILOPPROC glad_glStencilOp; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +PFNGLTRANSLATEFPROC glad_glTranslatef; +PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +PFNGLTRANSLATEDPROC glad_glTranslated; +PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; +PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; +PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +PFNGLFOGCOORDFVPROC glad_glFogCoordfv; +PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +PFNGLINDEXSVPROC glad_glIndexsv; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +PFNGLVERTEX3IVPROC glad_glVertex3iv; +PFNGLBITMAPPROC glad_glBitmap; +PFNGLMATERIALIPROC glad_glMateriali; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +PFNGLGETQUERYIVPROC glad_glGetQueryiv; +PFNGLTEXCOORD4FPROC glad_glTexCoord4f; +PFNGLTEXCOORD4DPROC glad_glTexCoord4d; +PFNGLTEXCOORD4IPROC glad_glTexCoord4i; +PFNGLMATERIALFPROC glad_glMaterialf; +PFNGLTEXCOORD4SPROC glad_glTexCoord4s; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +PFNGLISSHADERPROC glad_glIsShader; +PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; +PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +PFNGLVERTEX3DVPROC glad_glVertex3dv; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +PFNGLENABLEPROC glad_glEnable; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +PFNGLCOLOR4FVPROC glad_glColor4fv; +PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; +PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; +PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; +PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; +PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; +PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; +PFNGLTEXGENFPROC glad_glTexGenf; +PFNGLGETPOINTERVPROC glad_glGetPointerv; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +PFNGLNORMAL3FVPROC glad_glNormal3fv; +PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; +PFNGLDEPTHRANGEPROC glad_glDepthRange; +PFNGLFRUSTUMPROC glad_glFrustum; +PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; +PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +PFNGLPUSHMATRIXPROC glad_glPushMatrix; +PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; +PFNGLORTHOPROC glad_glOrtho; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; +PFNGLCLEARINDEXPROC glad_glClearIndex; +PFNGLMAP1DPROC glad_glMap1d; +PFNGLMAP1FPROC glad_glMap1f; +PFNGLFLUSHPROC glad_glFlush; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +PFNGLINDEXIVPROC glad_glIndexiv; +PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +PFNGLPIXELZOOMPROC glad_glPixelZoom; +PFNGLFENCESYNCPROC glad_glFenceSync; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +PFNGLLIGHTIPROC glad_glLighti; +PFNGLLIGHTFPROC glad_glLightf; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +PFNGLCLAMPCOLORPROC glad_glClampColor; +PFNGLUNIFORM4IVPROC glad_glUniform4iv; +PFNGLCLEARSTENCILPROC glad_glClearStencil; +PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; +PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; +PFNGLGENTEXTURESPROC glad_glGenTextures; +PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; +PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +PFNGLINDEXPOINTERPROC glad_glIndexPointer; +PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +PFNGLISSYNCPROC glad_glIsSync; +PFNGLVERTEX2FPROC glad_glVertex2f; +PFNGLVERTEX2DPROC glad_glVertex2d; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +PFNGLUNIFORM2IPROC glad_glUniform2i; +PFNGLMAPGRID2DPROC glad_glMapGrid2d; +PFNGLMAPGRID2FPROC glad_glMapGrid2f; +PFNGLVERTEX2IPROC glad_glVertex2i; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +PFNGLVERTEX2SPROC glad_glVertex2s; +PFNGLNORMAL3BVPROC glad_glNormal3bv; +PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; +PFNGLVERTEX3SVPROC glad_glVertex3sv; +PFNGLGENQUERIESPROC glad_glGenQueries; +PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; +PFNGLTEXENVFPROC glad_glTexEnvf; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +PFNGLFOGCOORDDPROC glad_glFogCoordd; +PFNGLFOGCOORDFPROC glad_glFogCoordf; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +PFNGLTEXENVIPROC glad_glTexEnvi; +PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; +PFNGLISENABLEDIPROC glad_glIsEnabledi; +PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; +PFNGLUNIFORM2IVPROC glad_glUniform2iv; +PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +PFNGLMATRIXMODEPROC glad_glMatrixMode; +PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; +PFNGLGETMAPIVPROC glad_glGetMapiv; +PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +PFNGLGETSHADERIVPROC glad_glGetShaderiv; +PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; +PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; +PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; +PFNGLCALLLISTPROC glad_glCallList; +PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; +PFNGLGETDOUBLEVPROC glad_glGetDoublev; +PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; +PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +PFNGLLIGHTMODELFPROC glad_glLightModelf; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +PFNGLVERTEX2SVPROC glad_glVertex2sv; +PFNGLLIGHTMODELIPROC glad_glLightModeli; +PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; +PFNGLUNIFORM3FVPROC glad_glUniform3fv; +PFNGLPIXELSTOREIPROC glad_glPixelStorei; +PFNGLCALLLISTSPROC glad_glCallLists; +PFNGLMAPBUFFERPROC glad_glMapBuffer; +PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; +PFNGLTEXCOORD3IPROC glad_glTexCoord3i; +PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; +PFNGLRASTERPOS3IPROC glad_glRasterPos3i; +PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; +PFNGLRASTERPOS3DPROC glad_glRasterPos3d; +PFNGLRASTERPOS3FPROC glad_glRasterPos3f; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +PFNGLTEXCOORD3FPROC glad_glTexCoord3f; +PFNGLDELETESYNCPROC glad_glDeleteSync; +PFNGLTEXCOORD3DPROC glad_glTexCoord3d; +PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +PFNGLTEXCOORD3SPROC glad_glTexCoord3s; +PFNGLUNIFORM3IVPROC glad_glUniform3iv; +PFNGLRASTERPOS3SPROC glad_glRasterPos3s; +PFNGLPOLYGONMODEPROC glad_glPolygonMode; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; +PFNGLISLISTPROC glad_glIsList; +PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; +PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; +PFNGLCOLOR4SPROC glad_glColor4s; +PFNGLUSEPROGRAMPROC glad_glUseProgram; +PFNGLLINESTIPPLEPROC glad_glLineStipple; +PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +PFNGLCOLOR4BPROC glad_glColor4b; +PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; +PFNGLCOLOR4FPROC glad_glColor4f; +PFNGLCOLOR4DPROC glad_glColor4d; +PFNGLCOLOR4IPROC glad_glColor4i; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; +PFNGLVERTEX2DVPROC glad_glVertex2dv; +PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +PFNGLFINISHPROC glad_glFinish; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +PFNGLDELETESHADERPROC glad_glDeleteShader; +PFNGLDRAWELEMENTSPROC glad_glDrawElements; +PFNGLRASTERPOS2SPROC glad_glRasterPos2s; +PFNGLGETMAPDVPROC glad_glGetMapdv; +PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +PFNGLMATERIALFVPROC glad_glMaterialfv; +PFNGLVIEWPORTPROC glad_glViewport; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +PFNGLINDEXDVPROC glad_glIndexdv; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; +PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +PFNGLCLEARDEPTHPROC glad_glClearDepth; +PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +PFNGLTEXBUFFERPROC glad_glTexBuffer; +PFNGLPOPNAMEPROC glad_glPopName; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +PFNGLPIXELSTOREFPROC glad_glPixelStoref; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; +PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; +PFNGLRECTIPROC glad_glRecti; +PFNGLCOLOR4UBPROC glad_glColor4ub; +PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; +PFNGLRECTFPROC glad_glRectf; +PFNGLRECTDPROC glad_glRectd; +PFNGLNORMAL3SVPROC glad_glNormal3sv; +PFNGLNEWLISTPROC glad_glNewList; +PFNGLCOLOR4USPROC glad_glColor4us; +PFNGLLINKPROGRAMPROC glad_glLinkProgram; +PFNGLHINTPROC glad_glHint; +PFNGLRECTSPROC glad_glRects; +PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; +PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; +PFNGLGETSTRINGPROC glad_glGetString; +PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; +PFNGLDETACHSHADERPROC glad_glDetachShader; +PFNGLSCALEFPROC glad_glScalef; +PFNGLENDQUERYPROC glad_glEndQuery; +PFNGLSCALEDPROC glad_glScaled; +PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; +PFNGLCOPYPIXELSPROC glad_glCopyPixels; +PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +PFNGLPOPATTRIBPROC glad_glPopAttrib; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +PFNGLINITNAMESPROC glad_glInitNames; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +PFNGLCOLOR3DVPROC glad_glColor3dv; +PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +PFNGLWAITSYNCPROC glad_glWaitSync; +PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +PFNGLCOLORMATERIALPROC glad_glColorMaterial; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +PFNGLUNIFORM1FPROC glad_glUniform1f; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +PFNGLRENDERMODEPROC glad_glRenderMode; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; +PFNGLUNIFORM1IPROC glad_glUniform1i; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +PFNGLUNIFORM3IPROC glad_glUniform3i; +PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +PFNGLDISABLEPROC glad_glDisable; +PFNGLLOGICOPPROC glad_glLogicOp; +PFNGLEVALPOINT2PROC glad_glEvalPoint2; +PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; +PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; +PFNGLUNIFORM4UIPROC glad_glUniform4ui; +PFNGLCOLOR3FPROC glad_glColor3f; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; +PFNGLRECTFVPROC glad_glRectfv; +PFNGLCULLFACEPROC glad_glCullFace; +PFNGLGETLIGHTFVPROC glad_glGetLightfv; +PFNGLCOLOR3DPROC glad_glColor3d; +PFNGLTEXGENDPROC glad_glTexGend; +PFNGLTEXGENIPROC glad_glTexGeni; +PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; +PFNGLGETSTRINGIPROC glad_glGetStringi; +PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; +PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; +PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; +PFNGLATTACHSHADERPROC glad_glAttachShader; +PFNGLFOGCOORDDVPROC glad_glFogCoorddv; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; +PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; +PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +PFNGLTEXGENIVPROC glad_glTexGeniv; +PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; +PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; +PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; +PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; +PFNGLTEXENVFVPROC glad_glTexEnvfv; +PFNGLREADBUFFERPROC glad_glReadBuffer; +PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; +PFNGLLIGHTMODELFVPROC glad_glLightModelfv; +PFNGLDELETELISTSPROC glad_glDeleteLists; +PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; +PFNGLVERTEX4DVPROC glad_glVertex4dv; +PFNGLTEXCOORD2DPROC glad_glTexCoord2d; +PFNGLPOPMATRIXPROC glad_glPopMatrix; +PFNGLTEXCOORD2FPROC glad_glTexCoord2f; +PFNGLCOLOR4IVPROC glad_glColor4iv; +PFNGLINDEXUBVPROC glad_glIndexubv; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +PFNGLTEXCOORD2IPROC glad_glTexCoord2i; +PFNGLRASTERPOS4DPROC glad_glRasterPos4d; +PFNGLRASTERPOS4FPROC glad_glRasterPos4f; +PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +PFNGLTEXCOORD2SPROC glad_glTexCoord2s; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +PFNGLVERTEX3FVPROC glad_glVertex3fv; +PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; +PFNGLMATERIALIVPROC glad_glMaterialiv; +PFNGLISPROGRAMPROC glad_glIsProgram; +PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +PFNGLVERTEX4SPROC glad_glVertex4s; +PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +PFNGLNORMAL3DVPROC glad_glNormal3dv; +PFNGLUNIFORM4IPROC glad_glUniform4i; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +PFNGLROTATEDPROC glad_glRotated; +PFNGLROTATEFPROC glad_glRotatef; +PFNGLVERTEX4IPROC glad_glVertex4i; +PFNGLREADPIXELSPROC glad_glReadPixels; +PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +PFNGLLOADNAMEPROC glad_glLoadName; +PFNGLUNIFORM4FPROC glad_glUniform4f; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +PFNGLSHADEMODELPROC glad_glShadeModel; +PFNGLMAPGRID1DPROC glad_glMapGrid1d; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +PFNGLMAPGRID1FPROC glad_glMapGrid1f; +PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; +PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; +PFNGLALPHAFUNCPROC glad_glAlphaFunc; +PFNGLUNIFORM1IVPROC glad_glUniform1iv; +PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; +PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +PFNGLSTENCILFUNCPROC glad_glStencilFunc; +PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +PFNGLCOLOR4UIVPROC glad_glColor4uiv; +PFNGLRECTIVPROC glad_glRectiv; +PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; +PFNGLEVALMESH2PROC glad_glEvalMesh2; +PFNGLEVALMESH1PROC glad_glEvalMesh1; +PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; +PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; +PFNGLCOLOR4UBVPROC glad_glColor4ubv; +PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; +PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; +PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +PFNGLTEXENVIVPROC glad_glTexEnviv; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +PFNGLGENBUFFERSPROC glad_glGenBuffers; +PFNGLSELECTBUFFERPROC glad_glSelectBuffer; +PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +PFNGLPUSHATTRIBPROC glad_glPushAttrib; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +PFNGLBLENDFUNCPROC glad_glBlendFunc; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +PFNGLLIGHTIVPROC glad_glLightiv; +PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +PFNGLTEXGENFVPROC glad_glTexGenfv; +PFNGLENDPROC glad_glEnd; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +PFNGLSCISSORPROC glad_glScissor; +PFNGLCLIPPLANEPROC glad_glClipPlane; +PFNGLPUSHNAMEPROC glad_glPushName; +PFNGLTEXGENDVPROC glad_glTexGendv; +PFNGLINDEXUBPROC glad_glIndexub; +PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; +PFNGLRASTERPOS4IPROC glad_glRasterPos4i; +PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; +PFNGLCLEARCOLORPROC glad_glClearColor; +PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +PFNGLNORMAL3SPROC glad_glNormal3s; +PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +PFNGLBLENDCOLORPROC glad_glBlendColor; +PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; +PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +PFNGLUNIFORM3UIPROC glad_glUniform3ui; +PFNGLCOLOR4DVPROC glad_glColor4dv; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +PFNGLUNIFORM2FVPROC glad_glUniform2fv; +PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; +PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; +PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +PFNGLNORMAL3IVPROC glad_glNormal3iv; +PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; +PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; +PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; +PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; +PFNGLCOLOR3USPROC glad_glColor3us; +PFNGLCOLOR3UIVPROC glad_glColor3uiv; +PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +PFNGLGETLIGHTIVPROC glad_glGetLightiv; +PFNGLDEPTHFUNCPROC glad_glDepthFunc; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +PFNGLLISTBASEPROC glad_glListBase; +PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; +PFNGLCOLOR3UBPROC glad_glColor3ub; +PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; +PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +PFNGLCOLOR3UIPROC glad_glColor3ui; +PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; +PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; +PFNGLCOLORMASKPROC glad_glColorMask; +PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +PFNGLRASTERPOS4SPROC glad_glRasterPos4s; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; +PFNGLCOLOR4SVPROC glad_glColor4sv; +PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +PFNGLFOGFPROC glad_glFogf; +PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +PFNGLCOLOR3IVPROC glad_glColor3iv; +PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +PFNGLTEXCOORD1IPROC glad_glTexCoord1i; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +PFNGLTEXCOORD1DPROC glad_glTexCoord1d; +PFNGLTEXCOORD1FPROC glad_glTexCoord1f; +PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; +PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +PFNGLTEXCOORD1SPROC glad_glTexCoord1s; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +PFNGLGENLISTSPROC glad_glGenLists; +PFNGLCOLOR3BVPROC glad_glColor3bv; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +PFNGLGETTEXGENDVPROC glad_glGetTexGendv; +PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +PFNGLENDLISTPROC glad_glEndList; +PFNGLUNIFORM2UIPROC glad_glUniform2ui; +PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +PFNGLCOLOR3USVPROC glad_glColor3usv; +PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; +PFNGLDISABLEIPROC glad_glDisablei; +PFNGLINDEXMASKPROC glad_glIndexMask; +PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; +PFNGLSHADERSOURCEPROC glad_glShaderSource; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +PFNGLCLEARACCUMPROC glad_glClearAccum; +PFNGLGETSYNCIVPROC glad_glGetSynciv; +PFNGLUNIFORM2FPROC glad_glUniform2f; +PFNGLBEGINQUERYPROC glad_glBeginQuery; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +PFNGLBINDBUFFERPROC glad_glBindBuffer; +PFNGLMAP2DPROC glad_glMap2d; +PFNGLMAP2FPROC glad_glMap2f; +PFNGLVERTEX4DPROC glad_glVertex4d; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; +PFNGLBUFFERDATAPROC glad_glBufferData; +PFNGLEVALPOINT1PROC glad_glEvalPoint1; +PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; +PFNGLGETERRORPROC glad_glGetError; +PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +PFNGLGETFLOATVPROC glad_glGetFloatv; +PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; +PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; +PFNGLPIXELMAPFVPROC glad_glPixelMapfv; +PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; +PFNGLGETINTEGERVPROC glad_glGetIntegerv; +PFNGLACCUMPROC glad_glAccum; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; +PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; +PFNGLISQUERYPROC glad_glIsQuery; +PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; +PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +PFNGLSTENCILMASKPROC glad_glStencilMask; +PFNGLDRAWPIXELSPROC glad_glDrawPixels; +PFNGLMULTMATRIXDPROC glad_glMultMatrixd; +PFNGLMULTMATRIXFPROC glad_glMultMatrixf; +PFNGLISTEXTUREPROC glad_glIsTexture; +PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; +PFNGLUNIFORM1FVPROC glad_glUniform1fv; +PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; +PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +PFNGLVERTEX4FPROC glad_glVertex4f; +PFNGLRECTSVPROC glad_glRectsv; +PFNGLCOLOR4USVPROC glad_glColor4usv; +PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; +PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; +PFNGLNORMAL3IPROC glad_glNormal3i; +PFNGLNORMAL3FPROC glad_glNormal3f; +PFNGLNORMAL3DPROC glad_glNormal3d; +PFNGLNORMAL3BPROC glad_glNormal3b; +PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; +PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; +PFNGLARRAYELEMENTPROC glad_glArrayElement; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +PFNGLDEPTHMASKPROC glad_glDepthMask; +PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +PFNGLCOLOR3FVPROC glad_glColor3fv; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +PFNGLUNIFORM4FVPROC glad_glUniform4fv; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +PFNGLCOLORPOINTERPROC glad_glColorPointer; +PFNGLFRONTFACEPROC glad_glFrontFace; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +int GLAD_GL_ARB_robustness; +int GLAD_GL_ARB_multisample; +int GLAD_GL_EXT_separate_specular_color; +PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; +PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; +PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; +PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; +PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; +PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; +PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; +PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; +PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; +PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; +PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; +PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; +PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; +PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; +PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; +PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; +PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; +PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; +PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; +PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; +PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; +static void load_GL_VERSION_1_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_0) return; + glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); + glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); + glad_glHint = (PFNGLHINTPROC)load("glHint"); + glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); + glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize"); + glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode"); + glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); + glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); + glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); + glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); + glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); + glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D"); + glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); + glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer"); + glad_glClear = (PFNGLCLEARPROC)load("glClear"); + glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); + glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); + glad_glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth"); + glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); + glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); + glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); + glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); + glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); + glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); + glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); + glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); + glad_glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp"); + glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); + glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); + glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); + glad_glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref"); + glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); + glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); + glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); + glad_glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev"); + glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); + glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); + glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); + glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); + glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage"); + glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); + glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); + glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); + glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); + glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); + glad_glNewList = (PFNGLNEWLISTPROC)load("glNewList"); + glad_glEndList = (PFNGLENDLISTPROC)load("glEndList"); + glad_glCallList = (PFNGLCALLLISTPROC)load("glCallList"); + glad_glCallLists = (PFNGLCALLLISTSPROC)load("glCallLists"); + glad_glDeleteLists = (PFNGLDELETELISTSPROC)load("glDeleteLists"); + glad_glGenLists = (PFNGLGENLISTSPROC)load("glGenLists"); + glad_glListBase = (PFNGLLISTBASEPROC)load("glListBase"); + glad_glBegin = (PFNGLBEGINPROC)load("glBegin"); + glad_glBitmap = (PFNGLBITMAPPROC)load("glBitmap"); + glad_glColor3b = (PFNGLCOLOR3BPROC)load("glColor3b"); + glad_glColor3bv = (PFNGLCOLOR3BVPROC)load("glColor3bv"); + glad_glColor3d = (PFNGLCOLOR3DPROC)load("glColor3d"); + glad_glColor3dv = (PFNGLCOLOR3DVPROC)load("glColor3dv"); + glad_glColor3f = (PFNGLCOLOR3FPROC)load("glColor3f"); + glad_glColor3fv = (PFNGLCOLOR3FVPROC)load("glColor3fv"); + glad_glColor3i = (PFNGLCOLOR3IPROC)load("glColor3i"); + glad_glColor3iv = (PFNGLCOLOR3IVPROC)load("glColor3iv"); + glad_glColor3s = (PFNGLCOLOR3SPROC)load("glColor3s"); + glad_glColor3sv = (PFNGLCOLOR3SVPROC)load("glColor3sv"); + glad_glColor3ub = (PFNGLCOLOR3UBPROC)load("glColor3ub"); + glad_glColor3ubv = (PFNGLCOLOR3UBVPROC)load("glColor3ubv"); + glad_glColor3ui = (PFNGLCOLOR3UIPROC)load("glColor3ui"); + glad_glColor3uiv = (PFNGLCOLOR3UIVPROC)load("glColor3uiv"); + glad_glColor3us = (PFNGLCOLOR3USPROC)load("glColor3us"); + glad_glColor3usv = (PFNGLCOLOR3USVPROC)load("glColor3usv"); + glad_glColor4b = (PFNGLCOLOR4BPROC)load("glColor4b"); + glad_glColor4bv = (PFNGLCOLOR4BVPROC)load("glColor4bv"); + glad_glColor4d = (PFNGLCOLOR4DPROC)load("glColor4d"); + glad_glColor4dv = (PFNGLCOLOR4DVPROC)load("glColor4dv"); + glad_glColor4f = (PFNGLCOLOR4FPROC)load("glColor4f"); + glad_glColor4fv = (PFNGLCOLOR4FVPROC)load("glColor4fv"); + glad_glColor4i = (PFNGLCOLOR4IPROC)load("glColor4i"); + glad_glColor4iv = (PFNGLCOLOR4IVPROC)load("glColor4iv"); + glad_glColor4s = (PFNGLCOLOR4SPROC)load("glColor4s"); + glad_glColor4sv = (PFNGLCOLOR4SVPROC)load("glColor4sv"); + glad_glColor4ub = (PFNGLCOLOR4UBPROC)load("glColor4ub"); + glad_glColor4ubv = (PFNGLCOLOR4UBVPROC)load("glColor4ubv"); + glad_glColor4ui = (PFNGLCOLOR4UIPROC)load("glColor4ui"); + glad_glColor4uiv = (PFNGLCOLOR4UIVPROC)load("glColor4uiv"); + glad_glColor4us = (PFNGLCOLOR4USPROC)load("glColor4us"); + glad_glColor4usv = (PFNGLCOLOR4USVPROC)load("glColor4usv"); + glad_glEdgeFlag = (PFNGLEDGEFLAGPROC)load("glEdgeFlag"); + glad_glEdgeFlagv = (PFNGLEDGEFLAGVPROC)load("glEdgeFlagv"); + glad_glEnd = (PFNGLENDPROC)load("glEnd"); + glad_glIndexd = (PFNGLINDEXDPROC)load("glIndexd"); + glad_glIndexdv = (PFNGLINDEXDVPROC)load("glIndexdv"); + glad_glIndexf = (PFNGLINDEXFPROC)load("glIndexf"); + glad_glIndexfv = (PFNGLINDEXFVPROC)load("glIndexfv"); + glad_glIndexi = (PFNGLINDEXIPROC)load("glIndexi"); + glad_glIndexiv = (PFNGLINDEXIVPROC)load("glIndexiv"); + glad_glIndexs = (PFNGLINDEXSPROC)load("glIndexs"); + glad_glIndexsv = (PFNGLINDEXSVPROC)load("glIndexsv"); + glad_glNormal3b = (PFNGLNORMAL3BPROC)load("glNormal3b"); + glad_glNormal3bv = (PFNGLNORMAL3BVPROC)load("glNormal3bv"); + glad_glNormal3d = (PFNGLNORMAL3DPROC)load("glNormal3d"); + glad_glNormal3dv = (PFNGLNORMAL3DVPROC)load("glNormal3dv"); + glad_glNormal3f = (PFNGLNORMAL3FPROC)load("glNormal3f"); + glad_glNormal3fv = (PFNGLNORMAL3FVPROC)load("glNormal3fv"); + glad_glNormal3i = (PFNGLNORMAL3IPROC)load("glNormal3i"); + glad_glNormal3iv = (PFNGLNORMAL3IVPROC)load("glNormal3iv"); + glad_glNormal3s = (PFNGLNORMAL3SPROC)load("glNormal3s"); + glad_glNormal3sv = (PFNGLNORMAL3SVPROC)load("glNormal3sv"); + glad_glRasterPos2d = (PFNGLRASTERPOS2DPROC)load("glRasterPos2d"); + glad_glRasterPos2dv = (PFNGLRASTERPOS2DVPROC)load("glRasterPos2dv"); + glad_glRasterPos2f = (PFNGLRASTERPOS2FPROC)load("glRasterPos2f"); + glad_glRasterPos2fv = (PFNGLRASTERPOS2FVPROC)load("glRasterPos2fv"); + glad_glRasterPos2i = (PFNGLRASTERPOS2IPROC)load("glRasterPos2i"); + glad_glRasterPos2iv = (PFNGLRASTERPOS2IVPROC)load("glRasterPos2iv"); + glad_glRasterPos2s = (PFNGLRASTERPOS2SPROC)load("glRasterPos2s"); + glad_glRasterPos2sv = (PFNGLRASTERPOS2SVPROC)load("glRasterPos2sv"); + glad_glRasterPos3d = (PFNGLRASTERPOS3DPROC)load("glRasterPos3d"); + glad_glRasterPos3dv = (PFNGLRASTERPOS3DVPROC)load("glRasterPos3dv"); + glad_glRasterPos3f = (PFNGLRASTERPOS3FPROC)load("glRasterPos3f"); + glad_glRasterPos3fv = (PFNGLRASTERPOS3FVPROC)load("glRasterPos3fv"); + glad_glRasterPos3i = (PFNGLRASTERPOS3IPROC)load("glRasterPos3i"); + glad_glRasterPos3iv = (PFNGLRASTERPOS3IVPROC)load("glRasterPos3iv"); + glad_glRasterPos3s = (PFNGLRASTERPOS3SPROC)load("glRasterPos3s"); + glad_glRasterPos3sv = (PFNGLRASTERPOS3SVPROC)load("glRasterPos3sv"); + glad_glRasterPos4d = (PFNGLRASTERPOS4DPROC)load("glRasterPos4d"); + glad_glRasterPos4dv = (PFNGLRASTERPOS4DVPROC)load("glRasterPos4dv"); + glad_glRasterPos4f = (PFNGLRASTERPOS4FPROC)load("glRasterPos4f"); + glad_glRasterPos4fv = (PFNGLRASTERPOS4FVPROC)load("glRasterPos4fv"); + glad_glRasterPos4i = (PFNGLRASTERPOS4IPROC)load("glRasterPos4i"); + glad_glRasterPos4iv = (PFNGLRASTERPOS4IVPROC)load("glRasterPos4iv"); + glad_glRasterPos4s = (PFNGLRASTERPOS4SPROC)load("glRasterPos4s"); + glad_glRasterPos4sv = (PFNGLRASTERPOS4SVPROC)load("glRasterPos4sv"); + glad_glRectd = (PFNGLRECTDPROC)load("glRectd"); + glad_glRectdv = (PFNGLRECTDVPROC)load("glRectdv"); + glad_glRectf = (PFNGLRECTFPROC)load("glRectf"); + glad_glRectfv = (PFNGLRECTFVPROC)load("glRectfv"); + glad_glRecti = (PFNGLRECTIPROC)load("glRecti"); + glad_glRectiv = (PFNGLRECTIVPROC)load("glRectiv"); + glad_glRects = (PFNGLRECTSPROC)load("glRects"); + glad_glRectsv = (PFNGLRECTSVPROC)load("glRectsv"); + glad_glTexCoord1d = (PFNGLTEXCOORD1DPROC)load("glTexCoord1d"); + glad_glTexCoord1dv = (PFNGLTEXCOORD1DVPROC)load("glTexCoord1dv"); + glad_glTexCoord1f = (PFNGLTEXCOORD1FPROC)load("glTexCoord1f"); + glad_glTexCoord1fv = (PFNGLTEXCOORD1FVPROC)load("glTexCoord1fv"); + glad_glTexCoord1i = (PFNGLTEXCOORD1IPROC)load("glTexCoord1i"); + glad_glTexCoord1iv = (PFNGLTEXCOORD1IVPROC)load("glTexCoord1iv"); + glad_glTexCoord1s = (PFNGLTEXCOORD1SPROC)load("glTexCoord1s"); + glad_glTexCoord1sv = (PFNGLTEXCOORD1SVPROC)load("glTexCoord1sv"); + glad_glTexCoord2d = (PFNGLTEXCOORD2DPROC)load("glTexCoord2d"); + glad_glTexCoord2dv = (PFNGLTEXCOORD2DVPROC)load("glTexCoord2dv"); + glad_glTexCoord2f = (PFNGLTEXCOORD2FPROC)load("glTexCoord2f"); + glad_glTexCoord2fv = (PFNGLTEXCOORD2FVPROC)load("glTexCoord2fv"); + glad_glTexCoord2i = (PFNGLTEXCOORD2IPROC)load("glTexCoord2i"); + glad_glTexCoord2iv = (PFNGLTEXCOORD2IVPROC)load("glTexCoord2iv"); + glad_glTexCoord2s = (PFNGLTEXCOORD2SPROC)load("glTexCoord2s"); + glad_glTexCoord2sv = (PFNGLTEXCOORD2SVPROC)load("glTexCoord2sv"); + glad_glTexCoord3d = (PFNGLTEXCOORD3DPROC)load("glTexCoord3d"); + glad_glTexCoord3dv = (PFNGLTEXCOORD3DVPROC)load("glTexCoord3dv"); + glad_glTexCoord3f = (PFNGLTEXCOORD3FPROC)load("glTexCoord3f"); + glad_glTexCoord3fv = (PFNGLTEXCOORD3FVPROC)load("glTexCoord3fv"); + glad_glTexCoord3i = (PFNGLTEXCOORD3IPROC)load("glTexCoord3i"); + glad_glTexCoord3iv = (PFNGLTEXCOORD3IVPROC)load("glTexCoord3iv"); + glad_glTexCoord3s = (PFNGLTEXCOORD3SPROC)load("glTexCoord3s"); + glad_glTexCoord3sv = (PFNGLTEXCOORD3SVPROC)load("glTexCoord3sv"); + glad_glTexCoord4d = (PFNGLTEXCOORD4DPROC)load("glTexCoord4d"); + glad_glTexCoord4dv = (PFNGLTEXCOORD4DVPROC)load("glTexCoord4dv"); + glad_glTexCoord4f = (PFNGLTEXCOORD4FPROC)load("glTexCoord4f"); + glad_glTexCoord4fv = (PFNGLTEXCOORD4FVPROC)load("glTexCoord4fv"); + glad_glTexCoord4i = (PFNGLTEXCOORD4IPROC)load("glTexCoord4i"); + glad_glTexCoord4iv = (PFNGLTEXCOORD4IVPROC)load("glTexCoord4iv"); + glad_glTexCoord4s = (PFNGLTEXCOORD4SPROC)load("glTexCoord4s"); + glad_glTexCoord4sv = (PFNGLTEXCOORD4SVPROC)load("glTexCoord4sv"); + glad_glVertex2d = (PFNGLVERTEX2DPROC)load("glVertex2d"); + glad_glVertex2dv = (PFNGLVERTEX2DVPROC)load("glVertex2dv"); + glad_glVertex2f = (PFNGLVERTEX2FPROC)load("glVertex2f"); + glad_glVertex2fv = (PFNGLVERTEX2FVPROC)load("glVertex2fv"); + glad_glVertex2i = (PFNGLVERTEX2IPROC)load("glVertex2i"); + glad_glVertex2iv = (PFNGLVERTEX2IVPROC)load("glVertex2iv"); + glad_glVertex2s = (PFNGLVERTEX2SPROC)load("glVertex2s"); + glad_glVertex2sv = (PFNGLVERTEX2SVPROC)load("glVertex2sv"); + glad_glVertex3d = (PFNGLVERTEX3DPROC)load("glVertex3d"); + glad_glVertex3dv = (PFNGLVERTEX3DVPROC)load("glVertex3dv"); + glad_glVertex3f = (PFNGLVERTEX3FPROC)load("glVertex3f"); + glad_glVertex3fv = (PFNGLVERTEX3FVPROC)load("glVertex3fv"); + glad_glVertex3i = (PFNGLVERTEX3IPROC)load("glVertex3i"); + glad_glVertex3iv = (PFNGLVERTEX3IVPROC)load("glVertex3iv"); + glad_glVertex3s = (PFNGLVERTEX3SPROC)load("glVertex3s"); + glad_glVertex3sv = (PFNGLVERTEX3SVPROC)load("glVertex3sv"); + glad_glVertex4d = (PFNGLVERTEX4DPROC)load("glVertex4d"); + glad_glVertex4dv = (PFNGLVERTEX4DVPROC)load("glVertex4dv"); + glad_glVertex4f = (PFNGLVERTEX4FPROC)load("glVertex4f"); + glad_glVertex4fv = (PFNGLVERTEX4FVPROC)load("glVertex4fv"); + glad_glVertex4i = (PFNGLVERTEX4IPROC)load("glVertex4i"); + glad_glVertex4iv = (PFNGLVERTEX4IVPROC)load("glVertex4iv"); + glad_glVertex4s = (PFNGLVERTEX4SPROC)load("glVertex4s"); + glad_glVertex4sv = (PFNGLVERTEX4SVPROC)load("glVertex4sv"); + glad_glClipPlane = (PFNGLCLIPPLANEPROC)load("glClipPlane"); + glad_glColorMaterial = (PFNGLCOLORMATERIALPROC)load("glColorMaterial"); + glad_glFogf = (PFNGLFOGFPROC)load("glFogf"); + glad_glFogfv = (PFNGLFOGFVPROC)load("glFogfv"); + glad_glFogi = (PFNGLFOGIPROC)load("glFogi"); + glad_glFogiv = (PFNGLFOGIVPROC)load("glFogiv"); + glad_glLightf = (PFNGLLIGHTFPROC)load("glLightf"); + glad_glLightfv = (PFNGLLIGHTFVPROC)load("glLightfv"); + glad_glLighti = (PFNGLLIGHTIPROC)load("glLighti"); + glad_glLightiv = (PFNGLLIGHTIVPROC)load("glLightiv"); + glad_glLightModelf = (PFNGLLIGHTMODELFPROC)load("glLightModelf"); + glad_glLightModelfv = (PFNGLLIGHTMODELFVPROC)load("glLightModelfv"); + glad_glLightModeli = (PFNGLLIGHTMODELIPROC)load("glLightModeli"); + glad_glLightModeliv = (PFNGLLIGHTMODELIVPROC)load("glLightModeliv"); + glad_glLineStipple = (PFNGLLINESTIPPLEPROC)load("glLineStipple"); + glad_glMaterialf = (PFNGLMATERIALFPROC)load("glMaterialf"); + glad_glMaterialfv = (PFNGLMATERIALFVPROC)load("glMaterialfv"); + glad_glMateriali = (PFNGLMATERIALIPROC)load("glMateriali"); + glad_glMaterialiv = (PFNGLMATERIALIVPROC)load("glMaterialiv"); + glad_glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC)load("glPolygonStipple"); + glad_glShadeModel = (PFNGLSHADEMODELPROC)load("glShadeModel"); + glad_glTexEnvf = (PFNGLTEXENVFPROC)load("glTexEnvf"); + glad_glTexEnvfv = (PFNGLTEXENVFVPROC)load("glTexEnvfv"); + glad_glTexEnvi = (PFNGLTEXENVIPROC)load("glTexEnvi"); + glad_glTexEnviv = (PFNGLTEXENVIVPROC)load("glTexEnviv"); + glad_glTexGend = (PFNGLTEXGENDPROC)load("glTexGend"); + glad_glTexGendv = (PFNGLTEXGENDVPROC)load("glTexGendv"); + glad_glTexGenf = (PFNGLTEXGENFPROC)load("glTexGenf"); + glad_glTexGenfv = (PFNGLTEXGENFVPROC)load("glTexGenfv"); + glad_glTexGeni = (PFNGLTEXGENIPROC)load("glTexGeni"); + glad_glTexGeniv = (PFNGLTEXGENIVPROC)load("glTexGeniv"); + glad_glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC)load("glFeedbackBuffer"); + glad_glSelectBuffer = (PFNGLSELECTBUFFERPROC)load("glSelectBuffer"); + glad_glRenderMode = (PFNGLRENDERMODEPROC)load("glRenderMode"); + glad_glInitNames = (PFNGLINITNAMESPROC)load("glInitNames"); + glad_glLoadName = (PFNGLLOADNAMEPROC)load("glLoadName"); + glad_glPassThrough = (PFNGLPASSTHROUGHPROC)load("glPassThrough"); + glad_glPopName = (PFNGLPOPNAMEPROC)load("glPopName"); + glad_glPushName = (PFNGLPUSHNAMEPROC)load("glPushName"); + glad_glClearAccum = (PFNGLCLEARACCUMPROC)load("glClearAccum"); + glad_glClearIndex = (PFNGLCLEARINDEXPROC)load("glClearIndex"); + glad_glIndexMask = (PFNGLINDEXMASKPROC)load("glIndexMask"); + glad_glAccum = (PFNGLACCUMPROC)load("glAccum"); + glad_glPopAttrib = (PFNGLPOPATTRIBPROC)load("glPopAttrib"); + glad_glPushAttrib = (PFNGLPUSHATTRIBPROC)load("glPushAttrib"); + glad_glMap1d = (PFNGLMAP1DPROC)load("glMap1d"); + glad_glMap1f = (PFNGLMAP1FPROC)load("glMap1f"); + glad_glMap2d = (PFNGLMAP2DPROC)load("glMap2d"); + glad_glMap2f = (PFNGLMAP2FPROC)load("glMap2f"); + glad_glMapGrid1d = (PFNGLMAPGRID1DPROC)load("glMapGrid1d"); + glad_glMapGrid1f = (PFNGLMAPGRID1FPROC)load("glMapGrid1f"); + glad_glMapGrid2d = (PFNGLMAPGRID2DPROC)load("glMapGrid2d"); + glad_glMapGrid2f = (PFNGLMAPGRID2FPROC)load("glMapGrid2f"); + glad_glEvalCoord1d = (PFNGLEVALCOORD1DPROC)load("glEvalCoord1d"); + glad_glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC)load("glEvalCoord1dv"); + glad_glEvalCoord1f = (PFNGLEVALCOORD1FPROC)load("glEvalCoord1f"); + glad_glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC)load("glEvalCoord1fv"); + glad_glEvalCoord2d = (PFNGLEVALCOORD2DPROC)load("glEvalCoord2d"); + glad_glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC)load("glEvalCoord2dv"); + glad_glEvalCoord2f = (PFNGLEVALCOORD2FPROC)load("glEvalCoord2f"); + glad_glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC)load("glEvalCoord2fv"); + glad_glEvalMesh1 = (PFNGLEVALMESH1PROC)load("glEvalMesh1"); + glad_glEvalPoint1 = (PFNGLEVALPOINT1PROC)load("glEvalPoint1"); + glad_glEvalMesh2 = (PFNGLEVALMESH2PROC)load("glEvalMesh2"); + glad_glEvalPoint2 = (PFNGLEVALPOINT2PROC)load("glEvalPoint2"); + glad_glAlphaFunc = (PFNGLALPHAFUNCPROC)load("glAlphaFunc"); + glad_glPixelZoom = (PFNGLPIXELZOOMPROC)load("glPixelZoom"); + glad_glPixelTransferf = (PFNGLPIXELTRANSFERFPROC)load("glPixelTransferf"); + glad_glPixelTransferi = (PFNGLPIXELTRANSFERIPROC)load("glPixelTransferi"); + glad_glPixelMapfv = (PFNGLPIXELMAPFVPROC)load("glPixelMapfv"); + glad_glPixelMapuiv = (PFNGLPIXELMAPUIVPROC)load("glPixelMapuiv"); + glad_glPixelMapusv = (PFNGLPIXELMAPUSVPROC)load("glPixelMapusv"); + glad_glCopyPixels = (PFNGLCOPYPIXELSPROC)load("glCopyPixels"); + glad_glDrawPixels = (PFNGLDRAWPIXELSPROC)load("glDrawPixels"); + glad_glGetClipPlane = (PFNGLGETCLIPPLANEPROC)load("glGetClipPlane"); + glad_glGetLightfv = (PFNGLGETLIGHTFVPROC)load("glGetLightfv"); + glad_glGetLightiv = (PFNGLGETLIGHTIVPROC)load("glGetLightiv"); + glad_glGetMapdv = (PFNGLGETMAPDVPROC)load("glGetMapdv"); + glad_glGetMapfv = (PFNGLGETMAPFVPROC)load("glGetMapfv"); + glad_glGetMapiv = (PFNGLGETMAPIVPROC)load("glGetMapiv"); + glad_glGetMaterialfv = (PFNGLGETMATERIALFVPROC)load("glGetMaterialfv"); + glad_glGetMaterialiv = (PFNGLGETMATERIALIVPROC)load("glGetMaterialiv"); + glad_glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC)load("glGetPixelMapfv"); + glad_glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC)load("glGetPixelMapuiv"); + glad_glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC)load("glGetPixelMapusv"); + glad_glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC)load("glGetPolygonStipple"); + glad_glGetTexEnvfv = (PFNGLGETTEXENVFVPROC)load("glGetTexEnvfv"); + glad_glGetTexEnviv = (PFNGLGETTEXENVIVPROC)load("glGetTexEnviv"); + glad_glGetTexGendv = (PFNGLGETTEXGENDVPROC)load("glGetTexGendv"); + glad_glGetTexGenfv = (PFNGLGETTEXGENFVPROC)load("glGetTexGenfv"); + glad_glGetTexGeniv = (PFNGLGETTEXGENIVPROC)load("glGetTexGeniv"); + glad_glIsList = (PFNGLISLISTPROC)load("glIsList"); + glad_glFrustum = (PFNGLFRUSTUMPROC)load("glFrustum"); + glad_glLoadIdentity = (PFNGLLOADIDENTITYPROC)load("glLoadIdentity"); + glad_glLoadMatrixf = (PFNGLLOADMATRIXFPROC)load("glLoadMatrixf"); + glad_glLoadMatrixd = (PFNGLLOADMATRIXDPROC)load("glLoadMatrixd"); + glad_glMatrixMode = (PFNGLMATRIXMODEPROC)load("glMatrixMode"); + glad_glMultMatrixf = (PFNGLMULTMATRIXFPROC)load("glMultMatrixf"); + glad_glMultMatrixd = (PFNGLMULTMATRIXDPROC)load("glMultMatrixd"); + glad_glOrtho = (PFNGLORTHOPROC)load("glOrtho"); + glad_glPopMatrix = (PFNGLPOPMATRIXPROC)load("glPopMatrix"); + glad_glPushMatrix = (PFNGLPUSHMATRIXPROC)load("glPushMatrix"); + glad_glRotated = (PFNGLROTATEDPROC)load("glRotated"); + glad_glRotatef = (PFNGLROTATEFPROC)load("glRotatef"); + glad_glScaled = (PFNGLSCALEDPROC)load("glScaled"); + glad_glScalef = (PFNGLSCALEFPROC)load("glScalef"); + glad_glTranslated = (PFNGLTRANSLATEDPROC)load("glTranslated"); + glad_glTranslatef = (PFNGLTRANSLATEFPROC)load("glTranslatef"); +} +static void load_GL_VERSION_1_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_1) return; + glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); + glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); + glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv"); + glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); + glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); + glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); + glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D"); + glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); + glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D"); + glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); + glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); + glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); + glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); + glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); + glad_glArrayElement = (PFNGLARRAYELEMENTPROC)load("glArrayElement"); + glad_glColorPointer = (PFNGLCOLORPOINTERPROC)load("glColorPointer"); + glad_glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC)load("glDisableClientState"); + glad_glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC)load("glEdgeFlagPointer"); + glad_glEnableClientState = (PFNGLENABLECLIENTSTATEPROC)load("glEnableClientState"); + glad_glIndexPointer = (PFNGLINDEXPOINTERPROC)load("glIndexPointer"); + glad_glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC)load("glInterleavedArrays"); + glad_glNormalPointer = (PFNGLNORMALPOINTERPROC)load("glNormalPointer"); + glad_glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC)load("glTexCoordPointer"); + glad_glVertexPointer = (PFNGLVERTEXPOINTERPROC)load("glVertexPointer"); + glad_glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC)load("glAreTexturesResident"); + glad_glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)load("glPrioritizeTextures"); + glad_glIndexub = (PFNGLINDEXUBPROC)load("glIndexub"); + glad_glIndexubv = (PFNGLINDEXUBVPROC)load("glIndexubv"); + glad_glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC)load("glPopClientAttrib"); + glad_glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC)load("glPushClientAttrib"); +} +static void load_GL_VERSION_1_2(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_2) return; + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); +} +static void load_GL_VERSION_1_3(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_3) return; + glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); + glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); + glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); + glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); + glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); + glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); + glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); + glad_glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)load("glClientActiveTexture"); + glad_glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)load("glMultiTexCoord1d"); + glad_glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)load("glMultiTexCoord1dv"); + glad_glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)load("glMultiTexCoord1f"); + glad_glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)load("glMultiTexCoord1fv"); + glad_glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)load("glMultiTexCoord1i"); + glad_glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)load("glMultiTexCoord1iv"); + glad_glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)load("glMultiTexCoord1s"); + glad_glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)load("glMultiTexCoord1sv"); + glad_glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)load("glMultiTexCoord2d"); + glad_glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)load("glMultiTexCoord2dv"); + glad_glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)load("glMultiTexCoord2f"); + glad_glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)load("glMultiTexCoord2fv"); + glad_glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)load("glMultiTexCoord2i"); + glad_glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)load("glMultiTexCoord2iv"); + glad_glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)load("glMultiTexCoord2s"); + glad_glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)load("glMultiTexCoord2sv"); + glad_glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)load("glMultiTexCoord3d"); + glad_glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)load("glMultiTexCoord3dv"); + glad_glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)load("glMultiTexCoord3f"); + glad_glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)load("glMultiTexCoord3fv"); + glad_glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)load("glMultiTexCoord3i"); + glad_glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)load("glMultiTexCoord3iv"); + glad_glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)load("glMultiTexCoord3s"); + glad_glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)load("glMultiTexCoord3sv"); + glad_glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)load("glMultiTexCoord4d"); + glad_glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)load("glMultiTexCoord4dv"); + glad_glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)load("glMultiTexCoord4f"); + glad_glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)load("glMultiTexCoord4fv"); + glad_glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)load("glMultiTexCoord4i"); + glad_glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)load("glMultiTexCoord4iv"); + glad_glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)load("glMultiTexCoord4s"); + glad_glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)load("glMultiTexCoord4sv"); + glad_glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)load("glLoadTransposeMatrixf"); + glad_glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)load("glLoadTransposeMatrixd"); + glad_glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)load("glMultTransposeMatrixf"); + glad_glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)load("glMultTransposeMatrixd"); +} +static void load_GL_VERSION_1_4(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_4) return; + glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); + glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays"); + glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements"); + glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf"); + glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); + glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); + glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); + glad_glFogCoordf = (PFNGLFOGCOORDFPROC)load("glFogCoordf"); + glad_glFogCoordfv = (PFNGLFOGCOORDFVPROC)load("glFogCoordfv"); + glad_glFogCoordd = (PFNGLFOGCOORDDPROC)load("glFogCoordd"); + glad_glFogCoorddv = (PFNGLFOGCOORDDVPROC)load("glFogCoorddv"); + glad_glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)load("glFogCoordPointer"); + glad_glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)load("glSecondaryColor3b"); + glad_glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)load("glSecondaryColor3bv"); + glad_glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)load("glSecondaryColor3d"); + glad_glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)load("glSecondaryColor3dv"); + glad_glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)load("glSecondaryColor3f"); + glad_glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)load("glSecondaryColor3fv"); + glad_glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)load("glSecondaryColor3i"); + glad_glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)load("glSecondaryColor3iv"); + glad_glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)load("glSecondaryColor3s"); + glad_glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)load("glSecondaryColor3sv"); + glad_glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)load("glSecondaryColor3ub"); + glad_glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)load("glSecondaryColor3ubv"); + glad_glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)load("glSecondaryColor3ui"); + glad_glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)load("glSecondaryColor3uiv"); + glad_glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)load("glSecondaryColor3us"); + glad_glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)load("glSecondaryColor3usv"); + glad_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)load("glSecondaryColorPointer"); + glad_glWindowPos2d = (PFNGLWINDOWPOS2DPROC)load("glWindowPos2d"); + glad_glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)load("glWindowPos2dv"); + glad_glWindowPos2f = (PFNGLWINDOWPOS2FPROC)load("glWindowPos2f"); + glad_glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)load("glWindowPos2fv"); + glad_glWindowPos2i = (PFNGLWINDOWPOS2IPROC)load("glWindowPos2i"); + glad_glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)load("glWindowPos2iv"); + glad_glWindowPos2s = (PFNGLWINDOWPOS2SPROC)load("glWindowPos2s"); + glad_glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)load("glWindowPos2sv"); + glad_glWindowPos3d = (PFNGLWINDOWPOS3DPROC)load("glWindowPos3d"); + glad_glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)load("glWindowPos3dv"); + glad_glWindowPos3f = (PFNGLWINDOWPOS3FPROC)load("glWindowPos3f"); + glad_glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)load("glWindowPos3fv"); + glad_glWindowPos3i = (PFNGLWINDOWPOS3IPROC)load("glWindowPos3i"); + glad_glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)load("glWindowPos3iv"); + glad_glWindowPos3s = (PFNGLWINDOWPOS3SPROC)load("glWindowPos3s"); + glad_glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)load("glWindowPos3sv"); + glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); + glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); +} +static void load_GL_VERSION_1_5(GLADloadproc load) { + if(!GLAD_GL_VERSION_1_5) return; + glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); + glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); + glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); + glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); + glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); + glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); + glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); + glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); + glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); + glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); + glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); + glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData"); + glad_glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); + glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); +} +static void load_GL_VERSION_2_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_2_0) return; + glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); + glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); + glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); + glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); + glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); + glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); + glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); + glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); + glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); + glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); + glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); + glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); + glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); + glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); + glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); + glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); + glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); + glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); + glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); + glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); + glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); + glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); + glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); + glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); + glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); + glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); + glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv"); + glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); + glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); + glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); + glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); + glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); + glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); + glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); + glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); + glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); + glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); + glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); + glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); + glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); + glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); + glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); + glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); + glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); + glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); + glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); + glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); + glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); + glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); + glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); + glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); + glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); + glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); + glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); + glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); + glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d"); + glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv"); + glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); + glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); + glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s"); + glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv"); + glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d"); + glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv"); + glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); + glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); + glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s"); + glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv"); + glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d"); + glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv"); + glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); + glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); + glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s"); + glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv"); + glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv"); + glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv"); + glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv"); + glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub"); + glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv"); + glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv"); + glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv"); + glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv"); + glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d"); + glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv"); + glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); + glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); + glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv"); + glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s"); + glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv"); + glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv"); + glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv"); + glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv"); + glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); +} +static void load_GL_VERSION_2_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_2_1) return; + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); +} +static void load_GL_VERSION_3_0(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_0) return; + glad_glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); + glad_glEnablei = (PFNGLENABLEIPROC)load("glEnablei"); + glad_glDisablei = (PFNGLDISABLEIPROC)load("glDisablei"); + glad_glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); + glad_glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor"); + glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender"); + glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); + glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i"); + glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i"); + glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); + glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui"); + glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui"); + glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); + glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv"); + glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv"); + glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); + glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv"); + glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv"); + glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); + glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv"); + glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv"); + glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv"); + glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); + glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); + glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv"); + glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv"); + glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv"); + glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); +} +static void load_GL_VERSION_3_1(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_1) return; + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); + glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); + glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); + glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); +} +static void load_GL_VERSION_3_2(GLADloadproc load) { + if(!GLAD_GL_VERSION_3_2) return; + glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); + glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); + glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); + glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); + glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); + glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); + glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); + glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); + glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); + glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); + glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); +} +static void load_GL_ARB_multisample(GLADloadproc load) { + if(!GLAD_GL_ARB_multisample) return; + glad_glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)load("glSampleCoverageARB"); +} +static void load_GL_ARB_robustness(GLADloadproc load) { + if(!GLAD_GL_ARB_robustness) return; + glad_glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC)load("glGetGraphicsResetStatusARB"); + glad_glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC)load("glGetnTexImageARB"); + glad_glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)load("glReadnPixelsARB"); + glad_glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)load("glGetnCompressedTexImageARB"); + glad_glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC)load("glGetnUniformfvARB"); + glad_glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC)load("glGetnUniformivARB"); + glad_glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC)load("glGetnUniformuivARB"); + glad_glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC)load("glGetnUniformdvARB"); + glad_glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC)load("glGetnMapdvARB"); + glad_glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC)load("glGetnMapfvARB"); + glad_glGetnMapivARB = (PFNGLGETNMAPIVARBPROC)load("glGetnMapivARB"); + glad_glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC)load("glGetnPixelMapfvARB"); + glad_glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC)load("glGetnPixelMapuivARB"); + glad_glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC)load("glGetnPixelMapusvARB"); + glad_glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC)load("glGetnPolygonStippleARB"); + glad_glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC)load("glGetnColorTableARB"); + glad_glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC)load("glGetnConvolutionFilterARB"); + glad_glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC)load("glGetnSeparableFilterARB"); + glad_glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC)load("glGetnHistogramARB"); + glad_glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC)load("glGetnMinmaxARB"); +} +static void find_extensionsGL(void) { + GLAD_GL_EXT_separate_specular_color = has_ext("GL_EXT_separate_specular_color"); + GLAD_GL_ARB_multisample = has_ext("GL_ARB_multisample"); + GLAD_GL_ARB_robustness = has_ext("GL_ARB_robustness"); +} + +static void find_coreGL(void) { + + /* Thank you @elmindreda + * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 + * https://github.com/glfw/glfw/blob/master/src/context.c#L36 + */ + int i, major, minor; + + const char* version; + const char* prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + NULL + }; + + version = (const char*) glGetString(GL_VERSION); + if (!version) return; + + for (i = 0; prefixes[i]; i++) { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) { + version += length; + break; + } + } + +/* PR #18 */ +#ifdef _MSC_VER + sscanf_s(version, "%d.%d", &major, &minor); +#else + sscanf(version, "%d.%d", &major, &minor); +#endif + + GLVersion.major = major; GLVersion.minor = minor; + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; +} + +int gladLoadGLLoader(GLADloadproc load) { + GLVersion.major = 0; GLVersion.minor = 0; + glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); + if(glGetString == NULL) return 0; + if(glGetString(GL_VERSION) == NULL) return 0; + find_coreGL(); + load_GL_VERSION_1_0(load); + load_GL_VERSION_1_1(load); + load_GL_VERSION_1_2(load); + load_GL_VERSION_1_3(load); + load_GL_VERSION_1_4(load); + load_GL_VERSION_1_5(load); + load_GL_VERSION_2_0(load); + load_GL_VERSION_2_1(load); + load_GL_VERSION_3_0(load); + load_GL_VERSION_3_1(load); + load_GL_VERSION_3_2(load); + + find_extensionsGL(); + load_GL_ARB_multisample(load); + load_GL_ARB_robustness(load); + return GLVersion.major != 0 || GLVersion.minor != 0; +} + diff --git a/extern/glfw-3.2.1/deps/glad/glad.h b/extern/glfw-3.2.1/deps/glad/glad.h new file mode 100644 index 0000000..ef96591 --- /dev/null +++ b/extern/glfw-3.2.1/deps/glad/glad.h @@ -0,0 +1,3520 @@ + +#ifndef __glad_h_ +#define __glad_h_ + +#ifdef __gl_h_ +#error OpenGL header already included, remove this include, glad already provides it +#endif +#define __gl_h_ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct gladGLversionStruct { + int major; + int minor; +}; + +extern struct gladGLversionStruct GLVersion; + +typedef void* (* GLADloadproc)(const char *name); + +#ifndef GLAPI +# if defined(GLAD_GLAPI_EXPORT) +# if defined(WIN32) || defined(__CYGWIN__) +# if defined(GLAD_GLAPI_EXPORT_BUILD) +# if defined(__GNUC__) +# define GLAPI __attribute__ ((dllexport)) extern +# else +# define GLAPI __declspec(dllexport) extern +# endif +# else +# if defined(__GNUC__) +# define GLAPI __attribute__ ((dllimport)) extern +# else +# define GLAPI __declspec(dllimport) extern +# endif +# endif +# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) +# define GLAPI __attribute__ ((visibility ("default"))) extern +# else +# define GLAPI extern +# endif +# else +# define GLAPI extern +# endif +#endif +GLAPI int gladLoadGLLoader(GLADloadproc); + +#include +#include +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLclampx; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef int GLsizei; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void *GLeglImageOES; +typedef char GLchar; +typedef char GLcharARB; +#ifdef __APPLE__ +typedef void *GLhandleARB; +#else +typedef unsigned int GLhandleARB; +#endif +typedef unsigned short GLhalfARB; +typedef unsigned short GLhalf; +typedef GLint GLfixed; +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +typedef int64_t GLint64; +typedef uint64_t GLuint64; +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +typedef struct __GLsync *GLsync; +struct _cl_context; +struct _cl_event; +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); +typedef unsigned short GLhalfNV; +typedef GLintptr GLvdpauSurfaceNV; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_VIEWPORT 0x0BA2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_DOUBLE 0x140A +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +#define GL_TEXTURE 0x1702 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_REPEAT 0x2901 +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_LOGIC_OP 0x0BF1 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_COLOR_INDEX 0x1900 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_BITMAP 0x1A00 +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_ENV 0x2300 +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 +#define GL_CLAMP 0x2900 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_RESCALE_NORMAL 0x803A +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +#define GL_MULTISAMPLE_BIT 0x20000000 +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_DEPTH_TEXTURE_MODE 0x884B +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#define GL_SRC1_ALPHA 0x8589 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC2_ALPHA 0x858A +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_INDEX 0x8222 +#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 +#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_CLAMP_VERTEX_COLOR 0x891A +#define GL_CLAMP_FRAGMENT_COLOR 0x891B +#define GL_ALPHA_INTEGER 0x8D97 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFF +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#define GL_DEPTH_CLAMP 0x864F +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#ifndef GL_VERSION_1_0 +#define GL_VERSION_1_0 1 +GLAPI int GLAD_GL_VERSION_1_0; +typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum mode); +GLAPI PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum mode); +GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; +#define glFrontFace glad_glFrontFace +typedef void (APIENTRYP PFNGLHINTPROC)(GLenum target, GLenum mode); +GLAPI PFNGLHINTPROC glad_glHint; +#define glHint glad_glHint +typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat width); +GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +typedef void (APIENTRYP PFNGLPOINTSIZEPROC)(GLfloat size); +GLAPI PFNGLPOINTSIZEPROC glad_glPointSize; +#define glPointSize glad_glPointSize +typedef void (APIENTRYP PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); +GLAPI PFNGLPOLYGONMODEPROC glad_glPolygonMode; +#define glPolygonMode glad_glPolygonMode +typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLSCISSORPROC glad_glScissor; +#define glScissor glad_glScissor +typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); +GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; +#define glTexParameterf glad_glTexParameterf +typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat* params); +GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; +#define glTexParameterfv glad_glTexParameterfv +typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; +#define glTexParameteri glad_glTexParameteri +typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint* params); +GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; +#define glTexParameteriv glad_glTexParameteriv +typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLTEXIMAGE1DPROC glad_glTexImage1D; +#define glTexImage1D glad_glTexImage1D +typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; +#define glTexImage2D glad_glTexImage2D +typedef void (APIENTRYP PFNGLDRAWBUFFERPROC)(GLenum buf); +GLAPI PFNGLDRAWBUFFERPROC glad_glDrawBuffer; +#define glDrawBuffer glad_glDrawBuffer +typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield mask); +GLAPI PFNGLCLEARPROC glad_glClear; +#define glClear glad_glClear +typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; +#define glClearColor glad_glClearColor +typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint s); +GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; +#define glClearStencil glad_glClearStencil +typedef void (APIENTRYP PFNGLCLEARDEPTHPROC)(GLdouble depth); +GLAPI PFNGLCLEARDEPTHPROC glad_glClearDepth; +#define glClearDepth glad_glClearDepth +typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint mask); +GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; +#define glStencilMask glad_glStencilMask +typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI PFNGLCOLORMASKPROC glad_glColorMask; +#define glColorMask glad_glColorMask +typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean flag); +GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; +#define glDepthMask glad_glDepthMask +typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum cap); +GLAPI PFNGLDISABLEPROC glad_glDisable; +#define glDisable glad_glDisable +typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum cap); +GLAPI PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +typedef void (APIENTRYP PFNGLFINISHPROC)(); +GLAPI PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +typedef void (APIENTRYP PFNGLFLUSHPROC)(); +GLAPI PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); +GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; +#define glBlendFunc glad_glBlendFunc +typedef void (APIENTRYP PFNGLLOGICOPPROC)(GLenum opcode); +GLAPI PFNGLLOGICOPPROC glad_glLogicOp; +#define glLogicOp glad_glLogicOp +typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); +GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; +#define glStencilFunc glad_glStencilFunc +typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); +GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; +#define glStencilOp glad_glStencilOp +typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum func); +GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; +#define glDepthFunc glad_glDepthFunc +typedef void (APIENTRYP PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLPIXELSTOREFPROC glad_glPixelStoref; +#define glPixelStoref glad_glPixelStoref +typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); +GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum src); +GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); +GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; +#define glReadPixels glad_glReadPixels +typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean* data); +GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +typedef void (APIENTRYP PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble* data); +GLAPI PFNGLGETDOUBLEVPROC glad_glGetDoublev; +#define glGetDoublev glad_glGetDoublev +typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(); +GLAPI PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum pname, GLfloat* data); +GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint* data); +GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name); +GLAPI PFNGLGETSTRINGPROC glad_glGetString; +#define glGetString glad_glGetString +typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void* pixels); +GLAPI PFNGLGETTEXIMAGEPROC glad_glGetTexImage; +#define glGetTexImage glad_glGetTexImage +typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat* params); +GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params); +GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat* params); +GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint* params); +GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum cap); +GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; +#define glIsEnabled glad_glIsEnabled +typedef void (APIENTRYP PFNGLDEPTHRANGEPROC)(GLdouble near, GLdouble far); +GLAPI PFNGLDEPTHRANGEPROC glad_glDepthRange; +#define glDepthRange glad_glDepthRange +typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +typedef void (APIENTRYP PFNGLNEWLISTPROC)(GLuint list, GLenum mode); +GLAPI PFNGLNEWLISTPROC glad_glNewList; +#define glNewList glad_glNewList +typedef void (APIENTRYP PFNGLENDLISTPROC)(); +GLAPI PFNGLENDLISTPROC glad_glEndList; +#define glEndList glad_glEndList +typedef void (APIENTRYP PFNGLCALLLISTPROC)(GLuint list); +GLAPI PFNGLCALLLISTPROC glad_glCallList; +#define glCallList glad_glCallList +typedef void (APIENTRYP PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void* lists); +GLAPI PFNGLCALLLISTSPROC glad_glCallLists; +#define glCallLists glad_glCallLists +typedef void (APIENTRYP PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); +GLAPI PFNGLDELETELISTSPROC glad_glDeleteLists; +#define glDeleteLists glad_glDeleteLists +typedef GLuint (APIENTRYP PFNGLGENLISTSPROC)(GLsizei range); +GLAPI PFNGLGENLISTSPROC glad_glGenLists; +#define glGenLists glad_glGenLists +typedef void (APIENTRYP PFNGLLISTBASEPROC)(GLuint base); +GLAPI PFNGLLISTBASEPROC glad_glListBase; +#define glListBase glad_glListBase +typedef void (APIENTRYP PFNGLBEGINPROC)(GLenum mode); +GLAPI PFNGLBEGINPROC glad_glBegin; +#define glBegin glad_glBegin +typedef void (APIENTRYP PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte* bitmap); +GLAPI PFNGLBITMAPPROC glad_glBitmap; +#define glBitmap glad_glBitmap +typedef void (APIENTRYP PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +GLAPI PFNGLCOLOR3BPROC glad_glColor3b; +#define glColor3b glad_glColor3b +typedef void (APIENTRYP PFNGLCOLOR3BVPROC)(const GLbyte* v); +GLAPI PFNGLCOLOR3BVPROC glad_glColor3bv; +#define glColor3bv glad_glColor3bv +typedef void (APIENTRYP PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +GLAPI PFNGLCOLOR3DPROC glad_glColor3d; +#define glColor3d glad_glColor3d +typedef void (APIENTRYP PFNGLCOLOR3DVPROC)(const GLdouble* v); +GLAPI PFNGLCOLOR3DVPROC glad_glColor3dv; +#define glColor3dv glad_glColor3dv +typedef void (APIENTRYP PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +GLAPI PFNGLCOLOR3FPROC glad_glColor3f; +#define glColor3f glad_glColor3f +typedef void (APIENTRYP PFNGLCOLOR3FVPROC)(const GLfloat* v); +GLAPI PFNGLCOLOR3FVPROC glad_glColor3fv; +#define glColor3fv glad_glColor3fv +typedef void (APIENTRYP PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); +GLAPI PFNGLCOLOR3IPROC glad_glColor3i; +#define glColor3i glad_glColor3i +typedef void (APIENTRYP PFNGLCOLOR3IVPROC)(const GLint* v); +GLAPI PFNGLCOLOR3IVPROC glad_glColor3iv; +#define glColor3iv glad_glColor3iv +typedef void (APIENTRYP PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +GLAPI PFNGLCOLOR3SPROC glad_glColor3s; +#define glColor3s glad_glColor3s +typedef void (APIENTRYP PFNGLCOLOR3SVPROC)(const GLshort* v); +GLAPI PFNGLCOLOR3SVPROC glad_glColor3sv; +#define glColor3sv glad_glColor3sv +typedef void (APIENTRYP PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +GLAPI PFNGLCOLOR3UBPROC glad_glColor3ub; +#define glColor3ub glad_glColor3ub +typedef void (APIENTRYP PFNGLCOLOR3UBVPROC)(const GLubyte* v); +GLAPI PFNGLCOLOR3UBVPROC glad_glColor3ubv; +#define glColor3ubv glad_glColor3ubv +typedef void (APIENTRYP PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +GLAPI PFNGLCOLOR3UIPROC glad_glColor3ui; +#define glColor3ui glad_glColor3ui +typedef void (APIENTRYP PFNGLCOLOR3UIVPROC)(const GLuint* v); +GLAPI PFNGLCOLOR3UIVPROC glad_glColor3uiv; +#define glColor3uiv glad_glColor3uiv +typedef void (APIENTRYP PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +GLAPI PFNGLCOLOR3USPROC glad_glColor3us; +#define glColor3us glad_glColor3us +typedef void (APIENTRYP PFNGLCOLOR3USVPROC)(const GLushort* v); +GLAPI PFNGLCOLOR3USVPROC glad_glColor3usv; +#define glColor3usv glad_glColor3usv +typedef void (APIENTRYP PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +GLAPI PFNGLCOLOR4BPROC glad_glColor4b; +#define glColor4b glad_glColor4b +typedef void (APIENTRYP PFNGLCOLOR4BVPROC)(const GLbyte* v); +GLAPI PFNGLCOLOR4BVPROC glad_glColor4bv; +#define glColor4bv glad_glColor4bv +typedef void (APIENTRYP PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +GLAPI PFNGLCOLOR4DPROC glad_glColor4d; +#define glColor4d glad_glColor4d +typedef void (APIENTRYP PFNGLCOLOR4DVPROC)(const GLdouble* v); +GLAPI PFNGLCOLOR4DVPROC glad_glColor4dv; +#define glColor4dv glad_glColor4dv +typedef void (APIENTRYP PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLCOLOR4FPROC glad_glColor4f; +#define glColor4f glad_glColor4f +typedef void (APIENTRYP PFNGLCOLOR4FVPROC)(const GLfloat* v); +GLAPI PFNGLCOLOR4FVPROC glad_glColor4fv; +#define glColor4fv glad_glColor4fv +typedef void (APIENTRYP PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); +GLAPI PFNGLCOLOR4IPROC glad_glColor4i; +#define glColor4i glad_glColor4i +typedef void (APIENTRYP PFNGLCOLOR4IVPROC)(const GLint* v); +GLAPI PFNGLCOLOR4IVPROC glad_glColor4iv; +#define glColor4iv glad_glColor4iv +typedef void (APIENTRYP PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); +GLAPI PFNGLCOLOR4SPROC glad_glColor4s; +#define glColor4s glad_glColor4s +typedef void (APIENTRYP PFNGLCOLOR4SVPROC)(const GLshort* v); +GLAPI PFNGLCOLOR4SVPROC glad_glColor4sv; +#define glColor4sv glad_glColor4sv +typedef void (APIENTRYP PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +GLAPI PFNGLCOLOR4UBPROC glad_glColor4ub; +#define glColor4ub glad_glColor4ub +typedef void (APIENTRYP PFNGLCOLOR4UBVPROC)(const GLubyte* v); +GLAPI PFNGLCOLOR4UBVPROC glad_glColor4ubv; +#define glColor4ubv glad_glColor4ubv +typedef void (APIENTRYP PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); +GLAPI PFNGLCOLOR4UIPROC glad_glColor4ui; +#define glColor4ui glad_glColor4ui +typedef void (APIENTRYP PFNGLCOLOR4UIVPROC)(const GLuint* v); +GLAPI PFNGLCOLOR4UIVPROC glad_glColor4uiv; +#define glColor4uiv glad_glColor4uiv +typedef void (APIENTRYP PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); +GLAPI PFNGLCOLOR4USPROC glad_glColor4us; +#define glColor4us glad_glColor4us +typedef void (APIENTRYP PFNGLCOLOR4USVPROC)(const GLushort* v); +GLAPI PFNGLCOLOR4USVPROC glad_glColor4usv; +#define glColor4usv glad_glColor4usv +typedef void (APIENTRYP PFNGLEDGEFLAGPROC)(GLboolean flag); +GLAPI PFNGLEDGEFLAGPROC glad_glEdgeFlag; +#define glEdgeFlag glad_glEdgeFlag +typedef void (APIENTRYP PFNGLEDGEFLAGVPROC)(const GLboolean* flag); +GLAPI PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; +#define glEdgeFlagv glad_glEdgeFlagv +typedef void (APIENTRYP PFNGLENDPROC)(); +GLAPI PFNGLENDPROC glad_glEnd; +#define glEnd glad_glEnd +typedef void (APIENTRYP PFNGLINDEXDPROC)(GLdouble c); +GLAPI PFNGLINDEXDPROC glad_glIndexd; +#define glIndexd glad_glIndexd +typedef void (APIENTRYP PFNGLINDEXDVPROC)(const GLdouble* c); +GLAPI PFNGLINDEXDVPROC glad_glIndexdv; +#define glIndexdv glad_glIndexdv +typedef void (APIENTRYP PFNGLINDEXFPROC)(GLfloat c); +GLAPI PFNGLINDEXFPROC glad_glIndexf; +#define glIndexf glad_glIndexf +typedef void (APIENTRYP PFNGLINDEXFVPROC)(const GLfloat* c); +GLAPI PFNGLINDEXFVPROC glad_glIndexfv; +#define glIndexfv glad_glIndexfv +typedef void (APIENTRYP PFNGLINDEXIPROC)(GLint c); +GLAPI PFNGLINDEXIPROC glad_glIndexi; +#define glIndexi glad_glIndexi +typedef void (APIENTRYP PFNGLINDEXIVPROC)(const GLint* c); +GLAPI PFNGLINDEXIVPROC glad_glIndexiv; +#define glIndexiv glad_glIndexiv +typedef void (APIENTRYP PFNGLINDEXSPROC)(GLshort c); +GLAPI PFNGLINDEXSPROC glad_glIndexs; +#define glIndexs glad_glIndexs +typedef void (APIENTRYP PFNGLINDEXSVPROC)(const GLshort* c); +GLAPI PFNGLINDEXSVPROC glad_glIndexsv; +#define glIndexsv glad_glIndexsv +typedef void (APIENTRYP PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); +GLAPI PFNGLNORMAL3BPROC glad_glNormal3b; +#define glNormal3b glad_glNormal3b +typedef void (APIENTRYP PFNGLNORMAL3BVPROC)(const GLbyte* v); +GLAPI PFNGLNORMAL3BVPROC glad_glNormal3bv; +#define glNormal3bv glad_glNormal3bv +typedef void (APIENTRYP PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); +GLAPI PFNGLNORMAL3DPROC glad_glNormal3d; +#define glNormal3d glad_glNormal3d +typedef void (APIENTRYP PFNGLNORMAL3DVPROC)(const GLdouble* v); +GLAPI PFNGLNORMAL3DVPROC glad_glNormal3dv; +#define glNormal3dv glad_glNormal3dv +typedef void (APIENTRYP PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); +GLAPI PFNGLNORMAL3FPROC glad_glNormal3f; +#define glNormal3f glad_glNormal3f +typedef void (APIENTRYP PFNGLNORMAL3FVPROC)(const GLfloat* v); +GLAPI PFNGLNORMAL3FVPROC glad_glNormal3fv; +#define glNormal3fv glad_glNormal3fv +typedef void (APIENTRYP PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); +GLAPI PFNGLNORMAL3IPROC glad_glNormal3i; +#define glNormal3i glad_glNormal3i +typedef void (APIENTRYP PFNGLNORMAL3IVPROC)(const GLint* v); +GLAPI PFNGLNORMAL3IVPROC glad_glNormal3iv; +#define glNormal3iv glad_glNormal3iv +typedef void (APIENTRYP PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); +GLAPI PFNGLNORMAL3SPROC glad_glNormal3s; +#define glNormal3s glad_glNormal3s +typedef void (APIENTRYP PFNGLNORMAL3SVPROC)(const GLshort* v); +GLAPI PFNGLNORMAL3SVPROC glad_glNormal3sv; +#define glNormal3sv glad_glNormal3sv +typedef void (APIENTRYP PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); +GLAPI PFNGLRASTERPOS2DPROC glad_glRasterPos2d; +#define glRasterPos2d glad_glRasterPos2d +typedef void (APIENTRYP PFNGLRASTERPOS2DVPROC)(const GLdouble* v); +GLAPI PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; +#define glRasterPos2dv glad_glRasterPos2dv +typedef void (APIENTRYP PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); +GLAPI PFNGLRASTERPOS2FPROC glad_glRasterPos2f; +#define glRasterPos2f glad_glRasterPos2f +typedef void (APIENTRYP PFNGLRASTERPOS2FVPROC)(const GLfloat* v); +GLAPI PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; +#define glRasterPos2fv glad_glRasterPos2fv +typedef void (APIENTRYP PFNGLRASTERPOS2IPROC)(GLint x, GLint y); +GLAPI PFNGLRASTERPOS2IPROC glad_glRasterPos2i; +#define glRasterPos2i glad_glRasterPos2i +typedef void (APIENTRYP PFNGLRASTERPOS2IVPROC)(const GLint* v); +GLAPI PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; +#define glRasterPos2iv glad_glRasterPos2iv +typedef void (APIENTRYP PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); +GLAPI PFNGLRASTERPOS2SPROC glad_glRasterPos2s; +#define glRasterPos2s glad_glRasterPos2s +typedef void (APIENTRYP PFNGLRASTERPOS2SVPROC)(const GLshort* v); +GLAPI PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; +#define glRasterPos2sv glad_glRasterPos2sv +typedef void (APIENTRYP PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLRASTERPOS3DPROC glad_glRasterPos3d; +#define glRasterPos3d glad_glRasterPos3d +typedef void (APIENTRYP PFNGLRASTERPOS3DVPROC)(const GLdouble* v); +GLAPI PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; +#define glRasterPos3dv glad_glRasterPos3dv +typedef void (APIENTRYP PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLRASTERPOS3FPROC glad_glRasterPos3f; +#define glRasterPos3f glad_glRasterPos3f +typedef void (APIENTRYP PFNGLRASTERPOS3FVPROC)(const GLfloat* v); +GLAPI PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; +#define glRasterPos3fv glad_glRasterPos3fv +typedef void (APIENTRYP PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); +GLAPI PFNGLRASTERPOS3IPROC glad_glRasterPos3i; +#define glRasterPos3i glad_glRasterPos3i +typedef void (APIENTRYP PFNGLRASTERPOS3IVPROC)(const GLint* v); +GLAPI PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; +#define glRasterPos3iv glad_glRasterPos3iv +typedef void (APIENTRYP PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); +GLAPI PFNGLRASTERPOS3SPROC glad_glRasterPos3s; +#define glRasterPos3s glad_glRasterPos3s +typedef void (APIENTRYP PFNGLRASTERPOS3SVPROC)(const GLshort* v); +GLAPI PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; +#define glRasterPos3sv glad_glRasterPos3sv +typedef void (APIENTRYP PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI PFNGLRASTERPOS4DPROC glad_glRasterPos4d; +#define glRasterPos4d glad_glRasterPos4d +typedef void (APIENTRYP PFNGLRASTERPOS4DVPROC)(const GLdouble* v); +GLAPI PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; +#define glRasterPos4dv glad_glRasterPos4dv +typedef void (APIENTRYP PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI PFNGLRASTERPOS4FPROC glad_glRasterPos4f; +#define glRasterPos4f glad_glRasterPos4f +typedef void (APIENTRYP PFNGLRASTERPOS4FVPROC)(const GLfloat* v); +GLAPI PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; +#define glRasterPos4fv glad_glRasterPos4fv +typedef void (APIENTRYP PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); +GLAPI PFNGLRASTERPOS4IPROC glad_glRasterPos4i; +#define glRasterPos4i glad_glRasterPos4i +typedef void (APIENTRYP PFNGLRASTERPOS4IVPROC)(const GLint* v); +GLAPI PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; +#define glRasterPos4iv glad_glRasterPos4iv +typedef void (APIENTRYP PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI PFNGLRASTERPOS4SPROC glad_glRasterPos4s; +#define glRasterPos4s glad_glRasterPos4s +typedef void (APIENTRYP PFNGLRASTERPOS4SVPROC)(const GLshort* v); +GLAPI PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; +#define glRasterPos4sv glad_glRasterPos4sv +typedef void (APIENTRYP PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +GLAPI PFNGLRECTDPROC glad_glRectd; +#define glRectd glad_glRectd +typedef void (APIENTRYP PFNGLRECTDVPROC)(const GLdouble* v1, const GLdouble* v2); +GLAPI PFNGLRECTDVPROC glad_glRectdv; +#define glRectdv glad_glRectdv +typedef void (APIENTRYP PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +GLAPI PFNGLRECTFPROC glad_glRectf; +#define glRectf glad_glRectf +typedef void (APIENTRYP PFNGLRECTFVPROC)(const GLfloat* v1, const GLfloat* v2); +GLAPI PFNGLRECTFVPROC glad_glRectfv; +#define glRectfv glad_glRectfv +typedef void (APIENTRYP PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); +GLAPI PFNGLRECTIPROC glad_glRecti; +#define glRecti glad_glRecti +typedef void (APIENTRYP PFNGLRECTIVPROC)(const GLint* v1, const GLint* v2); +GLAPI PFNGLRECTIVPROC glad_glRectiv; +#define glRectiv glad_glRectiv +typedef void (APIENTRYP PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +GLAPI PFNGLRECTSPROC glad_glRects; +#define glRects glad_glRects +typedef void (APIENTRYP PFNGLRECTSVPROC)(const GLshort* v1, const GLshort* v2); +GLAPI PFNGLRECTSVPROC glad_glRectsv; +#define glRectsv glad_glRectsv +typedef void (APIENTRYP PFNGLTEXCOORD1DPROC)(GLdouble s); +GLAPI PFNGLTEXCOORD1DPROC glad_glTexCoord1d; +#define glTexCoord1d glad_glTexCoord1d +typedef void (APIENTRYP PFNGLTEXCOORD1DVPROC)(const GLdouble* v); +GLAPI PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; +#define glTexCoord1dv glad_glTexCoord1dv +typedef void (APIENTRYP PFNGLTEXCOORD1FPROC)(GLfloat s); +GLAPI PFNGLTEXCOORD1FPROC glad_glTexCoord1f; +#define glTexCoord1f glad_glTexCoord1f +typedef void (APIENTRYP PFNGLTEXCOORD1FVPROC)(const GLfloat* v); +GLAPI PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; +#define glTexCoord1fv glad_glTexCoord1fv +typedef void (APIENTRYP PFNGLTEXCOORD1IPROC)(GLint s); +GLAPI PFNGLTEXCOORD1IPROC glad_glTexCoord1i; +#define glTexCoord1i glad_glTexCoord1i +typedef void (APIENTRYP PFNGLTEXCOORD1IVPROC)(const GLint* v); +GLAPI PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; +#define glTexCoord1iv glad_glTexCoord1iv +typedef void (APIENTRYP PFNGLTEXCOORD1SPROC)(GLshort s); +GLAPI PFNGLTEXCOORD1SPROC glad_glTexCoord1s; +#define glTexCoord1s glad_glTexCoord1s +typedef void (APIENTRYP PFNGLTEXCOORD1SVPROC)(const GLshort* v); +GLAPI PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; +#define glTexCoord1sv glad_glTexCoord1sv +typedef void (APIENTRYP PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); +GLAPI PFNGLTEXCOORD2DPROC glad_glTexCoord2d; +#define glTexCoord2d glad_glTexCoord2d +typedef void (APIENTRYP PFNGLTEXCOORD2DVPROC)(const GLdouble* v); +GLAPI PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; +#define glTexCoord2dv glad_glTexCoord2dv +typedef void (APIENTRYP PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); +GLAPI PFNGLTEXCOORD2FPROC glad_glTexCoord2f; +#define glTexCoord2f glad_glTexCoord2f +typedef void (APIENTRYP PFNGLTEXCOORD2FVPROC)(const GLfloat* v); +GLAPI PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; +#define glTexCoord2fv glad_glTexCoord2fv +typedef void (APIENTRYP PFNGLTEXCOORD2IPROC)(GLint s, GLint t); +GLAPI PFNGLTEXCOORD2IPROC glad_glTexCoord2i; +#define glTexCoord2i glad_glTexCoord2i +typedef void (APIENTRYP PFNGLTEXCOORD2IVPROC)(const GLint* v); +GLAPI PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; +#define glTexCoord2iv glad_glTexCoord2iv +typedef void (APIENTRYP PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); +GLAPI PFNGLTEXCOORD2SPROC glad_glTexCoord2s; +#define glTexCoord2s glad_glTexCoord2s +typedef void (APIENTRYP PFNGLTEXCOORD2SVPROC)(const GLshort* v); +GLAPI PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; +#define glTexCoord2sv glad_glTexCoord2sv +typedef void (APIENTRYP PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); +GLAPI PFNGLTEXCOORD3DPROC glad_glTexCoord3d; +#define glTexCoord3d glad_glTexCoord3d +typedef void (APIENTRYP PFNGLTEXCOORD3DVPROC)(const GLdouble* v); +GLAPI PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; +#define glTexCoord3dv glad_glTexCoord3dv +typedef void (APIENTRYP PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); +GLAPI PFNGLTEXCOORD3FPROC glad_glTexCoord3f; +#define glTexCoord3f glad_glTexCoord3f +typedef void (APIENTRYP PFNGLTEXCOORD3FVPROC)(const GLfloat* v); +GLAPI PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; +#define glTexCoord3fv glad_glTexCoord3fv +typedef void (APIENTRYP PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); +GLAPI PFNGLTEXCOORD3IPROC glad_glTexCoord3i; +#define glTexCoord3i glad_glTexCoord3i +typedef void (APIENTRYP PFNGLTEXCOORD3IVPROC)(const GLint* v); +GLAPI PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; +#define glTexCoord3iv glad_glTexCoord3iv +typedef void (APIENTRYP PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); +GLAPI PFNGLTEXCOORD3SPROC glad_glTexCoord3s; +#define glTexCoord3s glad_glTexCoord3s +typedef void (APIENTRYP PFNGLTEXCOORD3SVPROC)(const GLshort* v); +GLAPI PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; +#define glTexCoord3sv glad_glTexCoord3sv +typedef void (APIENTRYP PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI PFNGLTEXCOORD4DPROC glad_glTexCoord4d; +#define glTexCoord4d glad_glTexCoord4d +typedef void (APIENTRYP PFNGLTEXCOORD4DVPROC)(const GLdouble* v); +GLAPI PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; +#define glTexCoord4dv glad_glTexCoord4dv +typedef void (APIENTRYP PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI PFNGLTEXCOORD4FPROC glad_glTexCoord4f; +#define glTexCoord4f glad_glTexCoord4f +typedef void (APIENTRYP PFNGLTEXCOORD4FVPROC)(const GLfloat* v); +GLAPI PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; +#define glTexCoord4fv glad_glTexCoord4fv +typedef void (APIENTRYP PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); +GLAPI PFNGLTEXCOORD4IPROC glad_glTexCoord4i; +#define glTexCoord4i glad_glTexCoord4i +typedef void (APIENTRYP PFNGLTEXCOORD4IVPROC)(const GLint* v); +GLAPI PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; +#define glTexCoord4iv glad_glTexCoord4iv +typedef void (APIENTRYP PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI PFNGLTEXCOORD4SPROC glad_glTexCoord4s; +#define glTexCoord4s glad_glTexCoord4s +typedef void (APIENTRYP PFNGLTEXCOORD4SVPROC)(const GLshort* v); +GLAPI PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; +#define glTexCoord4sv glad_glTexCoord4sv +typedef void (APIENTRYP PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); +GLAPI PFNGLVERTEX2DPROC glad_glVertex2d; +#define glVertex2d glad_glVertex2d +typedef void (APIENTRYP PFNGLVERTEX2DVPROC)(const GLdouble* v); +GLAPI PFNGLVERTEX2DVPROC glad_glVertex2dv; +#define glVertex2dv glad_glVertex2dv +typedef void (APIENTRYP PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); +GLAPI PFNGLVERTEX2FPROC glad_glVertex2f; +#define glVertex2f glad_glVertex2f +typedef void (APIENTRYP PFNGLVERTEX2FVPROC)(const GLfloat* v); +GLAPI PFNGLVERTEX2FVPROC glad_glVertex2fv; +#define glVertex2fv glad_glVertex2fv +typedef void (APIENTRYP PFNGLVERTEX2IPROC)(GLint x, GLint y); +GLAPI PFNGLVERTEX2IPROC glad_glVertex2i; +#define glVertex2i glad_glVertex2i +typedef void (APIENTRYP PFNGLVERTEX2IVPROC)(const GLint* v); +GLAPI PFNGLVERTEX2IVPROC glad_glVertex2iv; +#define glVertex2iv glad_glVertex2iv +typedef void (APIENTRYP PFNGLVERTEX2SPROC)(GLshort x, GLshort y); +GLAPI PFNGLVERTEX2SPROC glad_glVertex2s; +#define glVertex2s glad_glVertex2s +typedef void (APIENTRYP PFNGLVERTEX2SVPROC)(const GLshort* v); +GLAPI PFNGLVERTEX2SVPROC glad_glVertex2sv; +#define glVertex2sv glad_glVertex2sv +typedef void (APIENTRYP PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLVERTEX3DPROC glad_glVertex3d; +#define glVertex3d glad_glVertex3d +typedef void (APIENTRYP PFNGLVERTEX3DVPROC)(const GLdouble* v); +GLAPI PFNGLVERTEX3DVPROC glad_glVertex3dv; +#define glVertex3dv glad_glVertex3dv +typedef void (APIENTRYP PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLVERTEX3FPROC glad_glVertex3f; +#define glVertex3f glad_glVertex3f +typedef void (APIENTRYP PFNGLVERTEX3FVPROC)(const GLfloat* v); +GLAPI PFNGLVERTEX3FVPROC glad_glVertex3fv; +#define glVertex3fv glad_glVertex3fv +typedef void (APIENTRYP PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); +GLAPI PFNGLVERTEX3IPROC glad_glVertex3i; +#define glVertex3i glad_glVertex3i +typedef void (APIENTRYP PFNGLVERTEX3IVPROC)(const GLint* v); +GLAPI PFNGLVERTEX3IVPROC glad_glVertex3iv; +#define glVertex3iv glad_glVertex3iv +typedef void (APIENTRYP PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); +GLAPI PFNGLVERTEX3SPROC glad_glVertex3s; +#define glVertex3s glad_glVertex3s +typedef void (APIENTRYP PFNGLVERTEX3SVPROC)(const GLshort* v); +GLAPI PFNGLVERTEX3SVPROC glad_glVertex3sv; +#define glVertex3sv glad_glVertex3sv +typedef void (APIENTRYP PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI PFNGLVERTEX4DPROC glad_glVertex4d; +#define glVertex4d glad_glVertex4d +typedef void (APIENTRYP PFNGLVERTEX4DVPROC)(const GLdouble* v); +GLAPI PFNGLVERTEX4DVPROC glad_glVertex4dv; +#define glVertex4dv glad_glVertex4dv +typedef void (APIENTRYP PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI PFNGLVERTEX4FPROC glad_glVertex4f; +#define glVertex4f glad_glVertex4f +typedef void (APIENTRYP PFNGLVERTEX4FVPROC)(const GLfloat* v); +GLAPI PFNGLVERTEX4FVPROC glad_glVertex4fv; +#define glVertex4fv glad_glVertex4fv +typedef void (APIENTRYP PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); +GLAPI PFNGLVERTEX4IPROC glad_glVertex4i; +#define glVertex4i glad_glVertex4i +typedef void (APIENTRYP PFNGLVERTEX4IVPROC)(const GLint* v); +GLAPI PFNGLVERTEX4IVPROC glad_glVertex4iv; +#define glVertex4iv glad_glVertex4iv +typedef void (APIENTRYP PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI PFNGLVERTEX4SPROC glad_glVertex4s; +#define glVertex4s glad_glVertex4s +typedef void (APIENTRYP PFNGLVERTEX4SVPROC)(const GLshort* v); +GLAPI PFNGLVERTEX4SVPROC glad_glVertex4sv; +#define glVertex4sv glad_glVertex4sv +typedef void (APIENTRYP PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble* equation); +GLAPI PFNGLCLIPPLANEPROC glad_glClipPlane; +#define glClipPlane glad_glClipPlane +typedef void (APIENTRYP PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); +GLAPI PFNGLCOLORMATERIALPROC glad_glColorMaterial; +#define glColorMaterial glad_glColorMaterial +typedef void (APIENTRYP PFNGLFOGFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLFOGFPROC glad_glFogf; +#define glFogf glad_glFogf +typedef void (APIENTRYP PFNGLFOGFVPROC)(GLenum pname, const GLfloat* params); +GLAPI PFNGLFOGFVPROC glad_glFogfv; +#define glFogfv glad_glFogfv +typedef void (APIENTRYP PFNGLFOGIPROC)(GLenum pname, GLint param); +GLAPI PFNGLFOGIPROC glad_glFogi; +#define glFogi glad_glFogi +typedef void (APIENTRYP PFNGLFOGIVPROC)(GLenum pname, const GLint* params); +GLAPI PFNGLFOGIVPROC glad_glFogiv; +#define glFogiv glad_glFogiv +typedef void (APIENTRYP PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); +GLAPI PFNGLLIGHTFPROC glad_glLightf; +#define glLightf glad_glLightf +typedef void (APIENTRYP PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat* params); +GLAPI PFNGLLIGHTFVPROC glad_glLightfv; +#define glLightfv glad_glLightfv +typedef void (APIENTRYP PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); +GLAPI PFNGLLIGHTIPROC glad_glLighti; +#define glLighti glad_glLighti +typedef void (APIENTRYP PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint* params); +GLAPI PFNGLLIGHTIVPROC glad_glLightiv; +#define glLightiv glad_glLightiv +typedef void (APIENTRYP PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLLIGHTMODELFPROC glad_glLightModelf; +#define glLightModelf glad_glLightModelf +typedef void (APIENTRYP PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat* params); +GLAPI PFNGLLIGHTMODELFVPROC glad_glLightModelfv; +#define glLightModelfv glad_glLightModelfv +typedef void (APIENTRYP PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); +GLAPI PFNGLLIGHTMODELIPROC glad_glLightModeli; +#define glLightModeli glad_glLightModeli +typedef void (APIENTRYP PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint* params); +GLAPI PFNGLLIGHTMODELIVPROC glad_glLightModeliv; +#define glLightModeliv glad_glLightModeliv +typedef void (APIENTRYP PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); +GLAPI PFNGLLINESTIPPLEPROC glad_glLineStipple; +#define glLineStipple glad_glLineStipple +typedef void (APIENTRYP PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); +GLAPI PFNGLMATERIALFPROC glad_glMaterialf; +#define glMaterialf glad_glMaterialf +typedef void (APIENTRYP PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat* params); +GLAPI PFNGLMATERIALFVPROC glad_glMaterialfv; +#define glMaterialfv glad_glMaterialfv +typedef void (APIENTRYP PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); +GLAPI PFNGLMATERIALIPROC glad_glMateriali; +#define glMateriali glad_glMateriali +typedef void (APIENTRYP PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint* params); +GLAPI PFNGLMATERIALIVPROC glad_glMaterialiv; +#define glMaterialiv glad_glMaterialiv +typedef void (APIENTRYP PFNGLPOLYGONSTIPPLEPROC)(const GLubyte* mask); +GLAPI PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; +#define glPolygonStipple glad_glPolygonStipple +typedef void (APIENTRYP PFNGLSHADEMODELPROC)(GLenum mode); +GLAPI PFNGLSHADEMODELPROC glad_glShadeModel; +#define glShadeModel glad_glShadeModel +typedef void (APIENTRYP PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); +GLAPI PFNGLTEXENVFPROC glad_glTexEnvf; +#define glTexEnvf glad_glTexEnvf +typedef void (APIENTRYP PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat* params); +GLAPI PFNGLTEXENVFVPROC glad_glTexEnvfv; +#define glTexEnvfv glad_glTexEnvfv +typedef void (APIENTRYP PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); +GLAPI PFNGLTEXENVIPROC glad_glTexEnvi; +#define glTexEnvi glad_glTexEnvi +typedef void (APIENTRYP PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint* params); +GLAPI PFNGLTEXENVIVPROC glad_glTexEnviv; +#define glTexEnviv glad_glTexEnviv +typedef void (APIENTRYP PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); +GLAPI PFNGLTEXGENDPROC glad_glTexGend; +#define glTexGend glad_glTexGend +typedef void (APIENTRYP PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble* params); +GLAPI PFNGLTEXGENDVPROC glad_glTexGendv; +#define glTexGendv glad_glTexGendv +typedef void (APIENTRYP PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); +GLAPI PFNGLTEXGENFPROC glad_glTexGenf; +#define glTexGenf glad_glTexGenf +typedef void (APIENTRYP PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat* params); +GLAPI PFNGLTEXGENFVPROC glad_glTexGenfv; +#define glTexGenfv glad_glTexGenfv +typedef void (APIENTRYP PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); +GLAPI PFNGLTEXGENIPROC glad_glTexGeni; +#define glTexGeni glad_glTexGeni +typedef void (APIENTRYP PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint* params); +GLAPI PFNGLTEXGENIVPROC glad_glTexGeniv; +#define glTexGeniv glad_glTexGeniv +typedef void (APIENTRYP PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat* buffer); +GLAPI PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; +#define glFeedbackBuffer glad_glFeedbackBuffer +typedef void (APIENTRYP PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint* buffer); +GLAPI PFNGLSELECTBUFFERPROC glad_glSelectBuffer; +#define glSelectBuffer glad_glSelectBuffer +typedef GLint (APIENTRYP PFNGLRENDERMODEPROC)(GLenum mode); +GLAPI PFNGLRENDERMODEPROC glad_glRenderMode; +#define glRenderMode glad_glRenderMode +typedef void (APIENTRYP PFNGLINITNAMESPROC)(); +GLAPI PFNGLINITNAMESPROC glad_glInitNames; +#define glInitNames glad_glInitNames +typedef void (APIENTRYP PFNGLLOADNAMEPROC)(GLuint name); +GLAPI PFNGLLOADNAMEPROC glad_glLoadName; +#define glLoadName glad_glLoadName +typedef void (APIENTRYP PFNGLPASSTHROUGHPROC)(GLfloat token); +GLAPI PFNGLPASSTHROUGHPROC glad_glPassThrough; +#define glPassThrough glad_glPassThrough +typedef void (APIENTRYP PFNGLPOPNAMEPROC)(); +GLAPI PFNGLPOPNAMEPROC glad_glPopName; +#define glPopName glad_glPopName +typedef void (APIENTRYP PFNGLPUSHNAMEPROC)(GLuint name); +GLAPI PFNGLPUSHNAMEPROC glad_glPushName; +#define glPushName glad_glPushName +typedef void (APIENTRYP PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLCLEARACCUMPROC glad_glClearAccum; +#define glClearAccum glad_glClearAccum +typedef void (APIENTRYP PFNGLCLEARINDEXPROC)(GLfloat c); +GLAPI PFNGLCLEARINDEXPROC glad_glClearIndex; +#define glClearIndex glad_glClearIndex +typedef void (APIENTRYP PFNGLINDEXMASKPROC)(GLuint mask); +GLAPI PFNGLINDEXMASKPROC glad_glIndexMask; +#define glIndexMask glad_glIndexMask +typedef void (APIENTRYP PFNGLACCUMPROC)(GLenum op, GLfloat value); +GLAPI PFNGLACCUMPROC glad_glAccum; +#define glAccum glad_glAccum +typedef void (APIENTRYP PFNGLPOPATTRIBPROC)(); +GLAPI PFNGLPOPATTRIBPROC glad_glPopAttrib; +#define glPopAttrib glad_glPopAttrib +typedef void (APIENTRYP PFNGLPUSHATTRIBPROC)(GLbitfield mask); +GLAPI PFNGLPUSHATTRIBPROC glad_glPushAttrib; +#define glPushAttrib glad_glPushAttrib +typedef void (APIENTRYP PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); +GLAPI PFNGLMAP1DPROC glad_glMap1d; +#define glMap1d glad_glMap1d +typedef void (APIENTRYP PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); +GLAPI PFNGLMAP1FPROC glad_glMap1f; +#define glMap1f glad_glMap1f +typedef void (APIENTRYP PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); +GLAPI PFNGLMAP2DPROC glad_glMap2d; +#define glMap2d glad_glMap2d +typedef void (APIENTRYP PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); +GLAPI PFNGLMAP2FPROC glad_glMap2f; +#define glMap2f glad_glMap2f +typedef void (APIENTRYP PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); +GLAPI PFNGLMAPGRID1DPROC glad_glMapGrid1d; +#define glMapGrid1d glad_glMapGrid1d +typedef void (APIENTRYP PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); +GLAPI PFNGLMAPGRID1FPROC glad_glMapGrid1f; +#define glMapGrid1f glad_glMapGrid1f +typedef void (APIENTRYP PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +GLAPI PFNGLMAPGRID2DPROC glad_glMapGrid2d; +#define glMapGrid2d glad_glMapGrid2d +typedef void (APIENTRYP PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +GLAPI PFNGLMAPGRID2FPROC glad_glMapGrid2f; +#define glMapGrid2f glad_glMapGrid2f +typedef void (APIENTRYP PFNGLEVALCOORD1DPROC)(GLdouble u); +GLAPI PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; +#define glEvalCoord1d glad_glEvalCoord1d +typedef void (APIENTRYP PFNGLEVALCOORD1DVPROC)(const GLdouble* u); +GLAPI PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; +#define glEvalCoord1dv glad_glEvalCoord1dv +typedef void (APIENTRYP PFNGLEVALCOORD1FPROC)(GLfloat u); +GLAPI PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; +#define glEvalCoord1f glad_glEvalCoord1f +typedef void (APIENTRYP PFNGLEVALCOORD1FVPROC)(const GLfloat* u); +GLAPI PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; +#define glEvalCoord1fv glad_glEvalCoord1fv +typedef void (APIENTRYP PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); +GLAPI PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; +#define glEvalCoord2d glad_glEvalCoord2d +typedef void (APIENTRYP PFNGLEVALCOORD2DVPROC)(const GLdouble* u); +GLAPI PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; +#define glEvalCoord2dv glad_glEvalCoord2dv +typedef void (APIENTRYP PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); +GLAPI PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; +#define glEvalCoord2f glad_glEvalCoord2f +typedef void (APIENTRYP PFNGLEVALCOORD2FVPROC)(const GLfloat* u); +GLAPI PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; +#define glEvalCoord2fv glad_glEvalCoord2fv +typedef void (APIENTRYP PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); +GLAPI PFNGLEVALMESH1PROC glad_glEvalMesh1; +#define glEvalMesh1 glad_glEvalMesh1 +typedef void (APIENTRYP PFNGLEVALPOINT1PROC)(GLint i); +GLAPI PFNGLEVALPOINT1PROC glad_glEvalPoint1; +#define glEvalPoint1 glad_glEvalPoint1 +typedef void (APIENTRYP PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +GLAPI PFNGLEVALMESH2PROC glad_glEvalMesh2; +#define glEvalMesh2 glad_glEvalMesh2 +typedef void (APIENTRYP PFNGLEVALPOINT2PROC)(GLint i, GLint j); +GLAPI PFNGLEVALPOINT2PROC glad_glEvalPoint2; +#define glEvalPoint2 glad_glEvalPoint2 +typedef void (APIENTRYP PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); +GLAPI PFNGLALPHAFUNCPROC glad_glAlphaFunc; +#define glAlphaFunc glad_glAlphaFunc +typedef void (APIENTRYP PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); +GLAPI PFNGLPIXELZOOMPROC glad_glPixelZoom; +#define glPixelZoom glad_glPixelZoom +typedef void (APIENTRYP PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; +#define glPixelTransferf glad_glPixelTransferf +typedef void (APIENTRYP PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); +GLAPI PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; +#define glPixelTransferi glad_glPixelTransferi +typedef void (APIENTRYP PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat* values); +GLAPI PFNGLPIXELMAPFVPROC glad_glPixelMapfv; +#define glPixelMapfv glad_glPixelMapfv +typedef void (APIENTRYP PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint* values); +GLAPI PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; +#define glPixelMapuiv glad_glPixelMapuiv +typedef void (APIENTRYP PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort* values); +GLAPI PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; +#define glPixelMapusv glad_glPixelMapusv +typedef void (APIENTRYP PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +GLAPI PFNGLCOPYPIXELSPROC glad_glCopyPixels; +#define glCopyPixels glad_glCopyPixels +typedef void (APIENTRYP PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLDRAWPIXELSPROC glad_glDrawPixels; +#define glDrawPixels glad_glDrawPixels +typedef void (APIENTRYP PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble* equation); +GLAPI PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; +#define glGetClipPlane glad_glGetClipPlane +typedef void (APIENTRYP PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat* params); +GLAPI PFNGLGETLIGHTFVPROC glad_glGetLightfv; +#define glGetLightfv glad_glGetLightfv +typedef void (APIENTRYP PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint* params); +GLAPI PFNGLGETLIGHTIVPROC glad_glGetLightiv; +#define glGetLightiv glad_glGetLightiv +typedef void (APIENTRYP PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble* v); +GLAPI PFNGLGETMAPDVPROC glad_glGetMapdv; +#define glGetMapdv glad_glGetMapdv +typedef void (APIENTRYP PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat* v); +GLAPI PFNGLGETMAPFVPROC glad_glGetMapfv; +#define glGetMapfv glad_glGetMapfv +typedef void (APIENTRYP PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint* v); +GLAPI PFNGLGETMAPIVPROC glad_glGetMapiv; +#define glGetMapiv glad_glGetMapiv +typedef void (APIENTRYP PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat* params); +GLAPI PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; +#define glGetMaterialfv glad_glGetMaterialfv +typedef void (APIENTRYP PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint* params); +GLAPI PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; +#define glGetMaterialiv glad_glGetMaterialiv +typedef void (APIENTRYP PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat* values); +GLAPI PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; +#define glGetPixelMapfv glad_glGetPixelMapfv +typedef void (APIENTRYP PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint* values); +GLAPI PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; +#define glGetPixelMapuiv glad_glGetPixelMapuiv +typedef void (APIENTRYP PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort* values); +GLAPI PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; +#define glGetPixelMapusv glad_glGetPixelMapusv +typedef void (APIENTRYP PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte* mask); +GLAPI PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; +#define glGetPolygonStipple glad_glGetPolygonStipple +typedef void (APIENTRYP PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat* params); +GLAPI PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; +#define glGetTexEnvfv glad_glGetTexEnvfv +typedef void (APIENTRYP PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint* params); +GLAPI PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; +#define glGetTexEnviv glad_glGetTexEnviv +typedef void (APIENTRYP PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble* params); +GLAPI PFNGLGETTEXGENDVPROC glad_glGetTexGendv; +#define glGetTexGendv glad_glGetTexGendv +typedef void (APIENTRYP PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat* params); +GLAPI PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; +#define glGetTexGenfv glad_glGetTexGenfv +typedef void (APIENTRYP PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint* params); +GLAPI PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; +#define glGetTexGeniv glad_glGetTexGeniv +typedef GLboolean (APIENTRYP PFNGLISLISTPROC)(GLuint list); +GLAPI PFNGLISLISTPROC glad_glIsList; +#define glIsList glad_glIsList +typedef void (APIENTRYP PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI PFNGLFRUSTUMPROC glad_glFrustum; +#define glFrustum glad_glFrustum +typedef void (APIENTRYP PFNGLLOADIDENTITYPROC)(); +GLAPI PFNGLLOADIDENTITYPROC glad_glLoadIdentity; +#define glLoadIdentity glad_glLoadIdentity +typedef void (APIENTRYP PFNGLLOADMATRIXFPROC)(const GLfloat* m); +GLAPI PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; +#define glLoadMatrixf glad_glLoadMatrixf +typedef void (APIENTRYP PFNGLLOADMATRIXDPROC)(const GLdouble* m); +GLAPI PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; +#define glLoadMatrixd glad_glLoadMatrixd +typedef void (APIENTRYP PFNGLMATRIXMODEPROC)(GLenum mode); +GLAPI PFNGLMATRIXMODEPROC glad_glMatrixMode; +#define glMatrixMode glad_glMatrixMode +typedef void (APIENTRYP PFNGLMULTMATRIXFPROC)(const GLfloat* m); +GLAPI PFNGLMULTMATRIXFPROC glad_glMultMatrixf; +#define glMultMatrixf glad_glMultMatrixf +typedef void (APIENTRYP PFNGLMULTMATRIXDPROC)(const GLdouble* m); +GLAPI PFNGLMULTMATRIXDPROC glad_glMultMatrixd; +#define glMultMatrixd glad_glMultMatrixd +typedef void (APIENTRYP PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLAPI PFNGLORTHOPROC glad_glOrtho; +#define glOrtho glad_glOrtho +typedef void (APIENTRYP PFNGLPOPMATRIXPROC)(); +GLAPI PFNGLPOPMATRIXPROC glad_glPopMatrix; +#define glPopMatrix glad_glPopMatrix +typedef void (APIENTRYP PFNGLPUSHMATRIXPROC)(); +GLAPI PFNGLPUSHMATRIXPROC glad_glPushMatrix; +#define glPushMatrix glad_glPushMatrix +typedef void (APIENTRYP PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLROTATEDPROC glad_glRotated; +#define glRotated glad_glRotated +typedef void (APIENTRYP PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLROTATEFPROC glad_glRotatef; +#define glRotatef glad_glRotatef +typedef void (APIENTRYP PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLSCALEDPROC glad_glScaled; +#define glScaled glad_glScaled +typedef void (APIENTRYP PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLSCALEFPROC glad_glScalef; +#define glScalef glad_glScalef +typedef void (APIENTRYP PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLTRANSLATEDPROC glad_glTranslated; +#define glTranslated glad_glTranslated +typedef void (APIENTRYP PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLTRANSLATEFPROC glad_glTranslatef; +#define glTranslatef glad_glTranslatef +#endif +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 +GLAPI int GLAD_GL_VERSION_1_1; +typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices); +GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void** params); +GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv; +#define glGetPointerv glad_glGetPointerv +typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); +GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; +#define glCopyTexImage1D glad_glCopyTexImage1D +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; +#define glCopyTexSubImage1D glad_glCopyTexSubImage1D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; +#define glTexSubImage1D glad_glTexSubImage1D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint* textures); +GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint* textures); +GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture); +GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +typedef void (APIENTRYP PFNGLARRAYELEMENTPROC)(GLint i); +GLAPI PFNGLARRAYELEMENTPROC glad_glArrayElement; +#define glArrayElement glad_glArrayElement +typedef void (APIENTRYP PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLCOLORPOINTERPROC glad_glColorPointer; +#define glColorPointer glad_glColorPointer +typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEPROC)(GLenum array); +GLAPI PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; +#define glDisableClientState glad_glDisableClientState +typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void* pointer); +GLAPI PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; +#define glEdgeFlagPointer glad_glEdgeFlagPointer +typedef void (APIENTRYP PFNGLENABLECLIENTSTATEPROC)(GLenum array); +GLAPI PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; +#define glEnableClientState glad_glEnableClientState +typedef void (APIENTRYP PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLINDEXPOINTERPROC glad_glIndexPointer; +#define glIndexPointer glad_glIndexPointer +typedef void (APIENTRYP PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void* pointer); +GLAPI PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; +#define glInterleavedArrays glad_glInterleavedArrays +typedef void (APIENTRYP PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLNORMALPOINTERPROC glad_glNormalPointer; +#define glNormalPointer glad_glNormalPointer +typedef void (APIENTRYP PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; +#define glTexCoordPointer glad_glTexCoordPointer +typedef void (APIENTRYP PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLVERTEXPOINTERPROC glad_glVertexPointer; +#define glVertexPointer glad_glVertexPointer +typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint* textures, GLboolean* residences); +GLAPI PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; +#define glAreTexturesResident glad_glAreTexturesResident +typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint* textures, const GLfloat* priorities); +GLAPI PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; +#define glPrioritizeTextures glad_glPrioritizeTextures +typedef void (APIENTRYP PFNGLINDEXUBPROC)(GLubyte c); +GLAPI PFNGLINDEXUBPROC glad_glIndexub; +#define glIndexub glad_glIndexub +typedef void (APIENTRYP PFNGLINDEXUBVPROC)(const GLubyte* c); +GLAPI PFNGLINDEXUBVPROC glad_glIndexubv; +#define glIndexubv glad_glIndexubv +typedef void (APIENTRYP PFNGLPOPCLIENTATTRIBPROC)(); +GLAPI PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; +#define glPopClientAttrib glad_glPopClientAttrib +typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); +GLAPI PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; +#define glPushClientAttrib glad_glPushClientAttrib +#endif +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +GLAPI int GLAD_GL_VERSION_1_2; +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); +GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels); +GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +#endif +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +GLAPI int GLAD_GL_VERSION_1_3; +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture); +GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data); +GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; +#define glCompressedTexImage2D glad_glCompressedTexImage2D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data); +GLAPI PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; +#define glCompressedTexImage1D glad_glCompressedTexImage1D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data); +GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; +#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void* img); +GLAPI PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; +#define glGetCompressedTexImage glad_glGetCompressedTexImage +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); +GLAPI PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; +#define glClientActiveTexture glad_glClientActiveTexture +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); +GLAPI PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; +#define glMultiTexCoord1d glad_glMultiTexCoord1d +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble* v); +GLAPI PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; +#define glMultiTexCoord1dv glad_glMultiTexCoord1dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); +GLAPI PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; +#define glMultiTexCoord1f glad_glMultiTexCoord1f +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat* v); +GLAPI PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; +#define glMultiTexCoord1fv glad_glMultiTexCoord1fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); +GLAPI PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; +#define glMultiTexCoord1i glad_glMultiTexCoord1i +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint* v); +GLAPI PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; +#define glMultiTexCoord1iv glad_glMultiTexCoord1iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); +GLAPI PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; +#define glMultiTexCoord1s glad_glMultiTexCoord1s +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort* v); +GLAPI PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; +#define glMultiTexCoord1sv glad_glMultiTexCoord1sv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); +GLAPI PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; +#define glMultiTexCoord2d glad_glMultiTexCoord2d +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble* v); +GLAPI PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; +#define glMultiTexCoord2dv glad_glMultiTexCoord2dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); +GLAPI PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; +#define glMultiTexCoord2f glad_glMultiTexCoord2f +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat* v); +GLAPI PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; +#define glMultiTexCoord2fv glad_glMultiTexCoord2fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); +GLAPI PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; +#define glMultiTexCoord2i glad_glMultiTexCoord2i +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint* v); +GLAPI PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; +#define glMultiTexCoord2iv glad_glMultiTexCoord2iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); +GLAPI PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; +#define glMultiTexCoord2s glad_glMultiTexCoord2s +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort* v); +GLAPI PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; +#define glMultiTexCoord2sv glad_glMultiTexCoord2sv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; +#define glMultiTexCoord3d glad_glMultiTexCoord3d +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble* v); +GLAPI PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; +#define glMultiTexCoord3dv glad_glMultiTexCoord3dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; +#define glMultiTexCoord3f glad_glMultiTexCoord3f +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat* v); +GLAPI PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; +#define glMultiTexCoord3fv glad_glMultiTexCoord3fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); +GLAPI PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; +#define glMultiTexCoord3i glad_glMultiTexCoord3i +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint* v); +GLAPI PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; +#define glMultiTexCoord3iv glad_glMultiTexCoord3iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; +#define glMultiTexCoord3s glad_glMultiTexCoord3s +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort* v); +GLAPI PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; +#define glMultiTexCoord3sv glad_glMultiTexCoord3sv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; +#define glMultiTexCoord4d glad_glMultiTexCoord4d +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble* v); +GLAPI PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; +#define glMultiTexCoord4dv glad_glMultiTexCoord4dv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; +#define glMultiTexCoord4f glad_glMultiTexCoord4f +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat* v); +GLAPI PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; +#define glMultiTexCoord4fv glad_glMultiTexCoord4fv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; +#define glMultiTexCoord4i glad_glMultiTexCoord4i +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint* v); +GLAPI PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; +#define glMultiTexCoord4iv glad_glMultiTexCoord4iv +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; +#define glMultiTexCoord4s glad_glMultiTexCoord4s +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort* v); +GLAPI PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; +#define glMultiTexCoord4sv glad_glMultiTexCoord4sv +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat* m); +GLAPI PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; +#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf +typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble* m); +GLAPI PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; +#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat* m); +GLAPI PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; +#define glMultTransposeMatrixf glad_glMultTransposeMatrixf +typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble* m); +GLAPI PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; +#define glMultTransposeMatrixd glad_glMultTransposeMatrixd +#endif +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +GLAPI int GLAD_GL_VERSION_1_4; +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; +#define glBlendFuncSeparate glad_glBlendFuncSeparate +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint* first, const GLsizei* count, GLsizei drawcount); +GLAPI PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; +#define glMultiDrawArrays glad_glMultiDrawArrays +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei* count, GLenum type, const void** indices, GLsizei drawcount); +GLAPI PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; +#define glMultiDrawElements glad_glMultiDrawElements +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +GLAPI PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; +#define glPointParameterf glad_glPointParameterf +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat* params); +GLAPI PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; +#define glPointParameterfv glad_glPointParameterfv +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +GLAPI PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; +#define glPointParameteri glad_glPointParameteri +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint* params); +GLAPI PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; +#define glPointParameteriv glad_glPointParameteriv +typedef void (APIENTRYP PFNGLFOGCOORDFPROC)(GLfloat coord); +GLAPI PFNGLFOGCOORDFPROC glad_glFogCoordf; +#define glFogCoordf glad_glFogCoordf +typedef void (APIENTRYP PFNGLFOGCOORDFVPROC)(const GLfloat* coord); +GLAPI PFNGLFOGCOORDFVPROC glad_glFogCoordfv; +#define glFogCoordfv glad_glFogCoordfv +typedef void (APIENTRYP PFNGLFOGCOORDDPROC)(GLdouble coord); +GLAPI PFNGLFOGCOORDDPROC glad_glFogCoordd; +#define glFogCoordd glad_glFogCoordd +typedef void (APIENTRYP PFNGLFOGCOORDDVPROC)(const GLdouble* coord); +GLAPI PFNGLFOGCOORDDVPROC glad_glFogCoorddv; +#define glFogCoorddv glad_glFogCoorddv +typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; +#define glFogCoordPointer glad_glFogCoordPointer +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); +GLAPI PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; +#define glSecondaryColor3b glad_glSecondaryColor3b +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte* v); +GLAPI PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; +#define glSecondaryColor3bv glad_glSecondaryColor3bv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); +GLAPI PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; +#define glSecondaryColor3d glad_glSecondaryColor3d +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble* v); +GLAPI PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; +#define glSecondaryColor3dv glad_glSecondaryColor3dv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); +GLAPI PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; +#define glSecondaryColor3f glad_glSecondaryColor3f +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat* v); +GLAPI PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; +#define glSecondaryColor3fv glad_glSecondaryColor3fv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); +GLAPI PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; +#define glSecondaryColor3i glad_glSecondaryColor3i +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC)(const GLint* v); +GLAPI PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; +#define glSecondaryColor3iv glad_glSecondaryColor3iv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); +GLAPI PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; +#define glSecondaryColor3s glad_glSecondaryColor3s +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC)(const GLshort* v); +GLAPI PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; +#define glSecondaryColor3sv glad_glSecondaryColor3sv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); +GLAPI PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; +#define glSecondaryColor3ub glad_glSecondaryColor3ub +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte* v); +GLAPI PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; +#define glSecondaryColor3ubv glad_glSecondaryColor3ubv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); +GLAPI PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; +#define glSecondaryColor3ui glad_glSecondaryColor3ui +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint* v); +GLAPI PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; +#define glSecondaryColor3uiv glad_glSecondaryColor3uiv +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); +GLAPI PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; +#define glSecondaryColor3us glad_glSecondaryColor3us +typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC)(const GLushort* v); +GLAPI PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; +#define glSecondaryColor3usv glad_glSecondaryColor3usv +typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; +#define glSecondaryColorPointer glad_glSecondaryColorPointer +typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); +GLAPI PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; +#define glWindowPos2d glad_glWindowPos2d +typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC)(const GLdouble* v); +GLAPI PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; +#define glWindowPos2dv glad_glWindowPos2dv +typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); +GLAPI PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; +#define glWindowPos2f glad_glWindowPos2f +typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC)(const GLfloat* v); +GLAPI PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; +#define glWindowPos2fv glad_glWindowPos2fv +typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); +GLAPI PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; +#define glWindowPos2i glad_glWindowPos2i +typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC)(const GLint* v); +GLAPI PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; +#define glWindowPos2iv glad_glWindowPos2iv +typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); +GLAPI PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; +#define glWindowPos2s glad_glWindowPos2s +typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC)(const GLshort* v); +GLAPI PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; +#define glWindowPos2sv glad_glWindowPos2sv +typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; +#define glWindowPos3d glad_glWindowPos3d +typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC)(const GLdouble* v); +GLAPI PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; +#define glWindowPos3dv glad_glWindowPos3dv +typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; +#define glWindowPos3f glad_glWindowPos3f +typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC)(const GLfloat* v); +GLAPI PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; +#define glWindowPos3fv glad_glWindowPos3fv +typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); +GLAPI PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; +#define glWindowPos3i glad_glWindowPos3i +typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC)(const GLint* v); +GLAPI PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; +#define glWindowPos3iv glad_glWindowPos3iv +typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); +GLAPI PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; +#define glWindowPos3s glad_glWindowPos3s +typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC)(const GLshort* v); +GLAPI PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; +#define glWindowPos3sv glad_glWindowPos3sv +typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; +#define glBlendColor glad_glBlendColor +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode); +GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; +#define glBlendEquation glad_glBlendEquation +#endif +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +GLAPI int GLAD_GL_VERSION_1_5; +typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei n, GLuint* ids); +GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint* ids); +GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint id); +GLAPI PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum target); +GLAPI PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint* params); +GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint* params); +GLAPI PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; +#define glGetQueryObjectiv glad_glGetQueryObjectiv +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint* params); +GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); +GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint* buffers); +GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; +#define glDeleteBuffers glad_glDeleteBuffers +typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint* buffers); +GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; +#define glGenBuffers glad_glGenBuffers +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint buffer); +GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; +#define glIsBuffer glad_glIsBuffer +typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void* data, GLenum usage); +GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; +#define glBufferData glad_glBufferData +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data); +GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; +#define glBufferSubData glad_glBufferSubData +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void* data); +GLAPI PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; +#define glGetBufferSubData glad_glGetBufferSubData +typedef void* (APIENTRYP PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); +GLAPI PFNGLMAPBUFFERPROC glad_glMapBuffer; +#define glMapBuffer glad_glMapBuffer +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum target); +GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params); +GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void** params); +GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +#endif +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +GLAPI int GLAD_GL_VERSION_2_0; +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); +GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; +#define glBlendEquationSeparate glad_glBlendEquationSeparate +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum* bufs); +GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; +#define glStencilOpSeparate glad_glStencilOpSeparate +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); +GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; +#define glStencilFuncSeparate glad_glStencilFuncSeparate +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); +GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; +#define glStencilMaskSeparate glad_glStencilMaskSeparate +typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar* name); +GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader); +GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; +#define glCompileShader glad_glCompileShader +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(); +GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum type); +GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program); +GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; +#define glDeleteProgram glad_glDeleteProgram +typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader); +GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); +GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; +#define glDetachShader glad_glDetachShader +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); +GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; +#define glDisableVertexAttribArray glad_glDisableVertexAttribArray +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; +#define glGetActiveAttrib glad_glGetActiveAttrib +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; +#define glGetActiveUniform glad_glGetActiveUniform +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); +GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar* name); +GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint* params); +GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint* params); +GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; +#define glGetShaderiv glad_glGetShaderiv +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; +#define glGetShaderInfoLog glad_glGetShaderInfoLog +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source); +GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; +#define glGetShaderSource glad_glGetShaderSource +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar* name); +GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; +#define glGetUniformLocation glad_glGetUniformLocation +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat* params); +GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; +#define glGetUniformfv glad_glGetUniformfv +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint* params); +GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; +#define glGetUniformiv glad_glGetUniformiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble* params); +GLAPI PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; +#define glGetVertexAttribdv glad_glGetVertexAttribdv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat* params); +GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; +#define glGetVertexAttribfv glad_glGetVertexAttribfv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint* params); +GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; +#define glGetVertexAttribiv glad_glGetVertexAttribiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void** pointer); +GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; +#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint program); +GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; +#define glIsProgram glad_glIsProgram +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint shader); +GLAPI PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program); +GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length); +GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; +#define glShaderSource glad_glShaderSource +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program); +GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); +GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; +#define glUniform1f glad_glUniform1f +typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); +GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; +#define glUniform2f glad_glUniform2f +typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; +#define glUniform3f glad_glUniform3f +typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; +#define glUniform4f glad_glUniform4f +typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0); +GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; +#define glUniform1i glad_glUniform1i +typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); +GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; +#define glUniform2i glad_glUniform2i +typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); +GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; +#define glUniform3i glad_glUniform3i +typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; +#define glUniform4i glad_glUniform4i +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat* value); +GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; +#define glUniform1fv glad_glUniform1fv +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat* value); +GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; +#define glUniform2fv glad_glUniform2fv +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat* value); +GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; +#define glUniform3fv glad_glUniform3fv +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat* value); +GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; +#define glUniform4fv glad_glUniform4fv +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint* value); +GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; +#define glUniform1iv glad_glUniform1iv +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint* value); +GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; +#define glUniform2iv glad_glUniform2iv +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint* value); +GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; +#define glUniform3iv glad_glUniform3iv +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint* value); +GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; +#define glUniform4iv glad_glUniform4iv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint program); +GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); +GLAPI PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; +#define glVertexAttrib1d glad_glVertexAttrib1d +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble* v); +GLAPI PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; +#define glVertexAttrib1dv glad_glVertexAttrib1dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); +GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; +#define glVertexAttrib1f glad_glVertexAttrib1f +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat* v); +GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; +#define glVertexAttrib1fv glad_glVertexAttrib1fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); +GLAPI PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; +#define glVertexAttrib1s glad_glVertexAttrib1s +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort* v); +GLAPI PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; +#define glVertexAttrib1sv glad_glVertexAttrib1sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); +GLAPI PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; +#define glVertexAttrib2d glad_glVertexAttrib2d +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble* v); +GLAPI PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; +#define glVertexAttrib2dv glad_glVertexAttrib2dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); +GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; +#define glVertexAttrib2f glad_glVertexAttrib2f +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat* v); +GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; +#define glVertexAttrib2fv glad_glVertexAttrib2fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); +GLAPI PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; +#define glVertexAttrib2s glad_glVertexAttrib2s +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort* v); +GLAPI PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; +#define glVertexAttrib2sv glad_glVertexAttrib2sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; +#define glVertexAttrib3d glad_glVertexAttrib3d +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble* v); +GLAPI PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; +#define glVertexAttrib3dv glad_glVertexAttrib3dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; +#define glVertexAttrib3f glad_glVertexAttrib3f +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat* v); +GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; +#define glVertexAttrib3fv glad_glVertexAttrib3fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; +#define glVertexAttrib3s glad_glVertexAttrib3s +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort* v); +GLAPI PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; +#define glVertexAttrib3sv glad_glVertexAttrib3sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte* v); +GLAPI PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; +#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint* v); +GLAPI PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; +#define glVertexAttrib4Niv glad_glVertexAttrib4Niv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort* v); +GLAPI PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; +#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; +#define glVertexAttrib4Nub glad_glVertexAttrib4Nub +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte* v); +GLAPI PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; +#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint* v); +GLAPI PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; +#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort* v); +GLAPI PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; +#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte* v); +GLAPI PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; +#define glVertexAttrib4bv glad_glVertexAttrib4bv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; +#define glVertexAttrib4d glad_glVertexAttrib4d +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble* v); +GLAPI PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; +#define glVertexAttrib4dv glad_glVertexAttrib4dv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; +#define glVertexAttrib4f glad_glVertexAttrib4f +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat* v); +GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; +#define glVertexAttrib4fv glad_glVertexAttrib4fv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint* v); +GLAPI PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; +#define glVertexAttrib4iv glad_glVertexAttrib4iv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; +#define glVertexAttrib4s glad_glVertexAttrib4s +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort* v); +GLAPI PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; +#define glVertexAttrib4sv glad_glVertexAttrib4sv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte* v); +GLAPI PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; +#define glVertexAttrib4ubv glad_glVertexAttrib4ubv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint* v); +GLAPI PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; +#define glVertexAttrib4uiv glad_glVertexAttrib4uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort* v); +GLAPI PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; +#define glVertexAttrib4usv glad_glVertexAttrib4usv +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); +GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +#endif +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +GLAPI int GLAD_GL_VERSION_2_1; +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +#endif +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +GLAPI int GLAD_GL_VERSION_3_0; +typedef void (APIENTRYP PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI PFNGLCOLORMASKIPROC glad_glColorMaski; +#define glColorMaski glad_glColorMaski +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean* data); +GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint* data); +GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +typedef void (APIENTRYP PFNGLENABLEIPROC)(GLenum target, GLuint index); +GLAPI PFNGLENABLEIPROC glad_glEnablei; +#define glEnablei glad_glEnablei +typedef void (APIENTRYP PFNGLDISABLEIPROC)(GLenum target, GLuint index); +GLAPI PFNGLDISABLEIPROC glad_glDisablei; +#define glDisablei glad_glDisablei +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC)(GLenum target, GLuint index); +GLAPI PFNGLISENABLEDIPROC glad_glIsEnabledi; +#define glIsEnabledi glad_glIsEnabledi +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(); +GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar** varyings, GLenum bufferMode); +GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); +GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); +GLAPI PFNGLCLAMPCOLORPROC glad_glClampColor; +#define glClampColor glad_glClampColor +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); +GLAPI PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; +#define glBeginConditionalRender glad_glBeginConditionalRender +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC)(); +GLAPI PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; +#define glEndConditionalRender glad_glEndConditionalRender +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer); +GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint* params); +GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint* params); +GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); +GLAPI PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; +#define glVertexAttribI1i glad_glVertexAttribI1i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); +GLAPI PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; +#define glVertexAttribI2i glad_glVertexAttribI2i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); +GLAPI PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; +#define glVertexAttribI3i glad_glVertexAttribI3i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); +GLAPI PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; +#define glVertexAttribI1ui glad_glVertexAttribI1ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); +GLAPI PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; +#define glVertexAttribI2ui glad_glVertexAttribI2ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; +#define glVertexAttribI3ui glad_glVertexAttribI3ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint* v); +GLAPI PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; +#define glVertexAttribI1iv glad_glVertexAttribI1iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint* v); +GLAPI PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; +#define glVertexAttribI2iv glad_glVertexAttribI2iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint* v); +GLAPI PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; +#define glVertexAttribI3iv glad_glVertexAttribI3iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint* v); +GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint* v); +GLAPI PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; +#define glVertexAttribI1uiv glad_glVertexAttribI1uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint* v); +GLAPI PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; +#define glVertexAttribI2uiv glad_glVertexAttribI2uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint* v); +GLAPI PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; +#define glVertexAttribI3uiv glad_glVertexAttribI3uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint* v); +GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte* v); +GLAPI PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; +#define glVertexAttribI4bv glad_glVertexAttribI4bv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort* v); +GLAPI PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; +#define glVertexAttribI4sv glad_glVertexAttribI4sv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte* v); +GLAPI PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; +#define glVertexAttribI4ubv glad_glVertexAttribI4ubv +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort* v); +GLAPI PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; +#define glVertexAttribI4usv glad_glVertexAttribI4usv +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint* params); +GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar* name); +GLAPI PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; +#define glBindFragDataLocation glad_glBindFragDataLocation +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar* name); +GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint* value); +GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint* value); +GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint* value); +GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint* value); +GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint* params); +GLAPI PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; +#define glTexParameterIiv glad_glTexParameterIiv +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint* params); +GLAPI PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; +#define glTexParameterIuiv glad_glTexParameterIuiv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint* params); +GLAPI PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; +#define glGetTexParameterIiv glad_glGetTexParameterIiv +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint* params); +GLAPI PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; +#define glGetTexParameterIuiv glad_glGetTexParameterIuiv +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint* value); +GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint* value); +GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat* value); +GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint* renderbuffers); +GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint* renderbuffers); +GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; +#define glRenderbufferStorage glad_glRenderbufferStorage +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint* params); +GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); +GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; +#define glIsFramebuffer glad_glIsFramebuffer +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint* framebuffers); +GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; +#define glDeleteFramebuffers glad_glDeleteFramebuffers +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint* framebuffers); +GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; +#define glGenFramebuffers glad_glGenFramebuffers +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); +GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; +#define glCheckFramebufferStatus glad_glCheckFramebufferStatus +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; +#define glFramebufferTexture1D glad_glFramebufferTexture1D +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; +#define glFramebufferTexture3D glad_glFramebufferTexture3D +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint* params); +GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum target); +GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; +#define glGenerateMipmap glad_glGenerateMipmap +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +typedef void* (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint array); +GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint* arrays); +GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint* arrays); +GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint array); +GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +#endif +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +GLAPI int GLAD_GL_VERSION_3_1; +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount); +GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); +GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; +#define glTexBuffer glad_glTexBuffer +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); +GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; +#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar** uniformNames, GLuint* uniformIndices); +GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName); +GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; +#define glGetActiveUniformName glad_glGetActiveUniformName +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar* uniformBlockName); +GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); +GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +#endif +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +GLAPI int GLAD_GL_VERSION_3_2; +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex); +GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; +#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices, GLint basevertex); +GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; +#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex); +GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; +#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei* count, GLenum type, const void** indices, GLsizei drawcount, const GLint* basevertex); +GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; +#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum mode); +GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; +#define glProvokingVertex glad_glProvokingVertex +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync); +GLAPI PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync); +GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64* data); +GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values); +GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64* data); +GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64* params); +GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; +#define glFramebufferTexture glad_glFramebufferTexture +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; +#define glTexImage2DMultisample glad_glTexImage2DMultisample +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; +#define glTexImage3DMultisample glad_glTexImage3DMultisample +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat* val); +GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); +GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +#endif +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +GLAPI int GLAD_GL_EXT_separate_specular_color; +#endif +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +GLAPI int GLAD_GL_ARB_multisample; +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC)(GLfloat value, GLboolean invert); +GLAPI PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; +#define glSampleCoverageARB glad_glSampleCoverageARB +#endif +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 +GLAPI int GLAD_GL_ARB_robustness; +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC)(); +GLAPI PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; +#define glGetGraphicsResetStatusARB glad_glGetGraphicsResetStatusARB +typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img); +GLAPI PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; +#define glGetnTexImageARB glad_glGetnTexImageARB +typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data); +GLAPI PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; +#define glReadnPixelsARB glad_glReadnPixelsARB +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)(GLenum target, GLint lod, GLsizei bufSize, void* img); +GLAPI PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; +#define glGetnCompressedTexImageARB glad_glGetnCompressedTexImageARB +typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat* params); +GLAPI PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; +#define glGetnUniformfvARB glad_glGetnUniformfvARB +typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLint* params); +GLAPI PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; +#define glGetnUniformivARB glad_glGetnUniformivARB +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint* params); +GLAPI PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; +#define glGetnUniformuivARB glad_glGetnUniformuivARB +typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble* params); +GLAPI PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; +#define glGetnUniformdvARB glad_glGetnUniformdvARB +typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLdouble* v); +GLAPI PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; +#define glGetnMapdvARB glad_glGetnMapdvARB +typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLfloat* v); +GLAPI PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; +#define glGetnMapfvARB glad_glGetnMapfvARB +typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC)(GLenum target, GLenum query, GLsizei bufSize, GLint* v); +GLAPI PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; +#define glGetnMapivARB glad_glGetnMapivARB +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC)(GLenum map, GLsizei bufSize, GLfloat* values); +GLAPI PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; +#define glGetnPixelMapfvARB glad_glGetnPixelMapfvARB +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC)(GLenum map, GLsizei bufSize, GLuint* values); +GLAPI PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; +#define glGetnPixelMapuivARB glad_glGetnPixelMapuivARB +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC)(GLenum map, GLsizei bufSize, GLushort* values); +GLAPI PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; +#define glGetnPixelMapusvARB glad_glGetnPixelMapusvARB +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC)(GLsizei bufSize, GLubyte* pattern); +GLAPI PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; +#define glGetnPolygonStippleARB glad_glGetnPolygonStippleARB +typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table); +GLAPI PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; +#define glGetnColorTableARB glad_glGetnColorTableARB +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image); +GLAPI PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; +#define glGetnConvolutionFilterARB glad_glGetnConvolutionFilterARB +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC)(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void* column, void* span); +GLAPI PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; +#define glGetnSeparableFilterARB glad_glGetnSeparableFilterARB +typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +GLAPI PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; +#define glGetnHistogramARB glad_glGetnHistogramARB +typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values); +GLAPI PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; +#define glGetnMinmaxARB glad_glGetnMinmaxARB +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extern/glfw-3.2.1/deps/linmath.h b/extern/glfw-3.2.1/deps/linmath.h new file mode 100644 index 0000000..5732a76 --- /dev/null +++ b/extern/glfw-3.2.1/deps/linmath.h @@ -0,0 +1,574 @@ +#ifndef LINMATH_H +#define LINMATH_H + +#include + +#ifdef _MSC_VER +#define inline __inline +#endif + +#define LINMATH_H_DEFINE_VEC(n) \ +typedef float vec##n[n]; \ +static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \ +{ \ + int i; \ + for(i=0; i 1e-4) { + mat4x4 T, C, S; + + vec3_norm(u, u); + mat4x4_from_vec3_mul_outer(T, u, u); + + S[1][2] = u[0]; + S[2][1] = -u[0]; + S[2][0] = u[1]; + S[0][2] = -u[1]; + S[0][1] = u[2]; + S[1][0] = -u[2]; + + mat4x4_scale(S, S, s); + + mat4x4_identity(C); + mat4x4_sub(C, C, T); + + mat4x4_scale(C, C, c); + + mat4x4_add(T, T, C); + mat4x4_add(T, T, S); + + T[3][3] = 1.; + mat4x4_mul(R, M, T); + } else { + mat4x4_dup(R, M); + } +} +static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle) +{ + float s = sinf(angle); + float c = cosf(angle); + mat4x4 R = { + {1.f, 0.f, 0.f, 0.f}, + {0.f, c, s, 0.f}, + {0.f, -s, c, 0.f}, + {0.f, 0.f, 0.f, 1.f} + }; + mat4x4_mul(Q, M, R); +} +static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) +{ + float s = sinf(angle); + float c = cosf(angle); + mat4x4 R = { + { c, 0.f, s, 0.f}, + { 0.f, 1.f, 0.f, 0.f}, + { -s, 0.f, c, 0.f}, + { 0.f, 0.f, 0.f, 1.f} + }; + mat4x4_mul(Q, M, R); +} +static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle) +{ + float s = sinf(angle); + float c = cosf(angle); + mat4x4 R = { + { c, s, 0.f, 0.f}, + { -s, c, 0.f, 0.f}, + { 0.f, 0.f, 1.f, 0.f}, + { 0.f, 0.f, 0.f, 1.f} + }; + mat4x4_mul(Q, M, R); +} +static inline void mat4x4_invert(mat4x4 T, mat4x4 M) +{ + float idet; + float s[6]; + float c[6]; + s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; + s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2]; + s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3]; + s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2]; + s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3]; + s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3]; + + c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1]; + c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2]; + c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3]; + c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2]; + c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3]; + c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; + + /* Assumes it is invertible */ + idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); + + T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; + T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; + T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet; + T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet; + + T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet; + T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet; + T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet; + T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet; + + T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet; + T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet; + T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet; + T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet; + + T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet; + T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet; + T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; + T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; +} +static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) +{ + float s = 1.; + vec3 h; + + mat4x4_dup(R, M); + vec3_norm(R[2], R[2]); + + s = vec3_mul_inner(R[1], R[2]); + vec3_scale(h, R[2], s); + vec3_sub(R[1], R[1], h); + vec3_norm(R[2], R[2]); + + s = vec3_mul_inner(R[1], R[2]); + vec3_scale(h, R[2], s); + vec3_sub(R[1], R[1], h); + vec3_norm(R[1], R[1]); + + s = vec3_mul_inner(R[0], R[1]); + vec3_scale(h, R[1], s); + vec3_sub(R[0], R[0], h); + vec3_norm(R[0], R[0]); +} + +static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f) +{ + M[0][0] = 2.f*n/(r-l); + M[0][1] = M[0][2] = M[0][3] = 0.f; + + M[1][1] = 2.f*n/(t-b); + M[1][0] = M[1][2] = M[1][3] = 0.f; + + M[2][0] = (r+l)/(r-l); + M[2][1] = (t+b)/(t-b); + M[2][2] = -(f+n)/(f-n); + M[2][3] = -1.f; + + M[3][2] = -2.f*(f*n)/(f-n); + M[3][0] = M[3][1] = M[3][3] = 0.f; +} +static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f) +{ + M[0][0] = 2.f/(r-l); + M[0][1] = M[0][2] = M[0][3] = 0.f; + + M[1][1] = 2.f/(t-b); + M[1][0] = M[1][2] = M[1][3] = 0.f; + + M[2][2] = -2.f/(f-n); + M[2][0] = M[2][1] = M[2][3] = 0.f; + + M[3][0] = -(r+l)/(r-l); + M[3][1] = -(t+b)/(t-b); + M[3][2] = -(f+n)/(f-n); + M[3][3] = 1.f; +} +static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f) +{ + /* NOTE: Degrees are an unhandy unit to work with. + * linmath.h uses radians for everything! */ + float const a = 1.f / (float) tan(y_fov / 2.f); + + m[0][0] = a / aspect; + m[0][1] = 0.f; + m[0][2] = 0.f; + m[0][3] = 0.f; + + m[1][0] = 0.f; + m[1][1] = a; + m[1][2] = 0.f; + m[1][3] = 0.f; + + m[2][0] = 0.f; + m[2][1] = 0.f; + m[2][2] = -((f + n) / (f - n)); + m[2][3] = -1.f; + + m[3][0] = 0.f; + m[3][1] = 0.f; + m[3][2] = -((2.f * f * n) / (f - n)); + m[3][3] = 0.f; +} +static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up) +{ + /* Adapted from Android's OpenGL Matrix.java. */ + /* See the OpenGL GLUT documentation for gluLookAt for a description */ + /* of the algorithm. We implement it in a straightforward way: */ + + /* TODO: The negation of of can be spared by swapping the order of + * operands in the following cross products in the right way. */ + vec3 f; + vec3 s; + vec3 t; + + vec3_sub(f, center, eye); + vec3_norm(f, f); + + vec3_mul_cross(s, f, up); + vec3_norm(s, s); + + vec3_mul_cross(t, s, f); + + m[0][0] = s[0]; + m[0][1] = t[0]; + m[0][2] = -f[0]; + m[0][3] = 0.f; + + m[1][0] = s[1]; + m[1][1] = t[1]; + m[1][2] = -f[1]; + m[1][3] = 0.f; + + m[2][0] = s[2]; + m[2][1] = t[2]; + m[2][2] = -f[2]; + m[2][3] = 0.f; + + m[3][0] = 0.f; + m[3][1] = 0.f; + m[3][2] = 0.f; + m[3][3] = 1.f; + + mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]); +} + +typedef float quat[4]; +static inline void quat_identity(quat q) +{ + q[0] = q[1] = q[2] = 0.f; + q[3] = 1.f; +} +static inline void quat_add(quat r, quat a, quat b) +{ + int i; + for(i=0; i<4; ++i) + r[i] = a[i] + b[i]; +} +static inline void quat_sub(quat r, quat a, quat b) +{ + int i; + for(i=0; i<4; ++i) + r[i] = a[i] - b[i]; +} +static inline void quat_mul(quat r, quat p, quat q) +{ + vec3 w; + vec3_mul_cross(r, p, q); + vec3_scale(w, p, q[3]); + vec3_add(r, r, w); + vec3_scale(w, q, p[3]); + vec3_add(r, r, w); + r[3] = p[3]*q[3] - vec3_mul_inner(p, q); +} +static inline void quat_scale(quat r, quat v, float s) +{ + int i; + for(i=0; i<4; ++i) + r[i] = v[i] * s; +} +static inline float quat_inner_product(quat a, quat b) +{ + float p = 0.f; + int i; + for(i=0; i<4; ++i) + p += b[i]*a[i]; + return p; +} +static inline void quat_conj(quat r, quat q) +{ + int i; + for(i=0; i<3; ++i) + r[i] = -q[i]; + r[3] = q[3]; +} +static inline void quat_rotate(quat r, float angle, vec3 axis) { + int i; + vec3 v; + vec3_scale(v, axis, sinf(angle / 2)); + for(i=0; i<3; ++i) + r[i] = v[i]; + r[3] = cosf(angle / 2); +} +#define quat_norm vec4_norm +static inline void quat_mul_vec3(vec3 r, quat q, vec3 v) +{ +/* + * Method by Fabian 'ryg' Giessen (of Farbrausch) +t = 2 * cross(q.xyz, v) +v' = v + q.w * t + cross(q.xyz, t) + */ + vec3 t = {q[0], q[1], q[2]}; + vec3 u = {q[0], q[1], q[2]}; + + vec3_mul_cross(t, t, v); + vec3_scale(t, t, 2); + + vec3_mul_cross(u, u, t); + vec3_scale(t, t, q[3]); + + vec3_add(r, v, t); + vec3_add(r, r, u); +} +static inline void mat4x4_from_quat(mat4x4 M, quat q) +{ + float a = q[3]; + float b = q[0]; + float c = q[1]; + float d = q[2]; + float a2 = a*a; + float b2 = b*b; + float c2 = c*c; + float d2 = d*d; + + M[0][0] = a2 + b2 - c2 - d2; + M[0][1] = 2.f*(b*c + a*d); + M[0][2] = 2.f*(b*d - a*c); + M[0][3] = 0.f; + + M[1][0] = 2*(b*c - a*d); + M[1][1] = a2 - b2 + c2 - d2; + M[1][2] = 2.f*(c*d + a*b); + M[1][3] = 0.f; + + M[2][0] = 2.f*(b*d + a*c); + M[2][1] = 2.f*(c*d - a*b); + M[2][2] = a2 - b2 - c2 + d2; + M[2][3] = 0.f; + + M[3][0] = M[3][1] = M[3][2] = 0.f; + M[3][3] = 1.f; +} + +static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q) +{ +/* XXX: The way this is written only works for othogonal matrices. */ +/* TODO: Take care of non-orthogonal case. */ + quat_mul_vec3(R[0], q, M[0]); + quat_mul_vec3(R[1], q, M[1]); + quat_mul_vec3(R[2], q, M[2]); + + R[3][0] = R[3][1] = R[3][2] = 0.f; + R[3][3] = 1.f; +} +static inline void quat_from_mat4x4(quat q, mat4x4 M) +{ + float r=0.f; + int i; + + int perm[] = { 0, 1, 2, 0, 1 }; + int *p = perm; + + for(i = 0; i<3; i++) { + float m = M[i][i]; + if( m < r ) + continue; + m = r; + p = &perm[i]; + } + + r = (float) sqrt(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] ); + + if(r < 1e-6) { + q[0] = 1.f; + q[1] = q[2] = q[3] = 0.f; + return; + } + + q[0] = r/2.f; + q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r); + q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r); + q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); +} + +#endif diff --git a/extern/glfw-3.2.1/deps/mingw/_mingw_dxhelper.h b/extern/glfw-3.2.1/deps/mingw/_mingw_dxhelper.h new file mode 100644 index 0000000..849e291 --- /dev/null +++ b/extern/glfw-3.2.1/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/extern/glfw-3.2.1/deps/mingw/dinput.h b/extern/glfw-3.2.1/deps/mingw/dinput.h new file mode 100644 index 0000000..b575480 --- /dev/null +++ b/extern/glfw-3.2.1/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 +#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/extern/glfw-3.2.1/deps/mingw/xinput.h b/extern/glfw-3.2.1/deps/mingw/xinput.h new file mode 100644 index 0000000..d3ca726 --- /dev/null +++ b/extern/glfw-3.2.1/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 + +/* + * 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/extern/glfw-3.2.1/deps/tinycthread.c b/extern/glfw-3.2.1/deps/tinycthread.c new file mode 100644 index 0000000..ddb86d9 --- /dev/null +++ b/extern/glfw-3.2.1/deps/tinycthread.c @@ -0,0 +1,594 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2012 Marcus Geelnard + +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. +*/ + +/* 2013-01-06 Camilla Berglund + * + * Added casts from time_t to DWORD to avoid warnings on VC++. + * Fixed time retrieval on POSIX systems. + */ + +#include "tinycthread.h" +#include + +/* Platform specific includes */ +#if defined(_TTHREAD_POSIX_) + #include + #include + #include + #include + #include +#elif defined(_TTHREAD_WIN32_) + #include + #include +#endif + +/* Standard, good-to-have defines */ +#ifndef NULL + #define NULL (void*)0 +#endif +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 0 +#endif + +int mtx_init(mtx_t *mtx, int type) +{ +#if defined(_TTHREAD_WIN32_) + mtx->mAlreadyLocked = FALSE; + mtx->mRecursive = type & mtx_recursive; + InitializeCriticalSection(&mtx->mHandle); + return thrd_success; +#else + int ret; + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + if (type & mtx_recursive) + { + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + } + ret = pthread_mutex_init(mtx, &attr); + pthread_mutexattr_destroy(&attr); + return ret == 0 ? thrd_success : thrd_error; +#endif +} + +void mtx_destroy(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(&mtx->mHandle); +#else + pthread_mutex_destroy(mtx); +#endif +} + +int mtx_lock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + EnterCriticalSection(&mtx->mHandle); + if (!mtx->mRecursive) + { + while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */ + mtx->mAlreadyLocked = TRUE; + } + return thrd_success; +#else + return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; +#endif +} + +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) +{ + /* FIXME! */ + (void)mtx; + (void)ts; + return thrd_error; +} + +int mtx_trylock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy; + if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked) + { + LeaveCriticalSection(&mtx->mHandle); + ret = thrd_busy; + } + return ret; +#else + return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; +#endif +} + +int mtx_unlock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + mtx->mAlreadyLocked = FALSE; + LeaveCriticalSection(&mtx->mHandle); + return thrd_success; +#else + return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;; +#endif +} + +#if defined(_TTHREAD_WIN32_) +#define _CONDITION_EVENT_ONE 0 +#define _CONDITION_EVENT_ALL 1 +#endif + +int cnd_init(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + cond->mWaitersCount = 0; + + /* Init critical section */ + InitializeCriticalSection(&cond->mWaitersCountLock); + + /* Init events */ + cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); + if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL) + { + cond->mEvents[_CONDITION_EVENT_ALL] = NULL; + return thrd_error; + } + cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); + if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); + cond->mEvents[_CONDITION_EVENT_ONE] = NULL; + return thrd_error; + } + + return thrd_success; +#else + return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error; +#endif +} + +void cnd_destroy(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); + } + if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]); + } + DeleteCriticalSection(&cond->mWaitersCountLock); +#else + pthread_cond_destroy(cond); +#endif +} + +int cnd_signal(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + int haveWaiters; + + /* Are there any waiters? */ + EnterCriticalSection(&cond->mWaitersCountLock); + haveWaiters = (cond->mWaitersCount > 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we have any waiting threads, send them a signal */ + if(haveWaiters) + { + if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0) + { + return thrd_error; + } + } + + return thrd_success; +#else + return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; +#endif +} + +int cnd_broadcast(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + int haveWaiters; + + /* Are there any waiters? */ + EnterCriticalSection(&cond->mWaitersCountLock); + haveWaiters = (cond->mWaitersCount > 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we have any waiting threads, send them a signal */ + if(haveWaiters) + { + if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) + { + return thrd_error; + } + } + + return thrd_success; +#else + return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; +#endif +} + +#if defined(_TTHREAD_WIN32_) +static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout) +{ + int result, lastWaiter; + + /* Increment number of waiters */ + EnterCriticalSection(&cond->mWaitersCountLock); + ++ cond->mWaitersCount; + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* Release the mutex while waiting for the condition (will decrease + the number of waiters when done)... */ + mtx_unlock(mtx); + + /* Wait for either event to become signaled due to cnd_signal() or + cnd_broadcast() being called */ + result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout); + if (result == WAIT_TIMEOUT) + { + return thrd_timeout; + } + else if (result == (int)WAIT_FAILED) + { + return thrd_error; + } + + /* Check if we are the last waiter */ + EnterCriticalSection(&cond->mWaitersCountLock); + -- cond->mWaitersCount; + lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && + (cond->mWaitersCount == 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we are the last waiter to be notified to stop waiting, reset the event */ + if (lastWaiter) + { + if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) + { + return thrd_error; + } + } + + /* Re-acquire the mutex */ + mtx_lock(mtx); + + return thrd_success; +} +#endif + +int cnd_wait(cnd_t *cond, mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + return _cnd_timedwait_win32(cond, mtx, INFINITE); +#else + return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error; +#endif +} + +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) +{ +#if defined(_TTHREAD_WIN32_) + struct timespec now; + if (clock_gettime(CLOCK_REALTIME, &now) == 0) + { + DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 + + (ts->tv_nsec - now.tv_nsec + 500000) / 1000000); + return _cnd_timedwait_win32(cond, mtx, delta); + } + else + return thrd_error; +#else + int ret; + ret = pthread_cond_timedwait(cond, mtx, ts); + if (ret == ETIMEDOUT) + { + return thrd_timeout; + } + return ret == 0 ? thrd_success : thrd_error; +#endif +} + + +/** Information to pass to the new thread (what to run). */ +typedef struct { + thrd_start_t mFunction; /**< Pointer to the function to be executed. */ + void * mArg; /**< Function argument for the thread function. */ +} _thread_start_info; + +/* Thread wrapper function. */ +#if defined(_TTHREAD_WIN32_) +static unsigned WINAPI _thrd_wrapper_function(void * aArg) +#elif defined(_TTHREAD_POSIX_) +static void * _thrd_wrapper_function(void * aArg) +#endif +{ + thrd_start_t fun; + void *arg; + int res; +#if defined(_TTHREAD_POSIX_) + void *pres; +#endif + + /* Get thread startup information */ + _thread_start_info *ti = (_thread_start_info *) aArg; + fun = ti->mFunction; + arg = ti->mArg; + + /* The thread is responsible for freeing the startup information */ + free((void *)ti); + + /* Call the actual client thread function */ + res = fun(arg); + +#if defined(_TTHREAD_WIN32_) + return res; +#else + pres = malloc(sizeof(int)); + if (pres != NULL) + { + *(int*)pres = res; + } + return pres; +#endif +} + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) +{ + /* Fill out the thread startup information (passed to the thread wrapper, + which will eventually free it) */ + _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info)); + if (ti == NULL) + { + return thrd_nomem; + } + ti->mFunction = func; + ti->mArg = arg; + + /* Create the thread */ +#if defined(_TTHREAD_WIN32_) + *thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL); +#elif defined(_TTHREAD_POSIX_) + if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0) + { + *thr = 0; + } +#endif + + /* Did we fail to create the thread? */ + if(!*thr) + { + free(ti); + return thrd_error; + } + + return thrd_success; +} + +thrd_t thrd_current(void) +{ +#if defined(_TTHREAD_WIN32_) + return GetCurrentThread(); +#else + return pthread_self(); +#endif +} + +int thrd_detach(thrd_t thr) +{ + /* FIXME! */ + (void)thr; + return thrd_error; +} + +int thrd_equal(thrd_t thr0, thrd_t thr1) +{ +#if defined(_TTHREAD_WIN32_) + return thr0 == thr1; +#else + return pthread_equal(thr0, thr1); +#endif +} + +void thrd_exit(int res) +{ +#if defined(_TTHREAD_WIN32_) + ExitThread(res); +#else + void *pres = malloc(sizeof(int)); + if (pres != NULL) + { + *(int*)pres = res; + } + pthread_exit(pres); +#endif +} + +int thrd_join(thrd_t thr, int *res) +{ +#if defined(_TTHREAD_WIN32_) + if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED) + { + return thrd_error; + } + if (res != NULL) + { + DWORD dwRes; + GetExitCodeThread(thr, &dwRes); + *res = dwRes; + } +#elif defined(_TTHREAD_POSIX_) + void *pres; + int ires = 0; + if (pthread_join(thr, &pres) != 0) + { + return thrd_error; + } + if (pres != NULL) + { + ires = *(int*)pres; + free(pres); + } + if (res != NULL) + { + *res = ires; + } +#endif + return thrd_success; +} + +int thrd_sleep(const struct timespec *time_point, struct timespec *remaining) +{ + struct timespec now; +#if defined(_TTHREAD_WIN32_) + DWORD delta; +#else + long delta; +#endif + + /* Get the current time */ + if (clock_gettime(CLOCK_REALTIME, &now) != 0) + return -2; // FIXME: Some specific error code? + +#if defined(_TTHREAD_WIN32_) + /* Delta in milliseconds */ + delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 + + (time_point->tv_nsec - now.tv_nsec + 500000) / 1000000); + if (delta > 0) + { + Sleep(delta); + } +#else + /* Delta in microseconds */ + delta = (time_point->tv_sec - now.tv_sec) * 1000000L + + (time_point->tv_nsec - now.tv_nsec + 500L) / 1000L; + + /* On some systems, the usleep argument must be < 1000000 */ + while (delta > 999999L) + { + usleep(999999); + delta -= 999999L; + } + if (delta > 0L) + { + usleep((useconds_t)delta); + } +#endif + + /* We don't support waking up prematurely (yet) */ + if (remaining) + { + remaining->tv_sec = 0; + remaining->tv_nsec = 0; + } + return 0; +} + +void thrd_yield(void) +{ +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#else + sched_yield(); +#endif +} + +int tss_create(tss_t *key, tss_dtor_t dtor) +{ +#if defined(_TTHREAD_WIN32_) + /* FIXME: The destructor function is not supported yet... */ + if (dtor != NULL) + { + return thrd_error; + } + *key = TlsAlloc(); + if (*key == TLS_OUT_OF_INDEXES) + { + return thrd_error; + } +#else + if (pthread_key_create(key, dtor) != 0) + { + return thrd_error; + } +#endif + return thrd_success; +} + +void tss_delete(tss_t key) +{ +#if defined(_TTHREAD_WIN32_) + TlsFree(key); +#else + pthread_key_delete(key); +#endif +} + +void *tss_get(tss_t key) +{ +#if defined(_TTHREAD_WIN32_) + return TlsGetValue(key); +#else + return pthread_getspecific(key); +#endif +} + +int tss_set(tss_t key, void *val) +{ +#if defined(_TTHREAD_WIN32_) + if (TlsSetValue(key, val) == 0) + { + return thrd_error; + } +#else + if (pthread_setspecific(key, val) != 0) + { + return thrd_error; + } +#endif + return thrd_success; +} + +#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_) +int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts) +{ +#if defined(_TTHREAD_WIN32_) + struct _timeb tb; + _ftime(&tb); + ts->tv_sec = (time_t)tb.time; + ts->tv_nsec = 1000000L * (long)tb.millitm; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + ts->tv_sec = (time_t)tv.tv_sec; + ts->tv_nsec = 1000L * (long)tv.tv_usec; +#endif + return 0; +} +#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_ + diff --git a/extern/glfw-3.2.1/deps/tinycthread.h b/extern/glfw-3.2.1/deps/tinycthread.h new file mode 100644 index 0000000..6da30d7 --- /dev/null +++ b/extern/glfw-3.2.1/deps/tinycthread.h @@ -0,0 +1,441 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2012 Marcus Geelnard + +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 _TINYCTHREAD_H_ +#define _TINYCTHREAD_H_ + +/** +* @file +* @mainpage TinyCThread API Reference +* +* @section intro_sec Introduction +* TinyCThread is a minimal, portable implementation of basic threading +* classes for C. +* +* They closely mimic the functionality and naming of the C11 standard, and +* should be easily replaceable with the corresponding standard variants. +* +* @section port_sec Portability +* The Win32 variant uses the native Win32 API for implementing the thread +* classes, while for other systems, the POSIX threads API (pthread) is used. +* +* @section misc_sec Miscellaneous +* The following special keywords are available: #_Thread_local. +* +* For more detailed information, browse the different sections of this +* documentation. A good place to start is: +* tinycthread.h. +*/ + +/* Which platform are we on? */ +#if !defined(_TTHREAD_PLATFORM_DEFINED_) + #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define _TTHREAD_WIN32_ + #else + #define _TTHREAD_POSIX_ + #endif + #define _TTHREAD_PLATFORM_DEFINED_ +#endif + +/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */ +#if defined(_TTHREAD_POSIX_) + #undef _FEATURES_H + #if !defined(_GNU_SOURCE) + #define _GNU_SOURCE + #endif + #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L) + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L + #endif + #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500) + #undef _XOPEN_SOURCE + #define _XOPEN_SOURCE 500 + #endif +#endif + +/* Generic includes */ +#include + +/* Platform specific includes */ +#if defined(_TTHREAD_POSIX_) + #include + #include +#elif defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif + #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif +#endif + +/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC, + it's quite likely that libc does not support it either. Hence, fall back to + the only other supported time specifier: CLOCK_REALTIME (and if that fails, + we're probably emulating clock_gettime anyway, so anything goes). */ +#ifndef TIME_UTC + #ifdef CLOCK_REALTIME + #define TIME_UTC CLOCK_REALTIME + #else + #define TIME_UTC 0 + #endif +#endif + +/* Workaround for missing clock_gettime (most Windows compilers, afaik) */ +#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__) +#define _TTHREAD_EMULATE_CLOCK_GETTIME_ +/* Emulate struct timespec */ +#if defined(_TTHREAD_WIN32_) +struct _ttherad_timespec { + time_t tv_sec; + long tv_nsec; +}; +#define timespec _ttherad_timespec +#endif + +/* Emulate clockid_t */ +typedef int _tthread_clockid_t; +#define clockid_t _tthread_clockid_t + +/* Emulate clock_gettime */ +int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts); +#define clock_gettime _tthread_clock_gettime +#define CLOCK_REALTIME 0 +#endif + + +/** TinyCThread version (major number). */ +#define TINYCTHREAD_VERSION_MAJOR 1 +/** TinyCThread version (minor number). */ +#define TINYCTHREAD_VERSION_MINOR 1 +/** TinyCThread version (full version). */ +#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR) + +/** +* @def _Thread_local +* Thread local storage keyword. +* A variable that is declared with the @c _Thread_local keyword makes the +* value of the variable local to each thread (known as thread-local storage, +* or TLS). Example usage: +* @code +* // This variable is local to each thread. +* _Thread_local int variable; +* @endcode +* @note The @c _Thread_local keyword is a macro that maps to the corresponding +* compiler directive (e.g. @c __declspec(thread)). +* @note This directive is currently not supported on Mac OS X (it will give +* a compiler error), since compile-time TLS is not supported in the Mac OS X +* executable format. Also, some older versions of MinGW (before GCC 4.x) do +* not support this directive. +* @hideinitializer +*/ + +/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local) + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) + #define _Thread_local __thread + #else + #define _Thread_local __declspec(thread) + #endif +#endif + +/* Macros */ +#define TSS_DTOR_ITERATIONS 0 + +/* Function return values */ +#define thrd_error 0 /**< The requested operation failed */ +#define thrd_success 1 /**< The requested operation succeeded */ +#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */ +#define thrd_busy 3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */ +#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */ + +/* Mutex types */ +#define mtx_plain 1 +#define mtx_timed 2 +#define mtx_try 4 +#define mtx_recursive 8 + +/* Mutex */ +#if defined(_TTHREAD_WIN32_) +typedef struct { + CRITICAL_SECTION mHandle; /* Critical section handle */ + int mAlreadyLocked; /* TRUE if the mutex is already locked */ + int mRecursive; /* TRUE if the mutex is recursive */ +} mtx_t; +#else +typedef pthread_mutex_t mtx_t; +#endif + +/** Create a mutex object. +* @param mtx A mutex object. +* @param type Bit-mask that must have one of the following six values: +* @li @c mtx_plain for a simple non-recursive mutex +* @li @c mtx_timed for a non-recursive mutex that supports timeout +* @li @c mtx_try for a non-recursive mutex that supports test and return +* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive) +* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive) +* @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive) +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_init(mtx_t *mtx, int type); + +/** Release any resources used by the given mutex. +* @param mtx A mutex object. +*/ +void mtx_destroy(mtx_t *mtx); + +/** Lock the given mutex. +* Blocks until the given mutex can be locked. If the mutex is non-recursive, and +* the calling thread already has a lock on the mutex, this call will block +* forever. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_lock(mtx_t *mtx); + +/** NOT YET IMPLEMENTED. +*/ +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts); + +/** Try to lock the given mutex. +* The specified mutex shall support either test and return or timeout. If the +* mutex is already locked, the function returns without blocking. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_busy if the resource +* requested is already in use, or @ref thrd_error if the request could not be +* honored. +*/ +int mtx_trylock(mtx_t *mtx); + +/** Unlock the given mutex. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_unlock(mtx_t *mtx); + +/* Condition variable */ +#if defined(_TTHREAD_WIN32_) +typedef struct { + HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */ + unsigned int mWaitersCount; /* Count of the number of waiters. */ + CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */ +} cnd_t; +#else +typedef pthread_cond_t cnd_t; +#endif + +/** Create a condition variable object. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_init(cnd_t *cond); + +/** Release any resources used by the given condition variable. +* @param cond A condition variable object. +*/ +void cnd_destroy(cnd_t *cond); + +/** Signal a condition variable. +* Unblocks one of the threads that are blocked on the given condition variable +* at the time of the call. If no threads are blocked on the condition variable +* at the time of the call, the function does nothing and return success. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_signal(cnd_t *cond); + +/** Broadcast a condition variable. +* Unblocks all of the threads that are blocked on the given condition variable +* at the time of the call. If no threads are blocked on the condition variable +* at the time of the call, the function does nothing and return success. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_broadcast(cnd_t *cond); + +/** Wait for a condition variable to become signaled. +* The function atomically unlocks the given mutex and endeavors to block until +* the given condition variable is signaled by a call to cnd_signal or to +* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex +* before it returns. +* @param cond A condition variable object. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_wait(cnd_t *cond, mtx_t *mtx); + +/** Wait for a condition variable to become signaled. +* The function atomically unlocks the given mutex and endeavors to block until +* the given condition variable is signaled by a call to cnd_signal or to +* cnd_broadcast, or until after the specified time. When the calling thread +* becomes unblocked it locks the mutex before it returns. +* @param cond A condition variable object. +* @param mtx A mutex object. +* @param xt A point in time at which the request will time out (absolute time). +* @return @ref thrd_success upon success, or @ref thrd_timeout if the time +* specified in the call was reached without acquiring the requested resource, or +* @ref thrd_error if the request could not be honored. +*/ +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts); + +/* Thread */ +#if defined(_TTHREAD_WIN32_) +typedef HANDLE thrd_t; +#else +typedef pthread_t thrd_t; +#endif + +/** Thread start function. +* Any thread that is started with the @ref thrd_create() function must be +* started through a function of this type. +* @param arg The thread argument (the @c arg argument of the corresponding +* @ref thrd_create() call). +* @return The thread return value, which can be obtained by another thread +* by using the @ref thrd_join() function. +*/ +typedef int (*thrd_start_t)(void *arg); + +/** Create a new thread. +* @param thr Identifier of the newly created thread. +* @param func A function pointer to the function that will be executed in +* the new thread. +* @param arg An argument to the thread function. +* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could +* be allocated for the thread requested, or @ref thrd_error if the request +* could not be honored. +* @note A thread’s identifier may be reused for a different thread once the +* original thread has exited and either been detached or joined to another +* thread. +*/ +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); + +/** Identify the calling thread. +* @return The identifier of the calling thread. +*/ +thrd_t thrd_current(void); + +/** NOT YET IMPLEMENTED. +*/ +int thrd_detach(thrd_t thr); + +/** Compare two thread identifiers. +* The function determines if two thread identifiers refer to the same thread. +* @return Zero if the two thread identifiers refer to different threads. +* Otherwise a nonzero value is returned. +*/ +int thrd_equal(thrd_t thr0, thrd_t thr1); + +/** Terminate execution of the calling thread. +* @param res Result code of the calling thread. +*/ +void thrd_exit(int res); + +/** Wait for a thread to terminate. +* The function joins the given thread with the current thread by blocking +* until the other thread has terminated. +* @param thr The thread to join with. +* @param res If this pointer is not NULL, the function will store the result +* code of the given thread in the integer pointed to by @c res. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int thrd_join(thrd_t thr, int *res); + +/** Put the calling thread to sleep. +* Suspend execution of the calling thread. +* @param time_point A point in time at which the thread will resume (absolute time). +* @param remaining If non-NULL, this parameter will hold the remaining time until +* time_point upon return. This will typically be zero, but if +* the thread was woken up by a signal that is not ignored before +* time_point was reached @c remaining will hold a positive +* time. +* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred. +*/ +int thrd_sleep(const struct timespec *time_point, struct timespec *remaining); + +/** Yield execution to another thread. +* Permit other threads to run, even if the current thread would ordinarily +* continue to run. +*/ +void thrd_yield(void); + +/* Thread local storage */ +#if defined(_TTHREAD_WIN32_) +typedef DWORD tss_t; +#else +typedef pthread_key_t tss_t; +#endif + +/** Destructor function for a thread-specific storage. +* @param val The value of the destructed thread-specific storage. +*/ +typedef void (*tss_dtor_t)(void *val); + +/** Create a thread-specific storage. +* @param key The unique key identifier that will be set if the function is +* successful. +* @param dtor Destructor function. This can be NULL. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +* @note The destructor function is not supported under Windows. If @c dtor is +* not NULL when calling this function under Windows, the function will fail +* and return @ref thrd_error. +*/ +int tss_create(tss_t *key, tss_dtor_t dtor); + +/** Delete a thread-specific storage. +* The function releases any resources used by the given thread-specific +* storage. +* @param key The key that shall be deleted. +*/ +void tss_delete(tss_t key); + +/** Get the value for a thread-specific storage. +* @param key The thread-specific storage identifier. +* @return The value for the current thread held in the given thread-specific +* storage. +*/ +void *tss_get(tss_t key); + +/** Set the value for a thread-specific storage. +* @param key The thread-specific storage identifier. +* @param val The value of the thread-specific storage to set for the current +* thread. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int tss_set(tss_t key, void *val); + + +#endif /* _TINYTHREAD_H_ */ + diff --git a/extern/glfw-3.2.1/deps/vulkan/vk_platform.h b/extern/glfw-3.2.1/deps/vulkan/vk_platform.h new file mode 100644 index 0000000..5d0fc76 --- /dev/null +++ b/extern/glfw-3.2.1/deps/vulkan/vk_platform.h @@ -0,0 +1,120 @@ +// +// File: vk_platform.h +// +/* +** Copyright (c) 2014-2015 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + + +#ifndef VK_PLATFORM_H_ +#define VK_PLATFORM_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/* +*************************************************************************************************** +* Platform-specific directives and type declarations +*************************************************************************************************** +*/ + +/* Platform-specific calling convention macros. + * + * Platforms should define these so that Vulkan clients call Vulkan commands + * with the same calling conventions that the Vulkan implementation expects. + * + * VKAPI_ATTR - Placed before the return type in function declarations. + * Useful for C++11 and GCC/Clang-style function attribute syntax. + * VKAPI_CALL - Placed after the return type in function declarations. + * Useful for MSVC-style calling convention syntax. + * VKAPI_PTR - Placed between the '(' and '*' in function pointer types. + * + * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); + * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); + */ +#if defined(_WIN32) + // On Windows, Vulkan commands use the stdcall convention + #define VKAPI_ATTR + #define VKAPI_CALL __stdcall + #define VKAPI_PTR VKAPI_CALL +#elif defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__) + // Android does not support Vulkan in native code using the "armeabi" ABI. + #error "Vulkan requires the 'armeabi-v7a' or 'armeabi-v7a-hard' ABI on 32-bit ARM CPUs" +#elif defined(__ANDROID__) && defined(__ARM_ARCH_7A__) + // On Android/ARMv7a, Vulkan functions use the armeabi-v7a-hard calling + // convention, even if the application's native code is compiled with the + // armeabi-v7a calling convention. + #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp"))) + #define VKAPI_CALL + #define VKAPI_PTR VKAPI_ATTR +#else + // On other platforms, use the default calling convention + #define VKAPI_ATTR + #define VKAPI_CALL + #define VKAPI_PTR +#endif + +#include + +#if !defined(VK_NO_STDINT_H) + #if defined(_MSC_VER) && (_MSC_VER < 1600) + typedef signed __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef signed __int16 int16_t; + typedef unsigned __int16 uint16_t; + typedef signed __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef signed __int64 int64_t; + typedef unsigned __int64 uint64_t; + #else + #include + #endif +#endif // !defined(VK_NO_STDINT_H) + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +// Platform-specific headers required by platform window system extensions. +// These are enabled prior to #including "vulkan.h". The same enable then +// controls inclusion of the extension interfaces in vulkan.h. + +#ifdef VK_USE_PLATFORM_ANDROID_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_MIR_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_WIN32_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_XLIB_KHR +#include +#endif + +#ifdef VK_USE_PLATFORM_XCB_KHR +#include +#endif + +#endif diff --git a/extern/glfw-3.2.1/deps/vulkan/vulkan.h b/extern/glfw-3.2.1/deps/vulkan/vulkan.h new file mode 100644 index 0000000..eb8343e --- /dev/null +++ b/extern/glfw-3.2.1/deps/vulkan/vulkan.h @@ -0,0 +1,3835 @@ +#ifndef VULKAN_H_ +#define VULKAN_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2016 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_VERSION_1_0 1 +#include "vk_platform.h" + +#define VK_MAKE_VERSION(major, minor, patch) \ + (((major) << 22) | ((minor) << 12) | (patch)) + +// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. +//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) + +// Vulkan 1.0 version number +#define VK_API_VERSION_1_0 VK_MAKE_VERSION(1, 0, 0) + +#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) +// Version of this file +#define VK_HEADER_VERSION 11 + + +#define VK_NULL_HANDLE 0 + + + +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + + + +typedef uint32_t VkFlags; +typedef uint32_t VkBool32; +typedef uint64_t VkDeviceSize; +typedef uint32_t VkSampleMask; + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_HANDLE(VkPhysicalDevice) +VK_DEFINE_HANDLE(VkDevice) +VK_DEFINE_HANDLE(VkQueue) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) +VK_DEFINE_HANDLE(VkCommandBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) + +#define VK_LOD_CLAMP_NONE 1000.0f +#define VK_REMAINING_MIP_LEVELS (~0U) +#define VK_REMAINING_ARRAY_LAYERS (~0U) +#define VK_WHOLE_SIZE (~0ULL) +#define VK_ATTACHMENT_UNUSED (~0U) +#define VK_TRUE 1 +#define VK_FALSE 0 +#define VK_QUEUE_FAMILY_IGNORED (~0U) +#define VK_SUBPASS_EXTERNAL (~0U) +#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256 +#define VK_UUID_SIZE 16 +#define VK_MAX_MEMORY_TYPES 32 +#define VK_MAX_MEMORY_HEAPS 16 +#define VK_MAX_EXTENSION_NAME_SIZE 256 +#define VK_MAX_DESCRIPTION_SIZE 256 + + +typedef enum VkPipelineCacheHeaderVersion { + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, + VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, + VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1), + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheHeaderVersion; + +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_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, + VK_SUBOPTIMAL_KHR = 1000001003, + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, + VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, + VK_ERROR_INVALID_SHADER_NV = -1000012000, + VK_RESULT_BEGIN_RANGE = VK_ERROR_FORMAT_NOT_SUPPORTED, + VK_RESULT_END_RANGE = VK_INCOMPLETE, + VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FORMAT_NOT_SUPPORTED + 1), + VK_RESULT_MAX_ENUM = 0x7FFFFFFF +} VkResult; + +typedef enum VkStructureType { + VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, + VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, + VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, + VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, + VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, + VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, + VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, + VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, + VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, + VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, + VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000, + 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_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, + VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, + VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, + VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkStructureType; + +typedef enum VkSystemAllocationScope { + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, + VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, + VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND, + VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE, + VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1), + VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF +} VkSystemAllocationScope; + +typedef enum VkInternalAllocationType { + VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, + VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, + VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, + VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1), + VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkInternalAllocationType; + +typedef enum VkFormat { + VK_FORMAT_UNDEFINED = 0, + VK_FORMAT_R4G4_UNORM_PACK8 = 1, + VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, + VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, + VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, + VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, + VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, + VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, + VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, + VK_FORMAT_R8_UNORM = 9, + VK_FORMAT_R8_SNORM = 10, + VK_FORMAT_R8_USCALED = 11, + VK_FORMAT_R8_SSCALED = 12, + VK_FORMAT_R8_UINT = 13, + VK_FORMAT_R8_SINT = 14, + VK_FORMAT_R8_SRGB = 15, + VK_FORMAT_R8G8_UNORM = 16, + VK_FORMAT_R8G8_SNORM = 17, + VK_FORMAT_R8G8_USCALED = 18, + VK_FORMAT_R8G8_SSCALED = 19, + VK_FORMAT_R8G8_UINT = 20, + VK_FORMAT_R8G8_SINT = 21, + VK_FORMAT_R8G8_SRGB = 22, + VK_FORMAT_R8G8B8_UNORM = 23, + VK_FORMAT_R8G8B8_SNORM = 24, + VK_FORMAT_R8G8B8_USCALED = 25, + VK_FORMAT_R8G8B8_SSCALED = 26, + VK_FORMAT_R8G8B8_UINT = 27, + VK_FORMAT_R8G8B8_SINT = 28, + VK_FORMAT_R8G8B8_SRGB = 29, + VK_FORMAT_B8G8R8_UNORM = 30, + VK_FORMAT_B8G8R8_SNORM = 31, + VK_FORMAT_B8G8R8_USCALED = 32, + VK_FORMAT_B8G8R8_SSCALED = 33, + VK_FORMAT_B8G8R8_UINT = 34, + VK_FORMAT_B8G8R8_SINT = 35, + VK_FORMAT_B8G8R8_SRGB = 36, + VK_FORMAT_R8G8B8A8_UNORM = 37, + VK_FORMAT_R8G8B8A8_SNORM = 38, + VK_FORMAT_R8G8B8A8_USCALED = 39, + VK_FORMAT_R8G8B8A8_SSCALED = 40, + VK_FORMAT_R8G8B8A8_UINT = 41, + VK_FORMAT_R8G8B8A8_SINT = 42, + VK_FORMAT_R8G8B8A8_SRGB = 43, + VK_FORMAT_B8G8R8A8_UNORM = 44, + VK_FORMAT_B8G8R8A8_SNORM = 45, + VK_FORMAT_B8G8R8A8_USCALED = 46, + VK_FORMAT_B8G8R8A8_SSCALED = 47, + VK_FORMAT_B8G8R8A8_UINT = 48, + VK_FORMAT_B8G8R8A8_SINT = 49, + VK_FORMAT_B8G8R8A8_SRGB = 50, + VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, + VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, + VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, + VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, + VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, + VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, + VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, + VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, + VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, + VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, + VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, + VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, + VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, + VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, + VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, + VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, + VK_FORMAT_R16_UNORM = 70, + VK_FORMAT_R16_SNORM = 71, + VK_FORMAT_R16_USCALED = 72, + VK_FORMAT_R16_SSCALED = 73, + VK_FORMAT_R16_UINT = 74, + VK_FORMAT_R16_SINT = 75, + VK_FORMAT_R16_SFLOAT = 76, + VK_FORMAT_R16G16_UNORM = 77, + VK_FORMAT_R16G16_SNORM = 78, + VK_FORMAT_R16G16_USCALED = 79, + VK_FORMAT_R16G16_SSCALED = 80, + VK_FORMAT_R16G16_UINT = 81, + VK_FORMAT_R16G16_SINT = 82, + VK_FORMAT_R16G16_SFLOAT = 83, + VK_FORMAT_R16G16B16_UNORM = 84, + VK_FORMAT_R16G16B16_SNORM = 85, + VK_FORMAT_R16G16B16_USCALED = 86, + VK_FORMAT_R16G16B16_SSCALED = 87, + VK_FORMAT_R16G16B16_UINT = 88, + VK_FORMAT_R16G16B16_SINT = 89, + VK_FORMAT_R16G16B16_SFLOAT = 90, + VK_FORMAT_R16G16B16A16_UNORM = 91, + VK_FORMAT_R16G16B16A16_SNORM = 92, + VK_FORMAT_R16G16B16A16_USCALED = 93, + VK_FORMAT_R16G16B16A16_SSCALED = 94, + VK_FORMAT_R16G16B16A16_UINT = 95, + VK_FORMAT_R16G16B16A16_SINT = 96, + VK_FORMAT_R16G16B16A16_SFLOAT = 97, + VK_FORMAT_R32_UINT = 98, + VK_FORMAT_R32_SINT = 99, + VK_FORMAT_R32_SFLOAT = 100, + VK_FORMAT_R32G32_UINT = 101, + VK_FORMAT_R32G32_SINT = 102, + VK_FORMAT_R32G32_SFLOAT = 103, + VK_FORMAT_R32G32B32_UINT = 104, + VK_FORMAT_R32G32B32_SINT = 105, + VK_FORMAT_R32G32B32_SFLOAT = 106, + VK_FORMAT_R32G32B32A32_UINT = 107, + VK_FORMAT_R32G32B32A32_SINT = 108, + VK_FORMAT_R32G32B32A32_SFLOAT = 109, + VK_FORMAT_R64_UINT = 110, + VK_FORMAT_R64_SINT = 111, + VK_FORMAT_R64_SFLOAT = 112, + VK_FORMAT_R64G64_UINT = 113, + VK_FORMAT_R64G64_SINT = 114, + VK_FORMAT_R64G64_SFLOAT = 115, + VK_FORMAT_R64G64B64_UINT = 116, + VK_FORMAT_R64G64B64_SINT = 117, + VK_FORMAT_R64G64B64_SFLOAT = 118, + VK_FORMAT_R64G64B64A64_UINT = 119, + VK_FORMAT_R64G64B64A64_SINT = 120, + VK_FORMAT_R64G64B64A64_SFLOAT = 121, + VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, + VK_FORMAT_D16_UNORM = 124, + VK_FORMAT_X8_D24_UNORM_PACK32 = 125, + VK_FORMAT_D32_SFLOAT = 126, + VK_FORMAT_S8_UINT = 127, + VK_FORMAT_D16_UNORM_S8_UINT = 128, + VK_FORMAT_D24_UNORM_S8_UINT = 129, + VK_FORMAT_D32_SFLOAT_S8_UINT = 130, + VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, + VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, + VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, + VK_FORMAT_BC2_UNORM_BLOCK = 135, + VK_FORMAT_BC2_SRGB_BLOCK = 136, + VK_FORMAT_BC3_UNORM_BLOCK = 137, + VK_FORMAT_BC3_SRGB_BLOCK = 138, + VK_FORMAT_BC4_UNORM_BLOCK = 139, + VK_FORMAT_BC4_SNORM_BLOCK = 140, + VK_FORMAT_BC5_UNORM_BLOCK = 141, + VK_FORMAT_BC5_SNORM_BLOCK = 142, + VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, + VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, + VK_FORMAT_BC7_UNORM_BLOCK = 145, + VK_FORMAT_BC7_SRGB_BLOCK = 146, + VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, + VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, + VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, + VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, + VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, + VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, + VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, + VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, + VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, + VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, + VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, + VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, + VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, + VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, + VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, + VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, + VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, + VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, + VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, + VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, + VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, + VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, + VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, + VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, + VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, + VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, + VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, + VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, + VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, + VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, + VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, + VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, + VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, + VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, + VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, + VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, + VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, + VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED, + VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK, + VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1), + VK_FORMAT_MAX_ENUM = 0x7FFFFFFF +} VkFormat; + +typedef enum VkImageType { + VK_IMAGE_TYPE_1D = 0, + VK_IMAGE_TYPE_2D = 1, + VK_IMAGE_TYPE_3D = 2, + VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D, + VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D, + VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1), + VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageType; + +typedef enum VkImageTiling { + VK_IMAGE_TILING_OPTIMAL = 0, + VK_IMAGE_TILING_LINEAR = 1, + VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR, + VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1), + VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF +} VkImageTiling; + +typedef enum VkPhysicalDeviceType { + VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, + VK_PHYSICAL_DEVICE_TYPE_CPU = 4, + VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER, + VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU, + VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1), + VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkPhysicalDeviceType; + +typedef enum VkQueryType { + VK_QUERY_TYPE_OCCLUSION = 0, + VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, + VK_QUERY_TYPE_TIMESTAMP = 2, + VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION, + VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP, + VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1), + VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkQueryType; + +typedef enum VkSharingMode { + VK_SHARING_MODE_EXCLUSIVE = 0, + VK_SHARING_MODE_CONCURRENT = 1, + VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE, + VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT, + VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1), + VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSharingMode; + +typedef enum VkImageLayout { + VK_IMAGE_LAYOUT_UNDEFINED = 0, + VK_IMAGE_LAYOUT_GENERAL = 1, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED, + VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1), + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF +} VkImageLayout; + +typedef enum VkImageViewType { + VK_IMAGE_VIEW_TYPE_1D = 0, + VK_IMAGE_VIEW_TYPE_2D = 1, + VK_IMAGE_VIEW_TYPE_3D = 2, + VK_IMAGE_VIEW_TYPE_CUBE = 3, + VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, + VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D, + VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1), + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageViewType; + +typedef enum VkComponentSwizzle { + VK_COMPONENT_SWIZZLE_IDENTITY = 0, + VK_COMPONENT_SWIZZLE_ZERO = 1, + VK_COMPONENT_SWIZZLE_ONE = 2, + VK_COMPONENT_SWIZZLE_R = 3, + VK_COMPONENT_SWIZZLE_G = 4, + VK_COMPONENT_SWIZZLE_B = 5, + VK_COMPONENT_SWIZZLE_A = 6, + VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A, + VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1), + VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF +} VkComponentSwizzle; + +typedef enum VkVertexInputRate { + VK_VERTEX_INPUT_RATE_VERTEX = 0, + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX, + VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE, + VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1), + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF +} VkVertexInputRate; + +typedef enum VkPrimitiveTopology { + VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, + VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF +} VkPrimitiveTopology; + +typedef enum VkPolygonMode { + VK_POLYGON_MODE_FILL = 0, + VK_POLYGON_MODE_LINE = 1, + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL, + VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT, + VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1), + VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF +} VkPolygonMode; + +typedef enum VkFrontFace { + VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE, + VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1), + VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF +} VkFrontFace; + +typedef enum VkCompareOp { + VK_COMPARE_OP_NEVER = 0, + VK_COMPARE_OP_LESS = 1, + VK_COMPARE_OP_EQUAL = 2, + VK_COMPARE_OP_LESS_OR_EQUAL = 3, + VK_COMPARE_OP_GREATER = 4, + VK_COMPARE_OP_NOT_EQUAL = 5, + VK_COMPARE_OP_GREATER_OR_EQUAL = 6, + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER, + VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS, + VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1), + VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF +} VkCompareOp; + +typedef enum VkStencilOp { + VK_STENCIL_OP_KEEP = 0, + VK_STENCIL_OP_ZERO = 1, + VK_STENCIL_OP_REPLACE = 2, + VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, + VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, + VK_STENCIL_OP_INVERT = 5, + VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP, + VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP, + VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1), + VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF +} VkStencilOp; + +typedef enum VkLogicOp { + VK_LOGIC_OP_CLEAR = 0, + VK_LOGIC_OP_AND = 1, + VK_LOGIC_OP_AND_REVERSE = 2, + VK_LOGIC_OP_COPY = 3, + VK_LOGIC_OP_AND_INVERTED = 4, + VK_LOGIC_OP_NO_OP = 5, + VK_LOGIC_OP_XOR = 6, + VK_LOGIC_OP_OR = 7, + VK_LOGIC_OP_NOR = 8, + VK_LOGIC_OP_EQUIVALENT = 9, + VK_LOGIC_OP_INVERT = 10, + VK_LOGIC_OP_OR_REVERSE = 11, + VK_LOGIC_OP_COPY_INVERTED = 12, + VK_LOGIC_OP_OR_INVERTED = 13, + VK_LOGIC_OP_NAND = 14, + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR, + VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET, + VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1), + VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF +} VkLogicOp; + +typedef enum VkBlendFactor { + VK_BLEND_FACTOR_ZERO = 0, + VK_BLEND_FACTOR_ONE = 1, + VK_BLEND_FACTOR_SRC_COLOR = 2, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, + VK_BLEND_FACTOR_DST_COLOR = 4, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, + VK_BLEND_FACTOR_SRC_ALPHA = 6, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, + VK_BLEND_FACTOR_DST_ALPHA = 8, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, + VK_BLEND_FACTOR_CONSTANT_COLOR = 10, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, + VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, + VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, + VK_BLEND_FACTOR_SRC1_COLOR = 15, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, + VK_BLEND_FACTOR_SRC1_ALPHA = 17, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, + VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO, + VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1), + VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF +} VkBlendFactor; + +typedef enum VkBlendOp { + VK_BLEND_OP_ADD = 0, + VK_BLEND_OP_SUBTRACT = 1, + VK_BLEND_OP_REVERSE_SUBTRACT = 2, + VK_BLEND_OP_MIN = 3, + VK_BLEND_OP_MAX = 4, + VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD, + VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX, + VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1), + VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF +} VkBlendOp; + +typedef enum VkDynamicState { + VK_DYNAMIC_STATE_VIEWPORT = 0, + VK_DYNAMIC_STATE_SCISSOR = 1, + VK_DYNAMIC_STATE_LINE_WIDTH = 2, + VK_DYNAMIC_STATE_DEPTH_BIAS = 3, + VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, + VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, + VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), + VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF +} VkDynamicState; + +typedef enum VkFilter { + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_CUBIC_IMG = 1000015000, + VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST, + VK_FILTER_END_RANGE = VK_FILTER_LINEAR, + VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1), + VK_FILTER_MAX_ENUM = 0x7FFFFFFF +} VkFilter; + +typedef enum VkSamplerMipmapMode { + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST, + VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1), + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerMipmapMode; + +typedef enum VkSamplerAddressMode { + VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1), + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerAddressMode; + +typedef enum VkBorderColor { + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, + VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, + VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, + VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, + VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, + VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), + VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF +} VkBorderColor; + +typedef enum VkDescriptorType { + VK_DESCRIPTOR_TYPE_SAMPLER = 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, + VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorType; + +typedef enum VkAttachmentLoadOp { + VK_ATTACHMENT_LOAD_OP_LOAD = 0, + VK_ATTACHMENT_LOAD_OP_CLEAR = 1, + VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, + VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1), + VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentLoadOp; + +typedef enum VkAttachmentStoreOp { + VK_ATTACHMENT_STORE_OP_STORE = 0, + VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, + VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1), + VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentStoreOp; + +typedef enum VkPipelineBindPoint { + VK_PIPELINE_BIND_POINT_GRAPHICS = 0, + VK_PIPELINE_BIND_POINT_COMPUTE = 1, + VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, + VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, + VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF +} VkPipelineBindPoint; + +typedef enum VkCommandBufferLevel { + VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, + VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1), + VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferLevel; + +typedef enum VkIndexType { + VK_INDEX_TYPE_UINT16 = 0, + VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, + VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, + VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), + VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkIndexType; + +typedef enum VkSubpassContents { + VK_SUBPASS_CONTENTS_INLINE = 0, + VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, + VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE, + VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, + VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1), + VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassContents; + +typedef VkFlags VkInstanceCreateFlags; + +typedef enum VkFormatFeatureFlagBits { + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, + VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, + VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, + VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, + VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFormatFeatureFlagBits; +typedef VkFlags VkFormatFeatureFlags; + +typedef enum VkImageUsageFlagBits { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, + VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, + VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageUsageFlagBits; +typedef VkFlags VkImageUsageFlags; + +typedef enum VkImageCreateFlagBits { + VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, + VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, + VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageCreateFlagBits; +typedef VkFlags VkImageCreateFlags; + +typedef enum VkSampleCountFlagBits { + VK_SAMPLE_COUNT_1_BIT = 0x00000001, + VK_SAMPLE_COUNT_2_BIT = 0x00000002, + VK_SAMPLE_COUNT_4_BIT = 0x00000004, + VK_SAMPLE_COUNT_8_BIT = 0x00000008, + VK_SAMPLE_COUNT_16_BIT = 0x00000010, + VK_SAMPLE_COUNT_32_BIT = 0x00000020, + VK_SAMPLE_COUNT_64_BIT = 0x00000040, + VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSampleCountFlagBits; +typedef VkFlags VkSampleCountFlags; + +typedef enum VkQueueFlagBits { + VK_QUEUE_GRAPHICS_BIT = 0x00000001, + VK_QUEUE_COMPUTE_BIT = 0x00000002, + VK_QUEUE_TRANSFER_BIT = 0x00000004, + VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, + VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueueFlagBits; +typedef VkFlags VkQueueFlags; + +typedef enum VkMemoryPropertyFlagBits { + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, + VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, + VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryPropertyFlagBits; +typedef VkFlags VkMemoryPropertyFlags; + +typedef enum VkMemoryHeapFlagBits { + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryHeapFlagBits; +typedef VkFlags VkMemoryHeapFlags; +typedef VkFlags VkDeviceCreateFlags; +typedef VkFlags VkDeviceQueueCreateFlags; + +typedef enum VkPipelineStageFlagBits { + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, + VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, + VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, + VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineStageFlagBits; +typedef VkFlags VkPipelineStageFlags; +typedef VkFlags VkMemoryMapFlags; + +typedef enum VkImageAspectFlagBits { + VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, + VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, + VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, + VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageAspectFlagBits; +typedef VkFlags VkImageAspectFlags; + +typedef enum VkSparseImageFormatFlagBits { + VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, + VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, + VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, + VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseImageFormatFlagBits; +typedef VkFlags VkSparseImageFormatFlags; + +typedef enum VkSparseMemoryBindFlagBits { + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseMemoryBindFlagBits; +typedef VkFlags VkSparseMemoryBindFlags; + +typedef enum VkFenceCreateFlagBits { + VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, + VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFenceCreateFlagBits; +typedef VkFlags VkFenceCreateFlags; +typedef VkFlags VkSemaphoreCreateFlags; +typedef VkFlags VkEventCreateFlags; +typedef VkFlags VkQueryPoolCreateFlags; + +typedef enum VkQueryPipelineStatisticFlagBits { + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, + VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, + VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, + VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, + VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryPipelineStatisticFlagBits; +typedef VkFlags VkQueryPipelineStatisticFlags; + +typedef enum VkQueryResultFlagBits { + VK_QUERY_RESULT_64_BIT = 0x00000001, + VK_QUERY_RESULT_WAIT_BIT = 0x00000002, + VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, + VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, + VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryResultFlagBits; +typedef VkFlags VkQueryResultFlags; + +typedef enum VkBufferCreateFlagBits { + VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkBufferCreateFlagBits; +typedef VkFlags VkBufferCreateFlags; + +typedef enum VkBufferUsageFlagBits { + VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkBufferUsageFlagBits; +typedef VkFlags VkBufferUsageFlags; +typedef VkFlags VkBufferViewCreateFlags; +typedef VkFlags VkImageViewCreateFlags; +typedef VkFlags VkShaderModuleCreateFlags; +typedef VkFlags VkPipelineCacheCreateFlags; + +typedef enum VkPipelineCreateFlagBits { + VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, + VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, + VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, + VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreateFlagBits; +typedef VkFlags VkPipelineCreateFlags; +typedef VkFlags VkPipelineShaderStageCreateFlags; + +typedef enum VkShaderStageFlagBits { + VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, + VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, + VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, + VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, + VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, + VK_SHADER_STAGE_ALL = 0x7FFFFFFF, + VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkShaderStageFlagBits; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; + +typedef enum VkCullModeFlagBits { + VK_CULL_MODE_NONE = 0, + VK_CULL_MODE_FRONT_BIT = 0x00000001, + VK_CULL_MODE_BACK_BIT = 0x00000002, + VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, + VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCullModeFlagBits; +typedef VkFlags VkCullModeFlags; +typedef VkFlags VkPipelineMultisampleStateCreateFlags; +typedef VkFlags VkPipelineDepthStencilStateCreateFlags; +typedef VkFlags VkPipelineColorBlendStateCreateFlags; + +typedef enum VkColorComponentFlagBits { + VK_COLOR_COMPONENT_R_BIT = 0x00000001, + VK_COLOR_COMPONENT_G_BIT = 0x00000002, + VK_COLOR_COMPONENT_B_BIT = 0x00000004, + VK_COLOR_COMPONENT_A_BIT = 0x00000008, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkColorComponentFlagBits; +typedef VkFlags VkColorComponentFlags; +typedef VkFlags VkPipelineDynamicStateCreateFlags; +typedef VkFlags VkPipelineLayoutCreateFlags; +typedef VkFlags VkShaderStageFlags; +typedef VkFlags VkSamplerCreateFlags; +typedef VkFlags VkDescriptorSetLayoutCreateFlags; + +typedef enum VkDescriptorPoolCreateFlagBits { + VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, + VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorPoolCreateFlagBits; +typedef VkFlags VkDescriptorPoolCreateFlags; +typedef VkFlags VkDescriptorPoolResetFlags; +typedef VkFlags VkFramebufferCreateFlags; +typedef VkFlags VkRenderPassCreateFlags; + +typedef enum VkAttachmentDescriptionFlagBits { + VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, + VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentDescriptionFlagBits; +typedef VkFlags VkAttachmentDescriptionFlags; +typedef VkFlags VkSubpassDescriptionFlags; + +typedef enum VkAccessFlagBits { + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, + VK_ACCESS_INDEX_READ_BIT = 0x00000002, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, + VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, + VK_ACCESS_SHADER_READ_BIT = 0x00000020, + VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, + VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, + VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, + VK_ACCESS_HOST_READ_BIT = 0x00002000, + VK_ACCESS_HOST_WRITE_BIT = 0x00004000, + VK_ACCESS_MEMORY_READ_BIT = 0x00008000, + VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAccessFlagBits; +typedef VkFlags VkAccessFlags; + +typedef enum VkDependencyFlagBits { + VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, + VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDependencyFlagBits; +typedef VkFlags VkDependencyFlags; + +typedef enum VkCommandPoolCreateFlagBits { + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, + VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolCreateFlagBits; +typedef VkFlags VkCommandPoolCreateFlags; + +typedef enum VkCommandPoolResetFlagBits { + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolResetFlagBits; +typedef VkFlags VkCommandPoolResetFlags; + +typedef enum VkCommandBufferUsageFlagBits { + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, + VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferUsageFlagBits; +typedef VkFlags VkCommandBufferUsageFlags; + +typedef enum VkQueryControlFlagBits { + VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, + VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryControlFlagBits; +typedef VkFlags VkQueryControlFlags; + +typedef enum VkCommandBufferResetFlagBits { + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferResetFlagBits; +typedef VkFlags VkCommandBufferResetFlags; + +typedef enum VkStencilFaceFlagBits { + VK_STENCIL_FACE_FRONT_BIT = 0x00000001, + VK_STENCIL_FACE_BACK_BIT = 0x00000002, + VK_STENCIL_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkStencilFaceFlagBits; +typedef VkFlags VkStencilFaceFlags; + +typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( + void* pUserData, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( + void* pUserData, + void* pOriginal, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkFreeFunction)( + void* pUserData, + void* pMemory); + +typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); + +typedef struct VkApplicationInfo { + VkStructureType sType; + const void* pNext; + const char* pApplicationName; + uint32_t applicationVersion; + const char* pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo; + +typedef struct VkInstanceCreateInfo { + VkStructureType sType; + const void* pNext; + VkInstanceCreateFlags flags; + const VkApplicationInfo* pApplicationInfo; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; +} VkInstanceCreateInfo; + +typedef struct VkAllocationCallbacks { + void* pUserData; + PFN_vkAllocationFunction pfnAllocation; + PFN_vkReallocationFunction pfnReallocation; + PFN_vkFreeFunction pfnFree; + PFN_vkInternalAllocationNotification pfnInternalAllocation; + PFN_vkInternalFreeNotification pfnInternalFree; +} VkAllocationCallbacks; + +typedef struct VkPhysicalDeviceFeatures { + VkBool32 robustBufferAccess; + VkBool32 fullDrawIndexUint32; + VkBool32 imageCubeArray; + VkBool32 independentBlend; + VkBool32 geometryShader; + VkBool32 tessellationShader; + VkBool32 sampleRateShading; + VkBool32 dualSrcBlend; + VkBool32 logicOp; + VkBool32 multiDrawIndirect; + VkBool32 drawIndirectFirstInstance; + VkBool32 depthClamp; + VkBool32 depthBiasClamp; + VkBool32 fillModeNonSolid; + VkBool32 depthBounds; + VkBool32 wideLines; + VkBool32 largePoints; + VkBool32 alphaToOne; + VkBool32 multiViewport; + VkBool32 samplerAnisotropy; + VkBool32 textureCompressionETC2; + VkBool32 textureCompressionASTC_LDR; + VkBool32 textureCompressionBC; + VkBool32 occlusionQueryPrecise; + VkBool32 pipelineStatisticsQuery; + VkBool32 vertexPipelineStoresAndAtomics; + VkBool32 fragmentStoresAndAtomics; + VkBool32 shaderTessellationAndGeometryPointSize; + VkBool32 shaderImageGatherExtended; + VkBool32 shaderStorageImageExtendedFormats; + VkBool32 shaderStorageImageMultisample; + VkBool32 shaderStorageImageReadWithoutFormat; + VkBool32 shaderStorageImageWriteWithoutFormat; + VkBool32 shaderUniformBufferArrayDynamicIndexing; + VkBool32 shaderSampledImageArrayDynamicIndexing; + VkBool32 shaderStorageBufferArrayDynamicIndexing; + VkBool32 shaderStorageImageArrayDynamicIndexing; + VkBool32 shaderClipDistance; + VkBool32 shaderCullDistance; + VkBool32 shaderFloat64; + VkBool32 shaderInt64; + VkBool32 shaderInt16; + VkBool32 shaderResourceResidency; + VkBool32 shaderResourceMinLod; + VkBool32 sparseBinding; + VkBool32 sparseResidencyBuffer; + VkBool32 sparseResidencyImage2D; + VkBool32 sparseResidencyImage3D; + VkBool32 sparseResidency2Samples; + VkBool32 sparseResidency4Samples; + VkBool32 sparseResidency8Samples; + VkBool32 sparseResidency16Samples; + VkBool32 sparseResidencyAliased; + VkBool32 variableMultisampleRate; + VkBool32 inheritedQueries; +} VkPhysicalDeviceFeatures; + +typedef struct VkFormatProperties { + VkFormatFeatureFlags linearTilingFeatures; + VkFormatFeatureFlags optimalTilingFeatures; + VkFormatFeatureFlags bufferFeatures; +} VkFormatProperties; + +typedef struct VkExtent3D { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D; + +typedef struct VkImageFormatProperties { + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; +} VkImageFormatProperties; + +typedef struct VkPhysicalDeviceLimits { + uint32_t maxImageDimension1D; + uint32_t maxImageDimension2D; + uint32_t maxImageDimension3D; + uint32_t maxImageDimensionCube; + uint32_t maxImageArrayLayers; + uint32_t maxTexelBufferElements; + uint32_t maxUniformBufferRange; + uint32_t maxStorageBufferRange; + uint32_t maxPushConstantsSize; + uint32_t maxMemoryAllocationCount; + uint32_t maxSamplerAllocationCount; + VkDeviceSize bufferImageGranularity; + VkDeviceSize sparseAddressSpaceSize; + uint32_t maxBoundDescriptorSets; + uint32_t maxPerStageDescriptorSamplers; + uint32_t maxPerStageDescriptorUniformBuffers; + uint32_t maxPerStageDescriptorStorageBuffers; + uint32_t maxPerStageDescriptorSampledImages; + uint32_t maxPerStageDescriptorStorageImages; + uint32_t maxPerStageDescriptorInputAttachments; + uint32_t maxPerStageResources; + uint32_t maxDescriptorSetSamplers; + uint32_t maxDescriptorSetUniformBuffers; + uint32_t maxDescriptorSetUniformBuffersDynamic; + uint32_t maxDescriptorSetStorageBuffers; + uint32_t maxDescriptorSetStorageBuffersDynamic; + uint32_t maxDescriptorSetSampledImages; + uint32_t maxDescriptorSetStorageImages; + uint32_t maxDescriptorSetInputAttachments; + uint32_t maxVertexInputAttributes; + uint32_t maxVertexInputBindings; + uint32_t maxVertexInputAttributeOffset; + uint32_t maxVertexInputBindingStride; + uint32_t maxVertexOutputComponents; + uint32_t maxTessellationGenerationLevel; + uint32_t maxTessellationPatchSize; + uint32_t maxTessellationControlPerVertexInputComponents; + uint32_t maxTessellationControlPerVertexOutputComponents; + uint32_t maxTessellationControlPerPatchOutputComponents; + uint32_t maxTessellationControlTotalOutputComponents; + uint32_t maxTessellationEvaluationInputComponents; + uint32_t maxTessellationEvaluationOutputComponents; + uint32_t maxGeometryShaderInvocations; + uint32_t maxGeometryInputComponents; + uint32_t maxGeometryOutputComponents; + uint32_t maxGeometryOutputVertices; + uint32_t maxGeometryTotalOutputComponents; + uint32_t maxFragmentInputComponents; + uint32_t maxFragmentOutputAttachments; + uint32_t maxFragmentDualSrcAttachments; + uint32_t maxFragmentCombinedOutputResources; + uint32_t maxComputeSharedMemorySize; + uint32_t maxComputeWorkGroupCount[3]; + uint32_t maxComputeWorkGroupInvocations; + uint32_t maxComputeWorkGroupSize[3]; + uint32_t subPixelPrecisionBits; + uint32_t subTexelPrecisionBits; + uint32_t mipmapPrecisionBits; + uint32_t maxDrawIndexedIndexValue; + uint32_t maxDrawIndirectCount; + float maxSamplerLodBias; + float maxSamplerAnisotropy; + uint32_t maxViewports; + uint32_t maxViewportDimensions[2]; + float viewportBoundsRange[2]; + uint32_t viewportSubPixelBits; + size_t minMemoryMapAlignment; + VkDeviceSize minTexelBufferOffsetAlignment; + VkDeviceSize minUniformBufferOffsetAlignment; + VkDeviceSize minStorageBufferOffsetAlignment; + int32_t minTexelOffset; + uint32_t maxTexelOffset; + int32_t minTexelGatherOffset; + uint32_t maxTexelGatherOffset; + float minInterpolationOffset; + float maxInterpolationOffset; + uint32_t subPixelInterpolationOffsetBits; + uint32_t maxFramebufferWidth; + uint32_t maxFramebufferHeight; + uint32_t maxFramebufferLayers; + VkSampleCountFlags framebufferColorSampleCounts; + VkSampleCountFlags framebufferDepthSampleCounts; + VkSampleCountFlags framebufferStencilSampleCounts; + VkSampleCountFlags framebufferNoAttachmentsSampleCounts; + uint32_t maxColorAttachments; + VkSampleCountFlags sampledImageColorSampleCounts; + VkSampleCountFlags sampledImageIntegerSampleCounts; + VkSampleCountFlags sampledImageDepthSampleCounts; + VkSampleCountFlags sampledImageStencilSampleCounts; + VkSampleCountFlags storageImageSampleCounts; + uint32_t maxSampleMaskWords; + VkBool32 timestampComputeAndGraphics; + float timestampPeriod; + uint32_t maxClipDistances; + uint32_t maxCullDistances; + uint32_t maxCombinedClipAndCullDistances; + uint32_t discreteQueuePriorities; + float pointSizeRange[2]; + float lineWidthRange[2]; + float pointSizeGranularity; + float lineWidthGranularity; + VkBool32 strictLines; + VkBool32 standardSampleLocations; + VkDeviceSize optimalBufferCopyOffsetAlignment; + VkDeviceSize optimalBufferCopyRowPitchAlignment; + VkDeviceSize nonCoherentAtomSize; +} VkPhysicalDeviceLimits; + +typedef struct VkPhysicalDeviceSparseProperties { + VkBool32 residencyStandard2DBlockShape; + VkBool32 residencyStandard2DMultisampleBlockShape; + VkBool32 residencyStandard3DBlockShape; + VkBool32 residencyAlignedMipSize; + VkBool32 residencyNonResidentStrict; +} VkPhysicalDeviceSparseProperties; + +typedef struct VkPhysicalDeviceProperties { + uint32_t apiVersion; + uint32_t driverVersion; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceType deviceType; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + VkPhysicalDeviceLimits limits; + VkPhysicalDeviceSparseProperties sparseProperties; +} VkPhysicalDeviceProperties; + +typedef struct VkQueueFamilyProperties { + VkQueueFlags queueFlags; + uint32_t queueCount; + uint32_t timestampValidBits; + VkExtent3D minImageTransferGranularity; +} VkQueueFamilyProperties; + +typedef struct VkMemoryType { + VkMemoryPropertyFlags propertyFlags; + uint32_t heapIndex; +} VkMemoryType; + +typedef struct VkMemoryHeap { + VkDeviceSize size; + VkMemoryHeapFlags flags; +} VkMemoryHeap; + +typedef struct VkPhysicalDeviceMemoryProperties { + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryProperties; + +typedef struct VkDeviceQueueCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + const float* pQueuePriorities; +} VkDeviceQueueCreateInfo; + +typedef struct VkDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceCreateFlags flags; + uint32_t queueCreateInfoCount; + const VkDeviceQueueCreateInfo* pQueueCreateInfos; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; + const VkPhysicalDeviceFeatures* pEnabledFeatures; +} VkDeviceCreateInfo; + +typedef struct VkExtensionProperties { + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; +} VkExtensionProperties; + +typedef struct VkLayerProperties { + char layerName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; + uint32_t implementationVersion; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkLayerProperties; + +typedef struct VkSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + const VkPipelineStageFlags* pWaitDstStageMask; + uint32_t commandBufferCount; + const VkCommandBuffer* pCommandBuffers; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkSubmitInfo; + +typedef struct VkMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeIndex; +} VkMemoryAllocateInfo; + +typedef struct VkMappedMemoryRange { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize size; +} VkMappedMemoryRange; + +typedef struct VkMemoryRequirements { + VkDeviceSize size; + VkDeviceSize alignment; + uint32_t memoryTypeBits; +} VkMemoryRequirements; + +typedef struct VkSparseImageFormatProperties { + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +typedef struct VkSparseImageMemoryRequirements { + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize imageMipTailSize; + VkDeviceSize imageMipTailOffset; + VkDeviceSize imageMipTailStride; +} VkSparseImageMemoryRequirements; + +typedef struct VkSparseMemoryBind { + VkDeviceSize resourceOffset; + VkDeviceSize size; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseMemoryBind; + +typedef struct VkSparseBufferMemoryBindInfo { + VkBuffer buffer; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseBufferMemoryBindInfo; + +typedef struct VkSparseImageOpaqueMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseImageOpaqueMemoryBindInfo; + +typedef struct VkImageSubresource { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t arrayLayer; +} VkImageSubresource; + +typedef struct VkOffset3D { + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D; + +typedef struct VkSparseImageMemoryBind { + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseImageMemoryBind; + +typedef struct VkSparseImageMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseImageMemoryBind* pBinds; +} VkSparseImageMemoryBindInfo; + +typedef struct VkBindSparseInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t bufferBindCount; + const VkSparseBufferMemoryBindInfo* pBufferBinds; + uint32_t imageOpaqueBindCount; + const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; + uint32_t imageBindCount; + const VkSparseImageMemoryBindInfo* pImageBinds; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkBindSparseInfo; + +typedef struct VkFenceCreateInfo { + VkStructureType sType; + const void* pNext; + VkFenceCreateFlags flags; +} VkFenceCreateInfo; + +typedef struct VkSemaphoreCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreCreateFlags flags; +} VkSemaphoreCreateInfo; + +typedef struct VkEventCreateInfo { + VkStructureType sType; + const void* pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo; + +typedef struct VkQueryPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkQueryPoolCreateFlags flags; + VkQueryType queryType; + uint32_t queryCount; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkQueryPoolCreateInfo; + +typedef struct VkBufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferCreateFlags flags; + VkDeviceSize size; + VkBufferUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkBufferCreateInfo; + +typedef struct VkBufferViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferViewCreateFlags flags; + VkBuffer buffer; + VkFormat format; + VkDeviceSize offset; + VkDeviceSize range; +} VkBufferViewCreateInfo; + +typedef struct VkImageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageType imageType; + VkFormat format; + VkExtent3D extent; + uint32_t mipLevels; + uint32_t arrayLayers; + VkSampleCountFlagBits samples; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkImageLayout initialLayout; +} VkImageCreateInfo; + +typedef struct VkSubresourceLayout { + VkDeviceSize offset; + VkDeviceSize size; + VkDeviceSize rowPitch; + VkDeviceSize arrayPitch; + VkDeviceSize depthPitch; +} VkSubresourceLayout; + +typedef struct VkComponentMapping { + VkComponentSwizzle r; + VkComponentSwizzle g; + VkComponentSwizzle b; + VkComponentSwizzle a; +} VkComponentMapping; + +typedef struct VkImageSubresourceRange { + VkImageAspectFlags aspectMask; + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceRange; + +typedef struct VkImageViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageViewCreateFlags flags; + VkImage image; + VkImageViewType viewType; + VkFormat format; + VkComponentMapping components; + VkImageSubresourceRange subresourceRange; +} VkImageViewCreateInfo; + +typedef struct VkShaderModuleCreateInfo { + VkStructureType sType; + const void* pNext; + VkShaderModuleCreateFlags flags; + size_t codeSize; + const uint32_t* pCode; +} VkShaderModuleCreateInfo; + +typedef struct VkPipelineCacheCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCacheCreateFlags flags; + size_t initialDataSize; + const void* pInitialData; +} VkPipelineCacheCreateInfo; + +typedef struct VkSpecializationMapEntry { + uint32_t constantID; + uint32_t offset; + size_t size; +} VkSpecializationMapEntry; + +typedef struct VkSpecializationInfo { + uint32_t mapEntryCount; + const VkSpecializationMapEntry* pMapEntries; + size_t dataSize; + const void* pData; +} VkSpecializationInfo; + +typedef struct VkPipelineShaderStageCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineShaderStageCreateFlags flags; + VkShaderStageFlagBits stage; + VkShaderModule module; + const char* pName; + const VkSpecializationInfo* pSpecializationInfo; +} VkPipelineShaderStageCreateInfo; + +typedef struct VkVertexInputBindingDescription { + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; +} VkVertexInputBindingDescription; + +typedef struct VkVertexInputAttributeDescription { + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription; + +typedef struct VkPipelineVertexInputStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineVertexInputStateCreateFlags flags; + uint32_t vertexBindingDescriptionCount; + const VkVertexInputBindingDescription* pVertexBindingDescriptions; + uint32_t vertexAttributeDescriptionCount; + const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; +} VkPipelineVertexInputStateCreateInfo; + +typedef struct VkPipelineInputAssemblyStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineInputAssemblyStateCreateFlags flags; + VkPrimitiveTopology topology; + VkBool32 primitiveRestartEnable; +} VkPipelineInputAssemblyStateCreateInfo; + +typedef struct VkPipelineTessellationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineTessellationStateCreateFlags flags; + uint32_t patchControlPoints; +} VkPipelineTessellationStateCreateInfo; + +typedef struct VkViewport { + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} VkViewport; + +typedef struct VkOffset2D { + int32_t x; + int32_t y; +} VkOffset2D; + +typedef struct VkExtent2D { + uint32_t width; + uint32_t height; +} VkExtent2D; + +typedef struct VkRect2D { + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D; + +typedef struct VkPipelineViewportStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineViewportStateCreateFlags flags; + uint32_t viewportCount; + const VkViewport* pViewports; + uint32_t scissorCount; + const VkRect2D* pScissors; +} VkPipelineViewportStateCreateInfo; + +typedef struct VkPipelineRasterizationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationStateCreateFlags flags; + VkBool32 depthClampEnable; + VkBool32 rasterizerDiscardEnable; + VkPolygonMode polygonMode; + VkCullModeFlags cullMode; + VkFrontFace frontFace; + VkBool32 depthBiasEnable; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; + float lineWidth; +} VkPipelineRasterizationStateCreateInfo; + +typedef struct VkPipelineMultisampleStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineMultisampleStateCreateFlags flags; + VkSampleCountFlagBits rasterizationSamples; + VkBool32 sampleShadingEnable; + float minSampleShading; + const VkSampleMask* pSampleMask; + VkBool32 alphaToCoverageEnable; + VkBool32 alphaToOneEnable; +} VkPipelineMultisampleStateCreateInfo; + +typedef struct VkStencilOpState { + VkStencilOp failOp; + VkStencilOp passOp; + VkStencilOp depthFailOp; + VkCompareOp compareOp; + uint32_t compareMask; + uint32_t writeMask; + uint32_t reference; +} VkStencilOpState; + +typedef struct VkPipelineDepthStencilStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDepthStencilStateCreateFlags flags; + VkBool32 depthTestEnable; + VkBool32 depthWriteEnable; + VkCompareOp depthCompareOp; + VkBool32 depthBoundsTestEnable; + VkBool32 stencilTestEnable; + VkStencilOpState front; + VkStencilOpState back; + float minDepthBounds; + float maxDepthBounds; +} VkPipelineDepthStencilStateCreateInfo; + +typedef struct VkPipelineColorBlendAttachmentState { + VkBool32 blendEnable; + VkBlendFactor srcColorBlendFactor; + VkBlendFactor dstColorBlendFactor; + VkBlendOp colorBlendOp; + VkBlendFactor srcAlphaBlendFactor; + VkBlendFactor dstAlphaBlendFactor; + VkBlendOp alphaBlendOp; + VkColorComponentFlags colorWriteMask; +} VkPipelineColorBlendAttachmentState; + +typedef struct VkPipelineColorBlendStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineColorBlendStateCreateFlags flags; + VkBool32 logicOpEnable; + VkLogicOp logicOp; + uint32_t attachmentCount; + const VkPipelineColorBlendAttachmentState* pAttachments; + float blendConstants[4]; +} VkPipelineColorBlendStateCreateInfo; + +typedef struct VkPipelineDynamicStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDynamicStateCreateFlags flags; + uint32_t dynamicStateCount; + const VkDynamicState* pDynamicStates; +} VkPipelineDynamicStateCreateInfo; + +typedef struct VkGraphicsPipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; + const VkPipelineViewportStateCreateInfo* pViewportState; + const VkPipelineRasterizationStateCreateInfo* pRasterizationState; + const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + const VkPipelineDynamicStateCreateInfo* pDynamicState; + VkPipelineLayout layout; + VkRenderPass renderPass; + uint32_t subpass; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkGraphicsPipelineCreateInfo; + +typedef struct VkComputePipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + VkPipelineShaderStageCreateInfo stage; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkComputePipelineCreateInfo; + +typedef struct VkPushConstantRange { + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; +} VkPushConstantRange; + +typedef struct VkPipelineLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineLayoutCreateFlags flags; + uint32_t setLayoutCount; + const VkDescriptorSetLayout* pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; +} VkPipelineLayoutCreateInfo; + +typedef struct VkSamplerCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerCreateFlags flags; + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU; + VkSamplerAddressMode addressModeV; + VkSamplerAddressMode addressModeW; + float mipLodBias; + VkBool32 anisotropyEnable; + float maxAnisotropy; + VkBool32 compareEnable; + VkCompareOp compareOp; + float minLod; + float maxLod; + VkBorderColor borderColor; + VkBool32 unnormalizedCoordinates; +} VkSamplerCreateInfo; + +typedef struct VkDescriptorSetLayoutBinding { + uint32_t binding; + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + const VkSampler* pImmutableSamplers; +} VkDescriptorSetLayoutBinding; + +typedef struct VkDescriptorSetLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayoutCreateFlags flags; + uint32_t bindingCount; + const VkDescriptorSetLayoutBinding* pBindings; +} VkDescriptorSetLayoutCreateInfo; + +typedef struct VkDescriptorPoolSize { + VkDescriptorType type; + uint32_t descriptorCount; +} VkDescriptorPoolSize; + +typedef struct VkDescriptorPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPoolCreateFlags flags; + uint32_t maxSets; + uint32_t poolSizeCount; + const VkDescriptorPoolSize* pPoolSizes; +} VkDescriptorPoolCreateInfo; + +typedef struct VkDescriptorSetAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPool descriptorPool; + uint32_t descriptorSetCount; + const VkDescriptorSetLayout* pSetLayouts; +} VkDescriptorSetAllocateInfo; + +typedef struct VkDescriptorImageInfo { + VkSampler sampler; + VkImageView imageView; + VkImageLayout imageLayout; +} VkDescriptorImageInfo; + +typedef struct VkDescriptorBufferInfo { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize range; +} VkDescriptorBufferInfo; + +typedef struct VkWriteDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + const VkDescriptorImageInfo* pImageInfo; + const VkDescriptorBufferInfo* pBufferInfo; + const VkBufferView* pTexelBufferView; +} VkWriteDescriptorSet; + +typedef struct VkCopyDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet srcSet; + uint32_t srcBinding; + uint32_t srcArrayElement; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; +} VkCopyDescriptorSet; + +typedef struct VkFramebufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkFramebufferCreateFlags flags; + VkRenderPass renderPass; + uint32_t attachmentCount; + const VkImageView* pAttachments; + uint32_t width; + uint32_t height; + uint32_t layers; +} VkFramebufferCreateInfo; + +typedef struct VkAttachmentDescription { + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription; + +typedef struct VkAttachmentReference { + uint32_t attachment; + VkImageLayout layout; +} VkAttachmentReference; + +typedef struct VkSubpassDescription { + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t inputAttachmentCount; + const VkAttachmentReference* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference* pColorAttachments; + const VkAttachmentReference* pResolveAttachments; + const VkAttachmentReference* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription; + +typedef struct VkSubpassDependency { + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; +} VkSubpassDependency; + +typedef struct VkRenderPassCreateInfo { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency* pDependencies; +} VkRenderPassCreateInfo; + +typedef struct VkCommandPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPoolCreateFlags flags; + uint32_t queueFamilyIndex; +} VkCommandPoolCreateInfo; + +typedef struct VkCommandBufferAllocateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPool commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo; + +typedef struct VkCommandBufferInheritanceInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + uint32_t subpass; + VkFramebuffer framebuffer; + VkBool32 occlusionQueryEnable; + VkQueryControlFlags queryFlags; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkCommandBufferInheritanceInfo; + +typedef struct VkCommandBufferBeginInfo { + VkStructureType sType; + const void* pNext; + VkCommandBufferUsageFlags flags; + const VkCommandBufferInheritanceInfo* pInheritanceInfo; +} VkCommandBufferBeginInfo; + +typedef struct VkBufferCopy { + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy; + +typedef struct VkImageSubresourceLayers { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceLayers; + +typedef struct VkImageCopy { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + +typedef struct VkImageBlit { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit; + +typedef struct VkBufferImageCopy { + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy; + +typedef union VkClearColorValue { + float float32[4]; + int32_t int32[4]; + uint32_t uint32[4]; +} VkClearColorValue; + +typedef struct VkClearDepthStencilValue { + float depth; + uint32_t stencil; +} VkClearDepthStencilValue; + +typedef union VkClearValue { + VkClearColorValue color; + VkClearDepthStencilValue depthStencil; +} VkClearValue; + +typedef struct VkClearAttachment { + VkImageAspectFlags aspectMask; + uint32_t colorAttachment; + VkClearValue clearValue; +} VkClearAttachment; + +typedef struct VkClearRect { + VkRect2D rect; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkClearRect; + +typedef struct VkImageResolve { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve; + +typedef struct VkMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkBufferMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier; + +typedef struct VkImageMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier; + +typedef struct VkRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + VkFramebuffer framebuffer; + VkRect2D renderArea; + uint32_t clearValueCount; + const VkClearValue* pClearValues; +} VkRenderPassBeginInfo; + +typedef struct VkDispatchIndirectCommand { + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkDrawIndexedIndirectCommand { + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} VkDrawIndexedIndirectCommand; + +typedef struct VkDrawIndirectCommand { + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +} VkDrawIndirectCommand; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); +typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); +typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); +typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); +typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData); +typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); +typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore); +typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent); +typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool); +typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage); +typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); +typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler); +typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); +typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); +typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); +typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); +typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); +typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); +typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const uint32_t* pData); +typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( + const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); + +VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( + VkInstance instance, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( + VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkImageFormatProperties* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties* pMemoryProperties); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( + VkInstance instance, + const char* pName); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( + VkDevice device, + const char* pName); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties( + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( + VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex, + VkQueue* pQueue); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( + VkQueue queue); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( + VkDevice device); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory( + VkDevice device, + const VkMemoryAllocateInfo* pAllocateInfo, + const VkAllocationCallbacks* pAllocator, + VkDeviceMemory* pMemory); + +VKAPI_ATTR void VKAPI_CALL vkFreeMemory( + VkDevice device, + VkDeviceMemory memory, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize offset, + VkDeviceSize size, + VkMemoryMapFlags flags, + void** ppData); + +VKAPI_ATTR void VKAPI_CALL vkUnmapMemory( + VkDevice device, + VkDeviceMemory memory); + +VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize* pCommittedMemoryInBytes); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory( + VkDevice device, + VkBuffer buffer, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory( + VkDevice device, + VkImage image, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements( + VkDevice device, + VkBuffer buffer, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements( + VkDevice device, + VkImage image, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements( + VkDevice device, + VkImage image, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkSampleCountFlagBits samples, + VkImageUsageFlags usage, + VkImageTiling tiling, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse( + VkQueue queue, + uint32_t bindInfoCount, + const VkBindSparseInfo* pBindInfo, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence( + VkDevice device, + const VkFenceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFence( + VkDevice device, + VkFence fence, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus( + VkDevice device, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences, + VkBool32 waitAll, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore( + VkDevice device, + const VkSemaphoreCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSemaphore* pSemaphore); + +VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( + VkDevice device, + VkSemaphore semaphore, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( + VkDevice device, + const VkEventCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkEvent* pEvent); + +VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( + VkDevice device, + VkEvent event, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( + VkDevice device, + const VkQueryPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkQueryPool* pQueryPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool( + VkDevice device, + VkQueryPool queryPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + size_t dataSize, + void* pData, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer( + VkDevice device, + const VkBufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBuffer* pBuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( + VkDevice device, + VkBuffer buffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView( + VkDevice device, + const VkBufferViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBufferView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView( + VkDevice device, + VkBufferView bufferView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage( + VkDevice device, + const VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage* pImage); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImage( + VkDevice device, + VkImage image, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout( + VkDevice device, + VkImage image, + const VkImageSubresource* pSubresource, + VkSubresourceLayout* pLayout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView( + VkDevice device, + const VkImageViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImageView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( + VkDevice device, + VkImageView imageView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule); + +VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule( + VkDevice device, + VkShaderModule shaderModule, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( + VkDevice device, + const VkPipelineCacheCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineCache* pPipelineCache); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache( + VkDevice device, + VkPipelineCache pipelineCache, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData( + VkDevice device, + VkPipelineCache pipelineCache, + size_t* pDataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( + VkDevice device, + VkPipelineCache dstCache, + uint32_t srcCacheCount, + const VkPipelineCache* pSrcCaches); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkGraphicsPipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkComputePipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline( + VkDevice device, + VkPipeline pipeline, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout( + VkDevice device, + const VkPipelineLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineLayout* pPipelineLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout( + VkDevice device, + VkPipelineLayout pipelineLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( + VkDevice device, + const VkSamplerCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSampler* pSampler); + +VKAPI_ATTR void VKAPI_CALL vkDestroySampler( + VkDevice device, + VkSampler sampler, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorSetLayout* pSetLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout( + VkDevice device, + VkDescriptorSetLayout descriptorSetLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( + VkDevice device, + const VkDescriptorPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorPool* pDescriptorPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + VkDescriptorPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets( + VkDevice device, + const VkDescriptorSetAllocateInfo* pAllocateInfo, + VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets( + VkDevice device, + VkDescriptorPool descriptorPool, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( + VkDevice device, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites, + uint32_t descriptorCopyCount, + const VkCopyDescriptorSet* pDescriptorCopies); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer( + VkDevice device, + const VkFramebufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFramebuffer* pFramebuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer( + VkDevice device, + VkFramebuffer framebuffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass( + VkDevice device, + const VkRenderPassCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass( + VkDevice device, + VkRenderPass renderPass, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( + VkDevice device, + VkRenderPass renderPass, + VkExtent2D* pGranularity); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool( + VkDevice device, + const VkCommandPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCommandPool* pCommandPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool( + VkDevice device, + VkCommandPool commandPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers( + VkDevice device, + const VkCommandBufferAllocateInfo* pAllocateInfo, + VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers( + VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer( + VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo* pBeginInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer( + VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor( + VkCommandBuffer commandBuffer, + uint32_t firstScissor, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth( + VkCommandBuffer commandBuffer, + float lineWidth); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias( + VkCommandBuffer commandBuffer, + float depthBiasConstantFactor, + float depthBiasClamp, + float depthBiasSlopeFactor); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants( + VkCommandBuffer commandBuffer, + const float blendConstants[4]); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds( + VkCommandBuffer commandBuffer, + float minDepthBounds, + float maxDepthBounds); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t compareMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t writeMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t reference); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t* pDynamicOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkIndexType indexType); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdDraw( + VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed( + VkCommandBuffer commandBuffer, + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( + VkCommandBuffer commandBuffer, + uint32_t x, + uint32_t y, + uint32_t z); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageBlit* pRegions, + VkFilter filter); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize dataSize, + const uint32_t* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue* pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment* pAttachments, + uint32_t rectCount, + const VkClearRect* pRects); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp( + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants( + VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, + uint32_t offset, + uint32_t size, + const void* pValues); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( + VkCommandBuffer commandBuffer, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); +#endif + +#define VK_KHR_surface 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#define VK_KHR_SURFACE_SPEC_VERSION 25 +#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" + + +typedef enum VkColorSpaceKHR { + VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLORSPACE_SRGB_NONLINEAR_KHR, + VK_COLOR_SPACE_END_RANGE_KHR = VK_COLORSPACE_SRGB_NONLINEAR_KHR, + VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLORSPACE_SRGB_NONLINEAR_KHR - VK_COLORSPACE_SRGB_NONLINEAR_KHR + 1), + VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkColorSpaceKHR; + +typedef enum VkPresentModeKHR { + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR, + VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + VK_PRESENT_MODE_RANGE_SIZE_KHR = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1), + VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentModeKHR; + + +typedef enum VkSurfaceTransformFlagBitsKHR { + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, + VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, + VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, + VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, + VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkSurfaceTransformFlagBitsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; + +typedef enum VkCompositeAlphaFlagBitsKHR { + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, + VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkCompositeAlphaFlagBitsKHR; +typedef VkFlags VkCompositeAlphaFlagsKHR; + +typedef struct VkSurfaceCapabilitiesKHR { + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; +} VkSurfaceCapabilitiesKHR; + +typedef struct VkSurfaceFormatKHR { + VkFormat format; + VkColorSpaceKHR colorSpace; +} VkSurfaceFormatKHR; + + +typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( + VkInstance instance, + VkSurfaceKHR surface, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32* pSupported); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormatKHR* pSurfaceFormats); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pPresentModeCount, + VkPresentModeKHR* pPresentModes); +#endif + +#define VK_KHR_swapchain 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) + +#define VK_KHR_SWAPCHAIN_SPEC_VERSION 68 +#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" + +typedef VkFlags VkSwapchainCreateFlagsKHR; + +typedef struct VkSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR oldSwapchain; +} VkSwapchainCreateInfoKHR; + +typedef struct VkPresentInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t swapchainCount; + const VkSwapchainKHR* pSwapchains; + const uint32_t* pImageIndices; + VkResult* pResults; +} VkPresentInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); +typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); +typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( + VkDevice device, + const VkSwapchainCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchain); + +VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( + VkDevice device, + VkSwapchainKHR swapchain, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pSwapchainImageCount, + VkImage* pSwapchainImages); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t timeout, + VkSemaphore semaphore, + VkFence fence, + uint32_t* pImageIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( + VkQueue queue, + const VkPresentInfoKHR* pPresentInfo); +#endif + +#define VK_KHR_display 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) + +#define VK_KHR_DISPLAY_SPEC_VERSION 21 +#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" + + +typedef enum VkDisplayPlaneAlphaFlagBitsKHR { + VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008, + VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDisplayPlaneAlphaFlagBitsKHR; +typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; +typedef VkFlags VkDisplayModeCreateFlagsKHR; +typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; + +typedef struct VkDisplayPropertiesKHR { + VkDisplayKHR display; + const char* displayName; + VkExtent2D physicalDimensions; + VkExtent2D physicalResolution; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkBool32 planeReorderPossible; + VkBool32 persistentContent; +} VkDisplayPropertiesKHR; + +typedef struct VkDisplayModeParametersKHR { + VkExtent2D visibleRegion; + uint32_t refreshRate; +} VkDisplayModeParametersKHR; + +typedef struct VkDisplayModePropertiesKHR { + VkDisplayModeKHR displayMode; + VkDisplayModeParametersKHR parameters; +} VkDisplayModePropertiesKHR; + +typedef struct VkDisplayModeCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplayModeCreateFlagsKHR flags; + VkDisplayModeParametersKHR parameters; +} VkDisplayModeCreateInfoKHR; + +typedef struct VkDisplayPlaneCapabilitiesKHR { + VkDisplayPlaneAlphaFlagsKHR supportedAlpha; + VkOffset2D minSrcPosition; + VkOffset2D maxSrcPosition; + VkExtent2D minSrcExtent; + VkExtent2D maxSrcExtent; + VkOffset2D minDstPosition; + VkOffset2D maxDstPosition; + VkExtent2D minDstExtent; + VkExtent2D maxDstExtent; +} VkDisplayPlaneCapabilitiesKHR; + +typedef struct VkDisplayPlanePropertiesKHR { + VkDisplayKHR currentDisplay; + uint32_t currentStackIndex; +} VkDisplayPlanePropertiesKHR; + +typedef struct VkDisplaySurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplaySurfaceCreateFlagsKHR flags; + VkDisplayModeKHR displayMode; + uint32_t planeIndex; + uint32_t planeStackIndex; + VkSurfaceTransformFlagBitsKHR transform; + float globalAlpha; + VkDisplayPlaneAlphaFlagBitsKHR alphaMode; + VkExtent2D imageExtent; +} VkDisplaySurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPlanePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( + VkPhysicalDevice physicalDevice, + uint32_t planeIndex, + uint32_t* pDisplayCount, + VkDisplayKHR* pDisplays); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + uint32_t* pPropertyCount, + VkDisplayModePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + const VkDisplayModeCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDisplayModeKHR* pMode); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayModeKHR mode, + uint32_t planeIndex, + VkDisplayPlaneCapabilitiesKHR* pCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( + VkInstance instance, + const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#define VK_KHR_display_swapchain 1 +#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 9 +#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" + +typedef struct VkDisplayPresentInfoKHR { + VkStructureType sType; + const void* pNext; + VkRect2D srcRect; + VkRect2D dstRect; + VkBool32 persistent; +} VkDisplayPresentInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( + VkDevice device, + uint32_t swapchainCount, + const VkSwapchainCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchains); +#endif + +#ifdef VK_USE_PLATFORM_XLIB_KHR +#define VK_KHR_xlib_surface 1 +#include + +#define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 +#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" + +typedef VkFlags VkXlibSurfaceCreateFlagsKHR; + +typedef struct VkXlibSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkXlibSurfaceCreateFlagsKHR flags; + Display* dpy; + Window window; +} VkXlibSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( + VkInstance instance, + const VkXlibSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + Display* dpy, + VisualID visualID); +#endif +#endif /* VK_USE_PLATFORM_XLIB_KHR */ + +#ifdef VK_USE_PLATFORM_XCB_KHR +#define VK_KHR_xcb_surface 1 +#include + +#define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 +#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" + +typedef VkFlags VkXcbSurfaceCreateFlagsKHR; + +typedef struct VkXcbSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkXcbSurfaceCreateFlagsKHR flags; + xcb_connection_t* connection; + xcb_window_t window; +} VkXcbSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( + VkInstance instance, + const VkXcbSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t* connection, + xcb_visualid_t visual_id); +#endif +#endif /* VK_USE_PLATFORM_XCB_KHR */ + +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +#define VK_KHR_wayland_surface 1 +#include + +#define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 5 +#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" + +typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; + +typedef struct VkWaylandSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkWaylandSurfaceCreateFlagsKHR flags; + struct wl_display* display; + struct wl_surface* surface; +} VkWaylandSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( + VkInstance instance, + const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct wl_display* display); +#endif +#endif /* VK_USE_PLATFORM_WAYLAND_KHR */ + +#ifdef VK_USE_PLATFORM_MIR_KHR +#define VK_KHR_mir_surface 1 +#include + +#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4 +#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface" + +typedef VkFlags VkMirSurfaceCreateFlagsKHR; + +typedef struct VkMirSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkMirSurfaceCreateFlagsKHR flags; + MirConnection* connection; + MirSurface* mirSurface; +} VkMirSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( + VkInstance instance, + const VkMirSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + MirConnection* connection); +#endif +#endif /* VK_USE_PLATFORM_MIR_KHR */ + +#ifdef VK_USE_PLATFORM_ANDROID_KHR +#define VK_KHR_android_surface 1 +#include + +#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6 +#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface" + +typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; + +typedef struct VkAndroidSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkAndroidSurfaceCreateFlagsKHR flags; + ANativeWindow* window; +} VkAndroidSurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( + VkInstance instance, + const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif +#endif /* VK_USE_PLATFORM_ANDROID_KHR */ + +#ifdef VK_USE_PLATFORM_WIN32_KHR +#define VK_KHR_win32_surface 1 +#include + +#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 5 +#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" + +typedef VkFlags VkWin32SurfaceCreateFlagsKHR; + +typedef struct VkWin32SurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkWin32SurfaceCreateFlagsKHR flags; + HINSTANCE hinstance; + HWND hwnd; +} VkWin32SurfaceCreateInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( + VkInstance instance, + const VkWin32SurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex); +#endif +#endif /* VK_USE_PLATFORM_WIN32_KHR */ + +#define VK_KHR_sampler_mirror_clamp_to_edge 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" + + +#define VK_EXT_debug_report 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) + +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 2 +#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" +#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT + + +typedef enum VkDebugReportObjectTypeEXT { + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, + VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, + VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, + VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, + VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, + VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, + VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, + VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, + VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, + VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, + VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, + VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, + VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = 28, + VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1), + VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportObjectTypeEXT; + +typedef enum VkDebugReportErrorEXT { + VK_DEBUG_REPORT_ERROR_NONE_EXT = 0, + VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT = 1, + VK_DEBUG_REPORT_ERROR_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_ERROR_NONE_EXT, + VK_DEBUG_REPORT_ERROR_END_RANGE_EXT = VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT, + VK_DEBUG_REPORT_ERROR_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT - VK_DEBUG_REPORT_ERROR_NONE_EXT + 1), + VK_DEBUG_REPORT_ERROR_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportErrorEXT; + + +typedef enum VkDebugReportFlagBitsEXT { + VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001, + VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002, + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004, + VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, + VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, + VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportFlagBitsEXT; +typedef VkFlags VkDebugReportFlagsEXT; + +typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData); + + +typedef struct VkDebugReportCallbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportFlagsEXT flags; + PFN_vkDebugReportCallbackEXT pfnCallback; + void* pUserData; +} VkDebugReportCallbackCreateInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugReportCallbackEXT* pCallback); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( + VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage); +#endif + +#define VK_NV_glsl_shader 1 +#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 +#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" + + +#define VK_IMG_filter_cubic 1 +#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1 +#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extern/glfw-3.2.1/docs/CMakeLists.txt b/extern/glfw-3.2.1/docs/CMakeLists.txt new file mode 100644 index 0000000..c030ac7 --- /dev/null +++ b/extern/glfw-3.2.1/docs/CMakeLists.txt @@ -0,0 +1,32 @@ + +set(glfw_DOCS_SOURCES + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h" + "${GLFW_SOURCE_DIR}/docs/main.dox" + "${GLFW_SOURCE_DIR}/docs/news.dox" + "${GLFW_SOURCE_DIR}/docs/moving.dox" + "${GLFW_SOURCE_DIR}/docs/quick.dox" + "${GLFW_SOURCE_DIR}/docs/compile.dox" + "${GLFW_SOURCE_DIR}/docs/build.dox" + "${GLFW_SOURCE_DIR}/docs/intro.dox" + "${GLFW_SOURCE_DIR}/docs/context.dox" + "${GLFW_SOURCE_DIR}/docs/monitor.dox" + "${GLFW_SOURCE_DIR}/docs/window.dox" + "${GLFW_SOURCE_DIR}/docs/input.dox" + "${GLFW_SOURCE_DIR}/docs/vulkan.dox" + "${GLFW_SOURCE_DIR}/docs/compat.dox") + +if (GLFW_DOCUMENT_INTERNALS) + list(APPEND glfw_DOCS_SOURCES "${GLFW_SOURCE_DIR}/src/internal.h") +endif() + +foreach(arg ${glfw_DOCS_SOURCES}) + set(GLFW_DOCS_SOURCES "${GLFW_DOCS_SOURCES} ${arg}") +endforeach() + +configure_file(Doxyfile.in Doxyfile @ONLY) + +add_custom_target(docs ALL "${DOXYGEN_EXECUTABLE}" + WORKING_DIRECTORY "${GLFW_BINARY_DIR}/docs" + COMMENT "Generating HTML documentation" VERBATIM) + diff --git a/extern/glfw-3.2.1/docs/Doxyfile.in b/extern/glfw-3.2.1/docs/Doxyfile.in new file mode 100644 index 0000000..b046f89 --- /dev/null +++ b/extern/glfw-3.2.1/docs/Doxyfile.in @@ -0,0 +1,1859 @@ +# Doxyfile 1.8.3.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "GLFW" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @GLFW_VERSION_FULL@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "A multi-platform library for OpenGL, window and input" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = @GLFW_BINARY_DIR@/docs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = "thread_safety=@par Thread safety\n" \ + "pointer_lifetime=@par Pointer lifetime\n" \ + "analysis=@par Analysis\n" \ + "reentrancy=@par Reentrancy\n" \ + "errors=@par Errors\n" \ + "glfw3=@par\n__GLFW 3:__" \ + "x11=__X11:__" \ + "win32=__Windows:__" \ + "osx=__OS X:__" + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented classes, +# or namespaces to their corresponding documentation. Such a link can be +# prevented in individual cases by by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = @GLFW_BINARY_DIR@/docs/warnings.txt + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @GLFW_DOCS_SOURCES@ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.h *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = APIENTRY GLFWAPI + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = @GLFW_SOURCE_DIR@/examples + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page (index.html). +# This can be useful if you have a project on for instance GitHub and want reuse +# the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = glfw GLFW_ + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = @GLFW_SOURCE_DIR@/docs/header.html + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = @GLFW_SOURCE_DIR@/docs/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = @GLFW_SOURCE_DIR@/docs/extra.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = @GLFW_SOURCE_DIR@/docs/spaces.svg + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 300 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search engine +# library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = GLFWAPI= \ + GLFW_EXPOSE_NATIVE_WIN32 \ + GLFW_EXPOSE_NATIVE_WGL \ + GLFW_EXPOSE_NATIVE_X11 \ + GLFW_EXPOSE_NATIVE_WAYLAND \ + GLFW_EXPOSE_NATIVE_MIR \ + GLFW_EXPOSE_NATIVE_GLX \ + GLFW_EXPOSE_NATIVE_COCOA \ + GLFW_EXPOSE_NATIVE_NSGL \ + GLFW_EXPOSE_NATIVE_EGL \ + VK_VERSION_1_0 + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/extern/glfw-3.2.1/docs/DoxygenLayout.xml b/extern/glfw-3.2.1/docs/DoxygenLayout.xml new file mode 100644 index 0000000..7917f91 --- /dev/null +++ b/extern/glfw-3.2.1/docs/DoxygenLayout.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extern/glfw-3.2.1/docs/build.dox b/extern/glfw-3.2.1/docs/build.dox new file mode 100644 index 0000000..ff9ed86 --- /dev/null +++ b/extern/glfw-3.2.1/docs/build.dox @@ -0,0 +1,347 @@ +/*! + +@page build_guide Building applications + +@tableofcontents + +This is about compiling and linking applications that use GLFW. For information on +how to write such applications, start with the +[introductory tutorial](@ref quick_guide). For information on how to compile +the GLFW library itself, see @ref compile_guide. + +This is not a tutorial on compilation or linking. It assumes basic +understanding of how to compile and link a C program as well as how to use the +specific compiler of your chosen development environment. The compilation +and linking process should be explained in your C programming material and in +the documentation for your development environment. + +@section build_include Including the GLFW header file + +In the source files of your application where you use OpenGL or GLFW, you should +include the GLFW header file, i.e.: + +@code +#include +@endcode + +The GLFW header declares the GLFW API and by default also includes the OpenGL +header of your development environment, which in turn defines all the constants, +types and function prototypes of the OpenGL API. + +The GLFW header also defines everything necessary for your OpenGL header to +function. For example, under Windows you are normally required to include +`windows.h` before the OpenGL header, which would pollute your code namespace +with the entire Win32 API. + +Instead, the GLFW header takes care of this for you, not by including +`windows.h`, but by duplicating only the very few necessary parts of it. It +does this only when needed, so if `windows.h` _is_ included, the GLFW header +does not try to redefine those symbols. The reverse is not true, i.e. +`windows.h` cannot cope if any of its symbols have already been defined. + +In other words: + + - Do _not_ include the OpenGL headers yourself, as GLFW does this for you + - Do _not_ include `windows.h` or other platform-specific headers unless you + plan on using those APIs directly + - If you _do_ need to include such headers, do it _before_ including + the GLFW header and it will handle this + +If you are using an OpenGL extension loading library such as +[glad](https://github.com/Dav1dde/glad), the extension loader header should +either be included _before_ the GLFW one, or the `GLFW_INCLUDE_NONE` macro +(described below) should be defined. + + +@subsection build_macros GLFW header option macros + +These macros may be defined before the inclusion of the GLFW header and affect +its behavior. + +`GLFW_DLL` is required on Windows when using the GLFW DLL, to tell the compiler +that the GLFW functions are defined in a DLL. + +The following macros control which OpenGL or OpenGL ES API header is included. +Only one of these may be defined at a time. + +`GLFW_INCLUDE_GLCOREARB` makes the GLFW header include the modern +`GL/glcorearb.h` header (`OpenGL/gl3.h` on OS X) instead of the regular OpenGL +header. + +`GLFW_INCLUDE_ES1` makes the GLFW header include the OpenGL ES 1.x `GLES/gl.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_ES2` makes the GLFW header include the OpenGL ES 2.0 `GLES2/gl2.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_ES3` makes the GLFW header include the OpenGL ES 3.0 `GLES3/gl3.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_ES31` makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_VULKAN` makes the GLFW header include the Vulkan `vulkan/vulkan.h` +header instead of the regular OpenGL header. + +`GLFW_INCLUDE_NONE` makes the GLFW header not include any OpenGL or OpenGL ES API +header. This is useful in combination with an extension loading library. + +If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h` +header (`OpenGL/gl.h` on OS X) is included. + +The following macros control the inclusion of additional API headers. Any +number of these may be defined simultaneously, and/or together with one of the +above macros. + +`GLFW_INCLUDE_GLEXT` makes the GLFW header include the appropriate extension +header for the OpenGL or OpenGL ES header selected above after and in addition +to that header. + +`GLFW_INCLUDE_GLU` makes the header include the GLU header in addition to the +header selected above. This should only be used with the standard OpenGL header +and only for compatibility with legacy code. GLU has been deprecated and should +not be used in new code. + +@note GLFW does not provide any of the API headers mentioned above. They must +be provided by your development environment or your OpenGL, OpenGL ES or Vulkan +SDK. + +@note None of these macros may be defined during the compilation of GLFW itself. +If your build includes GLFW and you define any these in your build files, make +sure they are not applied to the GLFW sources. + + +@section build_link Link with the right libraries + +GLFW is essentially a wrapper of various platform-specific APIs and therefore +needs to link against many different system libraries. If you are using GLFW as +a shared library / dynamic library / DLL then it takes care of these links. +However, if you are using GLFW as a static library then your executable will +need to link against these libraries. + +On Windows and OS X, the list of system libraries is static and can be +hard-coded into your build environment. See the section for your development +environment below. On Linux and other Unix-like operating systems, the list +varies but can be retrieved in various ways as described below. + +A good general introduction to linking is +[Beginner's Guide to Linkers](http://www.lurklurk.org/linkers/linkers.html) by +David Drysdale. + + +@subsection build_link_win32 With MinGW or Visual C++ on Windows + +The static version of the GLFW library is named `glfw3`. When using this +version, it is also necessary to link with some libraries that GLFW uses. + +When linking an application under Windows that uses the static version of GLFW, +you must link with `opengl32`. On some versions of MinGW, you must also +explicitly link with `gdi32`, while other versions of MinGW include it in the +set of default libraries along with other dependencies like `user32` and +`kernel32`. If you are using GLU, you must also link with `glu32`. + +The link library for the GLFW DLL is named `glfw3dll`. When compiling an +application that uses the DLL version of GLFW, you need to define the `GLFW_DLL` +macro _before_ any inclusion of the GLFW header. This can be done either with +a compiler switch or by defining it in your source code. + +An application using the GLFW DLL does not need to link against any of its +dependencies, but you still have to link against `opengl32` if your application +uses OpenGL and `glu32` if it uses GLU. + + +@subsection build_link_cmake_source With CMake and GLFW source + +This section is about using CMake to compile and link GLFW along with your +application. If you want to use an installed binary instead, see @ref +build_link_cmake_package. + +With just a few changes to your `CMakeLists.txt` you can have the GLFW source +tree built along with your application. + +When including GLFW as part of your build, you probably don't want to build the +GLFW tests, examples and documentation. To disable these, set the corresponding +cache variables before adding the GLFW source tree. + +@code +set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +@endcode + +Then add the root directory of the GLFW source tree to your project. This +will add the `glfw` target and the necessary cache variables to your project. + +@code{.cmake} +add_subdirectory(path/to/glfw) +@endcode + +Once GLFW has been added to the project, link against it with the `glfw` target. +This adds all link-time dependencies of GLFW as it is currently configured, +the include directory for the GLFW header and, when applicable, the +[GLFW_DLL](@ref build_macros) macro. + +@code{.cmake} +target_link_libraries(myapp glfw) +@endcode + +Note that the dependencies do not include OpenGL or GLU, as GLFW loads any +OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU. +If your application calls OpenGL directly, instead of using a modern +[extension loader library](@ref context_glext_auto) you can find it by requiring +the OpenGL package. + +@code{.cmake} +find_package(OpenGL REQUIRED) +@endcode + +If OpenGL is found, the `OPENGL_FOUND` variable is true and the +`OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used. + +@code{.cmake} +target_include_directories(myapp ${OPENGL_INCLUDE_DIR}) +target_link_libraries(myapp ${OPENGL_gl_LIBRARY}) +@endcode + +The OpenGL CMake package also looks for GLU. If GLU is found, the +`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and +`OPENGL_glu_LIBRARY` cache variables can be used. + +@code{.cmake} +target_link_libraries(myapp ${OPENGL_glu_LIBRARY}) +@endcode + +@note GLU has been deprecated and should not be used in new code, but some +legacy code requires it. + + +@subsection build_link_cmake_package With CMake and installed GLFW binaries + +This section is about using CMake to link GLFW after it has been built and +installed. If you want to build it along with your application instead, see +@ref build_link_cmake_source. + +With just a few changes to your `CMakeLists.txt`, you can locate the package and +target files generated when GLFW is installed. + +@code{.cmake} +find_package(glfw3 3.2 REQUIRED) +@endcode + +Note that the dependencies do not include OpenGL or GLU, as GLFW loads any +OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU. +If your application calls OpenGL directly, instead of using a modern +[extension loader library](@ref context_glext_auto) you can find it by requiring +the OpenGL package. + +@code{.cmake} +find_package(OpenGL REQUIRED) +@endcode + +If OpenGL is found, the `OPENGL_FOUND` variable is true and the +`OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used. + +@code{.cmake} +target_include_directories(myapp ${OPENGL_INCLUDE_DIR}) +target_link_libraries(myapp ${OPENGL_gl_LIBRARY}) +@endcode + +The OpenGL CMake package also looks for GLU. If GLU is found, the +`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and +`OPENGL_glu_LIBRARY` cache variables can be used. + +@code{.cmake} +target_link_libraries(myapp ${OPENGL_glu_LIBRARY}) +@endcode + +@note GLU has been deprecated and should not be used in new code, but some +legacy code requires it. + + +@subsection build_link_pkgconfig With makefiles and pkg-config on Unix + +GLFW supports [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/), +and the `glfw3.pc` pkg-config file is generated when the GLFW library is built +and is installed along with it. A pkg-config file describes all necessary +compile-time and link-time flags and dependencies needed to use a library. When +they are updated or if they differ between systems, you will get the correct +ones automatically. + +A typical compile and link command-line when using the static version of the +GLFW library may look like this: + +@code{.sh} +cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --static --libs glfw3` +@endcode + +If you are using the shared version of the GLFW library, simply omit the +`--static` flag. + +@code{.sh} +cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` +@endcode + +You can also use the `glfw3.pc` file without installing it first, by using the +`PKG_CONFIG_PATH` environment variable. + +@code{.sh} +env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` +@endcode + +The dependencies do not include OpenGL or GLU, as GLFW loads any OpenGL, OpenGL +ES or Vulkan libraries it needs at runtime and does not use GLU. On OS X, GLU +is built into the OpenGL framework, so if you need GLU you don't need to do +anything extra. If you need GLU and are using Linux or BSD, you should add the +`glu` pkg-config package. + +@code{.sh} +cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu` +@endcode + +@note GLU has been deprecated and should not be used in new code, but some +legacy code requires it. + +If you are using the static version of the GLFW library, make sure you don't +link statically against GLU. + +@code{.sh} +cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --static --libs glfw3` `pkg-config --libs glu` +@endcode + + +@subsection build_link_xcode With Xcode on OS X + +If you are using the dynamic library version of GLFW, simply add it to the +project dependencies. + +If you are using the static library version of GLFW, add it and the Cocoa, +OpenGL, IOKit and CoreVideo frameworks to the project as dependencies. They can +all be found in `/System/Library/Frameworks`. + + +@subsection build_link_osx With command-line on OS X + +It is recommended that you use [pkg-config](@ref build_link_pkgconfig) when +building from the command line on OS X. That way you will get any new +dependencies added automatically. If you still wish to build manually, you need +to add the required frameworks and libraries to your command-line yourself using +the `-l` and `-framework` switches. + +If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do: + +@code{.sh} +cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo +@endcode + +If you are using the static library, named `libglfw3.a`, substitute `-lglfw3` +for `-lglfw`. + +Note that you do not add the `.framework` extension to a framework when linking +against it from the command-line. + +The OpenGL framework contains both the OpenGL and GLU APIs, so there is nothing +special to do when using GLU. Also note that even though your machine may have +`libGL`-style OpenGL libraries, they are for use with the X Window System and +will _not_ work with the OS X native version of GLFW. + +*/ diff --git a/extern/glfw-3.2.1/docs/compat.dox b/extern/glfw-3.2.1/docs/compat.dox new file mode 100644 index 0000000..175036b --- /dev/null +++ b/extern/glfw-3.2.1/docs/compat.dox @@ -0,0 +1,224 @@ +/*! + +@page compat_guide Standards conformance + +@tableofcontents + +This guide describes the various API extensions used by this version of GLFW. +It lists what are essentially implementation details, but which are nonetheless +vital knowledge for developers intending to deploy their applications on a wide +range of machines. + +The information in this guide is not a part of GLFW API, but merely +preconditions for some parts of the library to function on a given machine. Any +part of this information may change in future versions of GLFW and that will not +be considered a breaking API change. + + +@section compat_x11 X11 extensions, protocols and IPC standards + +As GLFW uses Xlib directly, without any intervening toolkit +library, it has sole responsibility for interacting well with the many and +varied window managers in use on Unix-like systems. In order for applications +and window managers to work well together, a number of standards and +conventions have been developed that regulate behavior outside the scope of the +X11 API; most importantly the +[Inter-Client Communication Conventions Manual](http://www.tronche.com/gui/x/icccm/) +(ICCCM) and +[Extended Window Manager Hints](http://standards.freedesktop.org/wm-spec/wm-spec-latest.html) +(EWMH) standards. + +GLFW uses the `_MOTIF_WM_HINTS` window property to support borderless windows. +If the running window manager does not support this property, the +`GLFW_DECORATED` hint will have no effect. + +GLFW uses the ICCCM `WM_DELETE_WINDOW` protocol to intercept the user +attempting to close the GLFW window. If the running window manager does not +support this protocol, the close callback will never be called. + +GLFW uses the EWMH `_NET_WM_PING` protocol, allowing the window manager notify +the user when the application has stopped responding, i.e. when it has ceased to +process events. If the running window manager does not support this protocol, +the user will not be notified if the application locks up. + +GLFW uses the EWMH `_NET_WM_STATE_FULLSCREEN` window state to tell the window +manager to make the GLFW window full screen. If the running window manager does +not support this state, full screen windows may not work properly. GLFW has +a fallback code path in case this state is unavailable, but every window manager +behaves slightly differently in this regard. + +GLFW uses the EWMH `_NET_WM_BYPASS_COMPOSITOR` window property to tell a +compositing window manager to un-redirect full screen GLFW windows. If the +running window manager uses compositing but does not support this property then +additional copying may be performed for each buffer swap of full screen windows. + +GLFW uses the +[clipboard manager protocol](http://www.freedesktop.org/wiki/ClipboardManager/) +to push a clipboard string (i.e. selection) owned by a GLFW window about to be +destroyed to the clipboard manager. If there is no running clipboard manager, +the clipboard string will be unavailable once the window has been destroyed. + +GLFW uses the +[X drag-and-drop protocol](http://www.freedesktop.org/wiki/Specifications/XDND/) +to provide file drop events. If the application originating the drag does not +support this protocol, drag and drop will not work. + +GLFW uses the XRandR 1.3 extension to provide multi-monitor support. If the +running X server does not support this version of this extension, multi-monitor +support will not function and only a single, desktop-spanning monitor will be +reported. + +GLFW uses the XRandR 1.3 and Xf86vidmode extensions to provide gamma ramp +support. If the running X server does not support either or both of these +extensions, gamma ramp support will not function. + +GLFW uses the Xkb extension and detectable auto-repeat to provide keyboard +input. If the running X server does not support this extension, a non-Xkb +fallback path is used. + + +@section compat_glx GLX extensions + +The GLX API is the default API used to create OpenGL contexts on Unix-like +systems using the X Window System. + +GLFW uses the GLX 1.3 `GLXFBConfig` functions to enumerate and select framebuffer pixel +formats. If GLX 1.3 is not supported, @ref glfwInit will fail. + +GLFW uses the `GLX_MESA_swap_control,` `GLX_EXT_swap_control` and +`GLX_SGI_swap_control` extensions to provide vertical retrace synchronization +(or _vsync_), in that order of preference. Where none of these extension are +available, calling @ref glfwSwapInterval will have no effect. + +GLFW uses the `GLX_ARB_multisample` extension to create contexts with +multisampling anti-aliasing. Where this extension is unavailable, the +`GLFW_SAMPLES` hint will have no effect. + +GLFW uses the `GLX_ARB_create_context` extension when available, even when +creating OpenGL contexts of version 2.1 and below. Where this extension is +unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` +hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint +will have no effect, and setting the `GLFW_OPENGL_PROFILE` or +`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref +glfwCreateWindow to fail. + +GLFW uses the `GLX_ARB_create_context_profile` extension to provide support for +context profiles. Where this extension is unavailable, setting the +`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE`, or setting +`GLFW_CLIENT_API` to anything but `GLFW_OPENGL_API` or `GLFW_NO_API` will cause +@ref glfwCreateWindow to fail. + +GLFW uses the `GLX_ARB_context_flush_control` extension to provide control over +whether a context is flushed when it is released (made non-current). Where this +extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no +effect and the context will always be flushed when released. + +GLFW uses the `GLX_ARB_framebuffer_sRGB` and `GLX_EXT_framebuffer_sRGB` +extensions to provide support for sRGB framebuffers. Where both of these +extensions are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. + + +@section compat_wgl WGL extensions + +The WGL API is used to create OpenGL contexts on Microsoft Windows and other +implementations of the Win32 API, such as Wine. + +GLFW uses either the `WGL_EXT_extension_string` or the +`WGL_ARB_extension_string` extension to check for the presence of all other WGL +extensions listed below. If both are available, the EXT one is preferred. If +neither is available, no other extensions are used and many GLFW features +related to context creation will have no effect or cause errors when used. + +GLFW uses the `WGL_EXT_swap_control` extension to provide vertical retrace +synchronization (or _vsync_). Where this extension is unavailable, calling @ref +glfwSwapInterval will have no effect. + +GLFW uses the `WGL_ARB_pixel_format` and `WGL_ARB_multisample` extensions to +create contexts with multisampling anti-aliasing. Where these extensions are +unavailable, the `GLFW_SAMPLES` hint will have no effect. + +GLFW uses the `WGL_ARB_create_context` extension when available, even when +creating OpenGL contexts of version 2.1 and below. Where this extension is +unavailable, the `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` +hints will only be partially supported, the `GLFW_OPENGL_DEBUG_CONTEXT` hint +will have no effect, and setting the `GLFW_OPENGL_PROFILE` or +`GLFW_OPENGL_FORWARD_COMPAT` hints to `GLFW_TRUE` will cause @ref +glfwCreateWindow to fail. + +GLFW uses the `WGL_ARB_create_context_profile` extension to provide support for +context profiles. Where this extension is unavailable, setting the +`GLFW_OPENGL_PROFILE` hint to anything but `GLFW_OPENGL_ANY_PROFILE` will cause +@ref glfwCreateWindow to fail. + +GLFW uses the `WGL_ARB_context_flush_control` extension to provide control over +whether a context is flushed when it is released (made non-current). Where this +extension is unavailable, the `GLFW_CONTEXT_RELEASE_BEHAVIOR` hint will have no +effect and the context will always be flushed when released. + +GLFW uses the `WGL_ARB_framebuffer_sRGB` and `WGL_EXT_framebuffer_sRGB` +extensions to provide support for sRGB framebuffers. Where both of these +extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect. + + +@section compat_osx OpenGL 3.2 and later on OS X + +Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then +only forward-compatible, core profile contexts are supported. Support for +OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible, +core profile contexts. There is also still no mechanism for requesting debug +contexts. Versions of Mac OS X earlier than 10.7 support at most OpenGL +version 2.1. + +Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and +`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if +given version 3.0 or 3.1, the `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to +`GLFW_TRUE` and the `GLFW_OPENGL_PROFILE` hint must be set to +`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts and the +`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. + +Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and +`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1, +setting the `GLFW_OPENGL_PROFILE` or `GLFW_OPENGL_FORWARD_COMPAT` hints to +a non-default value will cause @ref glfwCreateWindow to fail and the +`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored. + + +@section compat_vulkan Vulkan loader and API + +GLFW uses the standard system-wide Vulkan loader to access the Vulkan API. +This should be installed by graphics drivers and Vulkan SDKs. If this is not +available, @ref glfwVulkanSupported will return `GLFW_FALSE` and all other +Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE error. + + +@section compat_wsi Vulkan WSI extensions + +The Vulkan WSI extensions are used to create Vulkan surfaces for GLFW windows on +all supported platforms. + +GLFW uses the `VK_KHR_surface` and `VK_KHR_win32_surface` extensions to create +surfaces on Microsoft Windows. If any of these extensions are not available, +@ref glfwGetRequiredInstanceExtensions will return an empty list and window +surface creation will fail. + +GLFW uses the `VK_KHR_surface` and either the `VK_KHR_xlib_surface` or +`VK_KHR_xcb_surface` extensions to create surfaces on X11. If `VK_KHR_surface` +or both `VK_KHR_xlib_surface` and `VK_KHR_xcb_surface` are not available, @ref +glfwGetRequiredInstanceExtensions will return an empty list and window surface +creation will fail. + +GLFW uses the `VK_KHR_surface` and `VK_KHR_wayland_surface` extensions to create +surfaces on Wayland. If any of these extensions are not available, @ref +glfwGetRequiredInstanceExtensions will return an empty list and window surface +creation will fail. + +GLFW uses the `VK_KHR_surface` and `VK_KHR_mir_surface` extensions to create +surfaces on Mir. If any of these extensions are not available, @ref +glfwGetRequiredInstanceExtensions will return an empty list and window surface +creation will fail. + +GLFW does not support any extensions for window surface creation on OS X, +meaning@ref glfwGetRequiredInstanceExtensions will return an empty list and +window surface creation will fail. + +*/ diff --git a/extern/glfw-3.2.1/docs/compile.dox b/extern/glfw-3.2.1/docs/compile.dox new file mode 100644 index 0000000..c77a26c --- /dev/null +++ b/extern/glfw-3.2.1/docs/compile.dox @@ -0,0 +1,284 @@ +/*! + +@page compile_guide Compiling GLFW + +@tableofcontents + +This is about compiling the GLFW library itself. For information on how to +build applications that use GLFW, see @ref build_guide. + + +@section compile_cmake Using CMake + +GLFW uses [CMake](http://www.cmake.org/) to generate project files or makefiles +for a particular development environment. If you are on a Unix-like system such +as Linux or FreeBSD or have a package system like Fink, MacPorts, Cygwin or +Homebrew, you can simply install its CMake package. If not, you can download +installers for Windows and OS X from the [CMake website](http://www.cmake.org/). + +@note CMake only generates project files or makefiles. It does not compile the +actual GLFW library. To compile GLFW, first generate these files for your +chosen development environment and then use them to compile the actual GLFW +library. + + +@subsection compile_deps Dependencies + +Once you have installed CMake, make sure that all other dependencies are +available. On some platforms, GLFW needs a few additional packages to be +installed. See the section for your chosen platform and development environment +below. + + +@subsubsection compile_deps_msvc Dependencies for Visual C++ on Windows + +The Microsoft Platform SDK that is installed along with Visual C++ already +contains all the necessary headers, link libraries and tools except for CMake. +Move on to @ref compile_generate. + + +@subsubsection compile_deps_mingw Dependencies for MinGW or MinGW-w64 on Windows + +Both the MinGW and the MinGW-w64 packages already contain all the necessary +headers, link libraries and tools except for CMake. Move on to @ref +compile_generate. + + +@subsubsection compile_deps_mingw_cross Dependencies for MinGW or MinGW-w64 cross-compilation + +Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For +example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages +for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives +like Ubuntu have the `mingw-w64` package for both. + +GLFW has CMake toolchain files in the `CMake/` directory that allow for easy +cross-compilation of Windows binaries. To use these files you need to add a +special parameter when generating the project files or makefiles: + +@code{.sh} +cmake -DCMAKE_TOOLCHAIN_FILE= . +@endcode + +The exact toolchain file to use depends on the prefix used by the MinGW or +MinGW-w64 binaries on your system. You can usually see this in the /usr +directory. For example, both the Debian/Ubuntu and Cygwin MinGW-w64 packages +have `/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct +invocation would be: + +@code{.sh} +cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake . +@endcode + +For more details see the article +[CMake Cross Compiling](http://www.paraview.org/Wiki/CMake_Cross_Compiling) on +the CMake wiki. + +Once you have this set up, move on to @ref compile_generate. + + +@subsubsection compile_deps_xcode Dependencies for Xcode on OS X + +Xcode comes with all necessary tools except for CMake. The required headers +and libraries are included in the core OS X frameworks. Xcode can be downloaded +from the Mac App Store or from the ADC Member Center. + +Once you have Xcode installed, move on to @ref compile_generate. + + +@subsubsection compile_deps_x11 Dependencies for Linux and X11 + +To compile GLFW for X11, you need to have the X11 packages installed, as well as +the basic development tools like GCC and make. For example, on Ubuntu and other +distributions based on Debian GNU/Linux, you need to install the `xorg-dev` +package, which pulls in all X.org header packages. + +Once you have installed the necessary packages, move on to @ref +compile_generate. + + +@subsection compile_generate Generating build files with CMake + +Once you have all necessary dependencies it is time to generate the project +files or makefiles for your development environment. CMake needs to know two +paths for this: the path to the _root_ directory of the GLFW source tree (i.e. +_not_ the `src` subdirectory) and the target path for the generated files and +compiled binaries. If these are the same, it is called an in-tree build, +otherwise it is called an out-of-tree build. + +One of several advantages of out-of-tree builds is that you can generate files +and compile for different development environments using a single source tree. + +@note This section is about generating the project files or makefiles necessary +to compile the GLFW library, not about compiling the actual library. + + +@subsubsection compile_generate_cli Generating files with the CMake command-line tool + +To make an in-tree build, enter the _root_ directory of the GLFW source tree +(i.e. _not_ the `src` subdirectory) and run CMake. The current directory is +used as target path, while the path provided as an argument is used to find the +source tree. + +@code{.sh} +cd +cmake . +@endcode + +To make an out-of-tree build, make a directory outside of the source tree, enter +it and run CMake with the (relative or absolute) path to the root of the source +tree as an argument. + +@code{.sh} +mkdir glfw-build +cd glfw-build +cmake +@endcode + +Once you have generated the project files or makefiles for your chosen +development environment, move on to @ref compile_compile. + + +@subsubsection compile_generate_gui Generating files with the CMake GUI + +If you are using the GUI version, choose the root of the GLFW source tree as +source location and the same directory or another, empty directory as the +destination for binaries. Choose _Configure_, change any options you wish to, +_Configure_ again to let the changes take effect and then _Generate_. + +Once you have generated the project files or makefiles for your chosen +development environment, move on to @ref compile_compile. + + +@subsection compile_compile Compiling the library + +You should now have all required dependencies and the project files or makefiles +necessary to compile GLFW. Go ahead and compile the actual GLFW library with +these files, as you would with any other project. + +Once the GLFW library is compiled, you are ready to build your applications, +linking it to the GLFW library. See @ref build_guide for more information. + + +@subsection compile_options CMake options + +The CMake files for GLFW provide a number of options, although not all are +available on all supported platforms. Some of these are de facto standards +among projects using CMake and so have no `GLFW_` prefix. + +If you are using the GUI version of CMake, these are listed and can be changed +from there. If you are using the command-line version of CMake you can use the +`ccmake` ncurses GUI to set options. Some package systems like Ubuntu and other +distributions based on Debian GNU/Linux have this tool in a separate +`cmake-curses-gui` package. + +Finally, if you don't want to use any GUI, you can set options from the `cmake` +command-line with the `-D` flag. + +@code{.sh} +cmake -DBUILD_SHARED_LIBS=ON . +@endcode + + +@subsubsection compile_options_shared Shared CMake options + +`BUILD_SHARED_LIBS` determines whether GLFW is built as a static +library or as a DLL / shared library / dynamic library. + +`LIB_SUFFIX` affects where the GLFW shared /dynamic library is installed. If it +is empty, it is installed to `${CMAKE_INSTALL_PREFIX}/lib`. If it is set to +`64`, it is installed to `${CMAKE_INSTALL_PREFIX}/lib64`. + +`GLFW_BUILD_EXAMPLES` determines whether the GLFW examples are built +along with the library. + +`GLFW_BUILD_TESTS` determines whether the GLFW test programs are +built along with the library. + +`GLFW_BUILD_DOCS` determines whether the GLFW documentation is built along with +the library. + +`GLFW_VULKAN_STATIC` determines whether to use the Vulkan loader linked +statically into the application. + + +@subsubsection compile_options_osx OS X specific CMake options + +`GLFW_USE_CHDIR` determines whether `glfwInit` changes the current +directory of bundled applications to the `Contents/Resources` directory. + +`GLFW_USE_MENUBAR` determines whether the first call to +`glfwCreateWindow` sets up a minimal menu bar. + +`GLFW_USE_RETINA` determines whether windows will use the full resolution of +Retina displays. + + +@subsubsection compile_options_win32 Windows specific CMake options + +`USE_MSVC_RUNTIME_LIBRARY_DLL` determines whether to use the DLL version or the +static library version of the Visual C++ runtime library. If set to `ON`, the +DLL version of the Visual C++ library is used. + +`GLFW_USE_HYBRID_HPG` determines whether to export the `NvOptimusEnablement` and +`AmdPowerXpressRequestHighPerformance` symbols, which force the use of the +high-performance GPU on Nvidia Optimus and AMD PowerXpress systems. These symbols +need to be exported by the EXE to be detected by the driver, so the override +will not work if GLFW is built as a DLL. + + +@section compile_manual Compiling GLFW manually + +If you wish to compile GLFW without its CMake build environment then you will +have to do at least some of the platform detection yourself. GLFW needs +a configuration macro to be defined in order to know what window system it's +being compiled for and also has optional, platform-specific ones for various +features. + +When building with CMake, the `glfw_config.h` configuration header is generated +based on the current platform and CMake options. The GLFW CMake environment +defines `_GLFW_USE_CONFIG_H`, which causes this header to be included by +`internal.h`. Without this macro, GLFW will expect the necessary configuration +macros to be defined on the command-line. + +The window creation API is used to create windows, handle input, monitors, gamma +ramps and clipboard. The options are: + + - `_GLFW_COCOA` to use the Cocoa frameworks + - `_GLFW_WIN32` to use the Win32 API + - `_GLFW_X11` to use the X Window System + - `_GLFW_WAYLAND` to use the Wayland API (experimental and incomplete) + - `_GLFW_MIR` to use the Mir API (experimental and incomplete) + +If you are building GLFW as a shared library / dynamic library / DLL then you +must also define `_GLFW_BUILD_DLL`. Otherwise, you must not define it. + +If you are linking the Vulkan loader statically into your application then you +must also define `_GLFW_VULKAN_STATIC`. Otherwise, GLFW will attempt to use the +external version. + +For the EGL context creation API, the following options are available: + + - `_GLFW_USE_EGLPLATFORM_H` to use `EGL/eglplatform.h` for native handle + definitions (fallback) + +If you are using the X11 window creation API, support for the following X11 +extensions can be enabled: + + - `_GLFW_HAS_XF86VM` to use Xxf86vm as a fallback when RandR gamma is broken + (recommended) + +If you are using the Cocoa window creation API, the following options are +available: + + - `_GLFW_USE_CHDIR` to `chdir` to the `Resources` subdirectory of the + application bundle during @ref glfwInit (recommended) + - `_GLFW_USE_MENUBAR` to create and populate the menu bar when the first window + is created (recommended) + - `_GLFW_USE_RETINA` to have windows use the full resolution of Retina displays + (recommended) + +@note None of the @ref build_macros may be defined during the compilation of +GLFW. If you define any of these in your build files, make sure they are not +applied to the GLFW sources. + +*/ diff --git a/extern/glfw-3.2.1/docs/context.dox b/extern/glfw-3.2.1/docs/context.dox new file mode 100644 index 0000000..ad3b184 --- /dev/null +++ b/extern/glfw-3.2.1/docs/context.dox @@ -0,0 +1,345 @@ +/*! + +@page context_guide Context guide + +@tableofcontents + +This guide introduces the OpenGL and OpenGL ES context related functions of +GLFW. For details on a specific function in this category, see the @ref +context. There are also guides for the other areas of the GLFW API. + + - @ref intro_guide + - @ref window_guide + - @ref vulkan_guide + - @ref monitor_guide + - @ref input_guide + + +@section context_object Context objects + +A window object encapsulates both a top-level window and an OpenGL or OpenGL ES +context. It is created with @ref glfwCreateWindow and destroyed with @ref +glfwDestroyWindow or @ref glfwTerminate. See @ref window_creation for more +information. + +As the window and context are inseparably linked, the window object also serves +as the context handle. + +To test the creation of various kinds of contexts and see their properties, run +the `glfwinfo` test program. + +@note Vulkan does not have a context and the Vulkan instance is created via the +Vulkan API itself. If you will be using Vulkan to render to a window, disable +context creation by setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to +`GLFW_NO_API`. For more information, see the @ref vulkan_guide. + + +@subsection context_hints Context creation hints + +There are a number of hints, specified using @ref glfwWindowHint, related to +what kind of context is created. See +[context related hints](@ref window_hints_ctx) in the window guide. + + +@subsection context_sharing Context object sharing + +When creating a window and its OpenGL or OpenGL ES context with @ref +glfwCreateWindow, you can specify another window whose context the new one +should share its objects (textures, vertex and element buffers, etc.) with. + +@code +GLFWwindow* second_window = glfwCreateWindow(640, 480, "Second Window", NULL, first_window); +@endcode + +Object sharing is implemented by the operating system and graphics driver. On +platforms where it is possible to choose which types of objects are shared, GLFW +requests that all types are shared. + +See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or +[OpenGL ES](http://www.khronos.org/opengles/) reference documents for more +information. The name and number of this chapter unfortunately varies between +versions and APIs, but has at times been named _Shared Objects and Multiple +Contexts_. + +GLFW comes with a simple object sharing test program called `sharing`. + + +@subsection context_offscreen Offscreen contexts + +GLFW doesn't support creating contexts without an associated window. However, +contexts with hidden windows can be created with the +[GLFW_VISIBLE](@ref window_hints_wnd) window hint. + +@code +glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + +GLFWwindow* offscreen_context = glfwCreateWindow(640, 480, "", NULL, NULL); +@endcode + +The window never needs to be shown and its context can be used as a plain +offscreen context. Depending on the window manager, the size of a hidden +window's framebuffer may not be usable or modifiable, so framebuffer +objects are recommended for rendering with such contexts. + +You should still [process events](@ref events) as long as you have at least one +window, even if none of them are visible. + +__OS X:__ The first time a window is created the menu bar is populated with +common commands like Hide, Quit and About. This is not desirable for example +when writing a command-line only application. The menu bar setup can be +disabled with a [compile-time option](@ref compile_options_osx). + + +@subsection context_less Windows without contexts + +You can disable context creation by setting the +[GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`. Windows without +contexts must not be passed to @ref glfwMakeContextCurrent or @ref +glfwSwapBuffers. + + +@section context_current Current context + +Before you can make OpenGL or OpenGL ES calls, you need to have a current +context of the correct type. A context can only be current for a single thread +at a time, and a thread can only have a single context current at a time. + +The context of a window is made current with @ref glfwMakeContextCurrent. + +@code +glfwMakeContextCurrent(window); +@endcode + +The window of the current context is returned by @ref glfwGetCurrentContext. + +@code +GLFWwindow* window = glfwGetCurrentContext(); +@endcode + +The following GLFW functions require a context to be current. Calling any these +functions without a current context will generate a @ref GLFW_NO_CURRENT_CONTEXT +error. + + - @ref glfwSwapInterval + - @ref glfwExtensionSupported + - @ref glfwGetProcAddress + + +@section context_swap Buffer swapping + +Buffer swapping is part of the window and framebuffer, not the context. See +@ref buffer_swap. + + +@section context_glext OpenGL and OpenGL ES extensions + +One of the benefits of OpenGL and OpenGL ES is their extensibility. +Hardware vendors may include extensions in their implementations that extend the +API before that functionality is included in a new version of the OpenGL or +OpenGL ES specification, and some extensions are never included and remain +as extensions until they become obsolete. + +An extension is defined by: + +- An extension name (e.g. `GL_ARB_debug_output`) +- New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`) +- New OpenGL functions (e.g. `glGetDebugMessageLogARB`) + +Note the `ARB` affix, which stands for Architecture Review Board and is used +for official extensions. The extension above was created by the ARB, but there +are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any +group may also use the generic `EXT` affix. Lists of extensions, together with +their specifications, can be found at the +[OpenGL Registry](http://www.opengl.org/registry/) and +[OpenGL ES Registry](https://www.khronos.org/registry/gles/). + + +@subsection context_glext_auto Loading extension with a loader library + +An extension loader library is the easiest and best way to access both OpenGL and +OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs. +They will take care of all the details of declaring and loading everything you +need. One such library is [glad](https://github.com/Dav1dde/glad) and there are +several others. + +The following example will use glad but all extension loader libraries work +similarly. + +First you need to generate the source files using the glad Python script. This +example generates a loader for any version of OpenGL, which is the default for +both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific +API versions and extension sets can be generated. The generated files are +written to the `output` directory. + +@code{.sh} +python main.py --generator c --no-loader --out-path output +@endcode + +The `--no-loader` option is added because GLFW already provides a function for +loading OpenGL and OpenGL ES function pointers, one that automatically uses the +selected context creation API, and glad can call this instead of having to +implement its own. There are several other command-line options as well. See +the glad documentation for details. + +Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and +`output/include/KHR/khrplatform.h` files to your build. Then you need to +include the glad header file, which will replace the OpenGL header of your +development environment. By including the glad header before the GLFW header, +it suppresses the development environment's OpenGL or OpenGL ES header. + +@code +#include +#include +@endcode + +Finally you need to initialize glad once you have a suitable current context. + +@code +window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); +if (!window) +{ + ... +} + +glfwMakeContextCurrent(window); + +gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); +@endcode + +Once glad has been loaded, you have access to all OpenGL core and extension +functions supported by both the context you created and the glad loader you +generated and you are ready to start rendering. + +You can specify a minimum required OpenGL or OpenGL ES version with +[context hints](@ref window_hints_ctx). If your needs are more complex, you can +check the actual OpenGL or OpenGL ES version with +[context attributes](@ref window_attribs_ctx), or you can check whether +a specific version is supported by the current context with the +`GLAD_GL_VERSION_x_x` booleans. + +@code +if (GLAD_GL_VERSION_3_2) +{ + // Call OpenGL 3.2+ specific code +} +@endcode + +To check whether a specific extension is supported, use the `GLAD_GL_xxx` +booleans. + +@code +if (GLAD_GL_ARB_debug_output) +{ + // Use GL_ARB_debug_output +} +@endcode + + +@subsection context_glext_manual Loading extensions manually + +__Do not use this technique__ unless it is absolutely necessary. An +[extension loader library](@ref context_glext_auto) will save you a ton of +tedious, repetitive, error prone work. + +To use a certain extension, you must first check whether the context supports +that extension and then, if it introduces new functions, retrieve the pointers +to those functions. GLFW provides @ref glfwExtensionSupported and @ref +glfwGetProcAddress for manual loading of extensions and new API functions. + +This section will demonstrate manual loading of OpenGL extensions. The loading +of OpenGL ES extensions is identical except for the name of the extension header. + + +@subsubsection context_glext_header The glext.h header + +The `glext.h` extension header is a continually updated file that defines the +interfaces for all OpenGL extensions. The latest version of this can always be +found at the [OpenGL Registry](http://www.opengl.org/registry/). There are also +extension headers for the various versions of OpenGL ES at the +[OpenGL ES Registry](https://www.khronos.org/registry/gles/). It it strongly +recommended that you use your own copy of the extension header, as the one +included in your development environment may be several years out of date and +may not include the extensions you wish to use. + +The header defines function pointer types for all functions of all extensions it +supports. These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for +`glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer +to function) and `PROC` (procedure) are added to the ends. + +To include the extension header, define [GLFW_INCLUDE_GLEXT](@ref build_macros) +before including the GLFW header. + +@code +#define GLFW_INCLUDE_GLEXT +#include +@endcode + + +@subsubsection context_glext_string Checking for extensions + +A given machine may not actually support the extension (it may have older +drivers or a graphics card that lacks the necessary hardware features), so it +is necessary to check at run-time whether the context supports the extension. +This is done with @ref glfwExtensionSupported. + +@code +if (glfwExtensionSupported("GL_ARB_debug_output")) +{ + // The extension is supported by the current context +} +@endcode + +The argument is a null terminated ASCII string with the extension name. If the +extension is supported, @ref glfwExtensionSupported returns `GLFW_TRUE`, +otherwise it returns `GLFW_FALSE`. + + +@subsubsection context_glext_proc Fetching function pointers + +Many extensions, though not all, require the use of new OpenGL functions. +These functions often do not have entry points in the client API libraries of +your operating system, making it necessary to fetch them at run time. You can +retrieve pointers to these functions with @ref glfwGetProcAddress. + +@code +PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB"); +@endcode + +In general, you should avoid giving the function pointer variables the (exact) +same name as the function, as this may confuse your linker. Instead, you can +use a different prefix, like above, or some other naming scheme. + +Now that all the pieces have been introduced, here is what they might look like +when used together. + +@code +#define GLFW_INCLUDE_GLEXT +#include + +#define glGetDebugMessageLogARB pfnGetDebugMessageLog +PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog; + +// Flag indicating whether the extension is supported +int has_ARB_debug_output = 0; + +void load_extensions(void) +{ + if (glfwExtensionSupported("GL_ARB_debug_output")) + { + pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC) + glfwGetProcAddress("glGetDebugMessageLogARB"); + has_ARB_debug_output = 1; + } +} + +void some_function(void) +{ + if (has_ARB_debug_output) + { + // Now the extension function can be called as usual + glGetDebugMessageLogARB(...); + } +} +@endcode + +*/ diff --git a/extern/glfw-3.2.1/docs/extra.css b/extern/glfw-3.2.1/docs/extra.css new file mode 100644 index 0000000..e9896fa --- /dev/null +++ b/extern/glfw-3.2.1/docs/extra.css @@ -0,0 +1 @@ +#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,hr,.memSeparator{border:none}.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.reflist dt a.el,.levels span,.directory .levels span{text-shadow:none}.memdoc,dl.reflist dd{box-shadow:none}div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code{background:#f2f2f2}body{color:#4d4d4d}h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em{color:#1a1a1a;border-bottom:none}h1{padding-top:0.5em;font-size:180%}h2{padding-top:0.5em;margin-bottom:0;font-size:140%}h3{padding-top:0.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;height:64px;max-width:920px;min-width:800px;padding:0 32px;margin:0 auto}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("http://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}#glfwhome,.glfwnavbar a,.glfwnavbar a:visited{transition:.35s ease}#titlearea,.footer{color:#666}address.footer{text-align:center;padding:2em;margin-top:3em}#top{background:#666}#navrow1,#navrow2,#navrow3,#navrow4{max-width:920px;min-width:800px;margin:0 auto;font-size:13px}.tablist{height:36px;display:block;position:relative}.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a{color:#f2f2f2}.tablist li.current a{background:linear-gradient(to bottom, #ffa733 0, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;color:#fff}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable th,dl.reflist dt{background:linear-gradient(to bottom, #ffa733 0, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;color:#fff}dl.reflist dt a.el{color:#f60;padding:.2em;border-radius:4px;background-color:#ffe0cc}div.toc{float:none;width:auto}div.toc h3{font-size:1.17em}div.toc ul{padding-left:1.5em}div.toc li{font-size:1em;padding-left:0;list-style-type:disc}div.toc,.memproto,div.qindex,div.ah{background:linear-gradient(to bottom, #f2f2f2 0, #e6e6e6 100%);box-shadow:inset 0 0 32px #e6e6e6;text-shadow:0 1px 1px #fff;color:#1a1a1a;border:2px solid #e6e6e6;border-radius:4px}.paramname{color:#803300}dl.reflist dt{border:2px solid #f60;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:none}dl.reflist dd{border:2px solid #f60;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:none}table.doxtable{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,.tablist a:hover,span.lineno a:hover{color:#f60;text-decoration:none}div.directory{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}hr,.memSeparator{height:2px;background:linear-gradient(to right, #f2f2f2 0, #d9d9d9 50%, #f2f2f2 100%)}dl.note,dl.pre,dl.post,dl.invariant{background:linear-gradient(to bottom, #ddfad1 0, #cbf7ba 100%);box-shadow:inset 0 0 32px #baf5a3;color:#1e5309;border:2px solid #afe599}dl.warning,dl.attention{background:linear-gradient(to bottom, #fae8d1 0, #f7ddba 100%);box-shadow:inset 0 0 32px #f5d1a3;color:#533309;border:2px solid #e5c499}dl.deprecated,dl.bug{background:linear-gradient(to bottom, #fad1e3 0, #f7bad6 100%);box-shadow:inset 0 0 32px #f5a3c8;color:#53092a;border:2px solid #e599bb}dl.todo,dl.test{background:linear-gradient(to bottom, #d1ecfa 0, #bae3f7 100%);box-shadow:inset 0 0 32px #a3daf5;color:#093a53;border:2px solid #99cce5}dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test{border-radius:4px;padding:1em;text-shadow:0 1px 1px #fff;margin:1em 0}.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited{color:inherit}div.line{line-height:inherit}div.fragment,pre.fragment{background:#f2f2f2;border-radius:4px;border:none;padding:1em;overflow:auto;border-left:4px solid #ccc;margin:1em 0}.lineno a,.lineno a:visited,.line,pre.fragment{color:#4d4d4d}span.preprocessor,span.comment{color:#007899}a.code,a.code:visited{color:#e64500}span.keyword,span.keywordtype,span.keywordflow{color:#404040;font-weight:bold}span.stringliteral{color:#360099}code{padding:.1em;border-radius:4px} diff --git a/extern/glfw-3.2.1/docs/extra.less b/extern/glfw-3.2.1/docs/extra.less new file mode 100644 index 0000000..9d0ce97 --- /dev/null +++ b/extern/glfw-3.2.1/docs/extra.less @@ -0,0 +1,370 @@ +// NOTE: Please use this file to perform modifications on default style sheets. +// +// You need to install a few Ruby gems to generate extra.css from this file: +// gem install less therubyracer +// +// Run this command to regenerate extra.css after you're finished with changes: +// lessc --compress extra.less > extra.css +// +// Alternatively you can use online services to regenerate extra.css. + + +// Default text color for page contents +@default-text-color: hsl(0,0%,30%); + +// Page header, footer, table rows, inline codes and definition lists +@header-footer-background-color: hsl(0,0%,95%); + +// Page header, footer links and navigation bar background +@header-footer-link-color: hsl(0,0%,40%); + +// Doxygen navigation bar links +@navbar-link-color: @header-footer-background-color; + +// Page content background color +@content-background-color: hsl(0,0%,100%); + +// Bold, italic, h1, h2, ... and table of contents +@heading-color: hsl(0,0%,10%); + +// Function, enum and macro definition separator +@def-separator-color: @header-footer-background-color; + +// Base color hue +@base-hue: 24; + +// Default color used for links +@default-link-color: hsl(@base-hue,100%,50%); + +// Doxygen navigation bar active tab +@tab-text-color: hsl(0,0%,100%); +@tab-background-color1: @default-link-color; +@tab-background-color2: lighten(spin(@tab-background-color1, 10), 10%); + +// Table borders +@default-border-color: @default-link-color; + +// Table header +@table-text-color: @tab-text-color; +@table-background-color1: @tab-background-color1; +@table-background-color2: @tab-background-color2; + +// Table of contents, data structure index and prototypes +@toc-background-color1: hsl(0,0%,90%); +@toc-background-color2: lighten(@toc-background-color1, 5%); + +// Function prototype parameters color +@prototype-param-color: darken(@default-link-color, 25%); + +// Message box color: note, pre, post and invariant +@box-note-color: hsl(103,80%,85%); + +// Message box color: warning and attention +@box-warning-color: hsl(34,80%,85%); + +// Message box color: deprecated and bug +@box-bug-color: hsl(333,80%,85%); + +// Message box color: todo and test +@box-todo-color: hsl(200,80%,85%); + +// Message box helper function +.message-box(@base-color) { + background:linear-gradient(to bottom,lighten(@base-color, 5%) 0%,@base-color 100%); + box-shadow:inset 0 0 32px darken(@base-color, 5%); + color:darken(@base-color, 67%); + border:2px solid desaturate(darken(@base-color, 10%), 20%); +} + + +#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code { + background:none; +} + +#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,hr,.memSeparator { + border:none; +} + +.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.reflist dt a.el,.levels span,.directory .levels span { + text-shadow:none; +} + +.memdoc,dl.reflist dd { + box-shadow:none; +} + +div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code { + padding:0; +} + +#nav-path,.directory .levels,span.lineno { + display:none; +} + +html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code { + background:@header-footer-background-color; +} + +body { + color:@default-text-color; +} + +h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em { + color:@heading-color; + border-bottom:none; +} + +h1 { + padding-top:0.5em; + font-size:180%; +} + +h2 { + padding-top:0.5em; + margin-bottom:0; + font-size:140%; +} + +h3 { + padding-top:0.5em; + margin-bottom:0; + font-size:110%; +} + +.glfwheader { + font-size:16px; + height:64px; + max-width:920px; + min-width:800px; + padding:0 32px; + margin:0 auto; +} + +#glfwhome { + line-height:64px; + padding-right:48px; + color:@header-footer-link-color; + font-size:2.5em; + background:url("http://www.glfw.org/css/arrow.png") no-repeat right; +} + +.glfwnavbar { + list-style-type:none; + margin:0 auto; + float:right; +} + +#glfwhome,.glfwnavbar li { + float:left; +} + +.glfwnavbar a,.glfwnavbar a:visited { + line-height:64px; + margin-left:2em; + display:block; + color:@header-footer-link-color; +} + +#glfwhome,.glfwnavbar a,.glfwnavbar a:visited { + transition:.35s ease; +} + +#titlearea,.footer { + color:@header-footer-link-color; +} + +address.footer { + text-align:center; + padding:2em; + margin-top:3em; +} + +#top { + background:@header-footer-link-color; +} + +#navrow1,#navrow2,#navrow3,#navrow4 { + max-width:920px; + min-width:800px; + margin:0 auto; + font-size:13px; +} + +.tablist { + height:36px; + display:block; + position:relative; +} + +.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a { + color:@navbar-link-color; +} + +.tablist li.current a { + background:linear-gradient(to bottom,@tab-background-color2 0%,@tab-background-color1 100%); + box-shadow:inset 0 0 32px @tab-background-color1; + text-shadow:0 -1px 1px darken(@tab-background-color1, 15%); + color:@tab-text-color; +} + +.contents { + min-height:590px; +} + +div.contents,div.header { + max-width:920px; + margin:0 auto; + padding:0 32px; + background:@content-background-color none; +} + +table.doxtable th,dl.reflist dt { + background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%); + box-shadow:inset 0 0 32px @table-background-color1; + text-shadow:0 -1px 1px darken(@table-background-color1, 15%); + color:@table-text-color; +} + +dl.reflist dt a.el { + color:@default-link-color; + padding:.2em; + border-radius:4px; + background-color:lighten(@default-link-color, 40%); +} + +div.toc { + float:none; + width:auto; +} + +div.toc h3 { + font-size:1.17em; +} + +div.toc ul { + padding-left:1.5em; +} + +div.toc li { + font-size:1em; + padding-left:0; + list-style-type:disc; +} + +div.toc,.memproto,div.qindex,div.ah { + background:linear-gradient(to bottom,@toc-background-color2 0%,@toc-background-color1 100%); + box-shadow:inset 0 0 32px @toc-background-color1; + text-shadow:0 1px 1px lighten(@toc-background-color2, 10%); + color:@heading-color; + border:2px solid @toc-background-color1; + border-radius:4px; +} + +.paramname { + color:@prototype-param-color; +} + +dl.reflist dt { + border:2px solid @default-border-color; + border-top-left-radius:4px; + border-top-right-radius:4px; + border-bottom:none; +} + +dl.reflist dd { + border:2px solid @default-border-color; + border-bottom-right-radius:4px; + border-bottom-left-radius:4px; + border-top:none; +} + +table.doxtable { + border-collapse:inherit; + border-spacing:0; + border:2px solid @default-border-color; + border-radius:4px; +} + +a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,.tablist a:hover,span.lineno a:hover { + color:@default-link-color; + text-decoration:none; +} + +div.directory { + border-collapse:inherit; + border-spacing:0; + border:2px solid @default-border-color; + border-radius:4px; +} + +hr,.memSeparator { + height:2px; + background:linear-gradient(to right,@def-separator-color 0%,darken(@def-separator-color, 10%) 50%,@def-separator-color 100%); +} + +dl.note,dl.pre,dl.post,dl.invariant { + .message-box(@box-note-color); +} + +dl.warning,dl.attention { + .message-box(@box-warning-color); +} + +dl.deprecated,dl.bug { + .message-box(@box-bug-color); +} + +dl.todo,dl.test { + .message-box(@box-todo-color); +} + +dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test { + border-radius:4px; + padding:1em; + text-shadow:0 1px 1px hsl(0,0%,100%); + margin:1em 0; +} + +.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited { + color:inherit; +} + +div.line { + line-height:inherit; +} + +div.fragment,pre.fragment { + background:hsl(0,0%,95%); + border-radius:4px; + border:none; + padding:1em; + overflow:auto; + border-left:4px solid hsl(0,0%,80%); + margin:1em 0; +} + +.lineno a,.lineno a:visited,.line,pre.fragment { + color:@default-text-color; +} + +span.preprocessor,span.comment { + color:hsl(193,100%,30%); +} + +a.code,a.code:visited { + color:hsl(18,100%,45%); +} + +span.keyword,span.keywordtype,span.keywordflow { + color:darken(@default-text-color, 5%); + font-weight:bold; +} + +span.stringliteral { + color:hsl(261,100%,30%); +} + +code { + padding:.1em; + border-radius:4px; +} diff --git a/extern/glfw-3.2.1/docs/footer.html b/extern/glfw-3.2.1/docs/footer.html new file mode 100644 index 0000000..b0434ca --- /dev/null +++ b/extern/glfw-3.2.1/docs/footer.html @@ -0,0 +1,7 @@ + + + diff --git a/extern/glfw-3.2.1/docs/header.html b/extern/glfw-3.2.1/docs/header.html new file mode 100644 index 0000000..9759d8b --- /dev/null +++ b/extern/glfw-3.2.1/docs/header.html @@ -0,0 +1,34 @@ + + + + + + +$projectname: $title +$title + + + +$treeview +$search +$mathjax + +$extrastylesheet + + +
+ + + + + diff --git a/extern/glfw-3.2.1/docs/input.dox b/extern/glfw-3.2.1/docs/input.dox new file mode 100644 index 0000000..1a06e62 --- /dev/null +++ b/extern/glfw-3.2.1/docs/input.dox @@ -0,0 +1,665 @@ +/*! + +@page input_guide Input guide + +@tableofcontents + +This guide introduces the input related functions of GLFW. For details on +a specific function in this category, see the @ref input. There are also guides +for the other areas of GLFW. + + - @ref intro_guide + - @ref window_guide + - @ref context_guide + - @ref vulkan_guide + - @ref monitor_guide + +GLFW provides many kinds of input. While some can only be polled, like time, or +only received via callbacks, like scrolling, there are those that provide both +callbacks and polling. Where a callback is provided, that is the recommended +way to receive that kind of input. The more you can use callbacks the less time +your users' machines will need to spend polling. + +All input callbacks receive a window handle. By using the +[window user pointer](@ref window_userptr), you can access non-global structures +or objects from your callbacks. + +To get a better feel for how the various events callbacks behave, run the +`events` test program. It register every callback supported by GLFW and prints +out all arguments provided for every event, along with time and sequence +information. + + +@section events Event processing + +GLFW needs to communicate regularly with the window system both in order to +receive events and to show that the application hasn't locked up. Event +processing must be done regularly while you have any windows and is normally +done each frame after [buffer swapping](@ref buffer_swap). Even when you have +no windows, event polling needs to be done in order to receive monitor +connection events. + +There are two functions for processing pending events. @ref glfwPollEvents, +processes only those events that have already been received and then returns +immediately. + +@code +glfwPollEvents(); +@endcode + +This is the best choice when rendering continually, like most games do. + +If you only need to update the contents of the window when you receive new +input, @ref glfwWaitEvents is a better choice. + +@code +glfwWaitEvents(); +@endcode + +It puts the thread to sleep until at least one event has been received and then +processes all received events. This saves a great deal of CPU cycles and is +useful for, for example, editing tools. There must be at least one GLFW window +for this function to sleep. + +If you want to wait for events but have UI elements that need periodic updates, +call @ref glfwWaitEventsTimeout. + +@code +glfwWaitEventsTimeout(0.7); +@endcode + +It puts the thread to sleep until at least one event has been received, or until +the specified number of seconds have elapsed. It then processes any received +events. + +If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from +another thread by posting an empty event to the event queue with @ref +glfwPostEmptyEvent. + +@code +glfwPostEmptyEvent(); +@endcode + +Do not assume that callbacks will _only_ be called through either of the above +functions. While it is necessary to process events in the event queue, some +window systems will send some events directly to the application, which in turn +causes callbacks to be called outside of regular event processing. + + +@section input_keyboard Keyboard input + +GLFW divides keyboard input into two categories; key events and character +events. Key events relate to actual physical keyboard keys, whereas character +events relate to the Unicode code points generated by pressing some of them. + +Keys and characters do not map 1:1. A single key press may produce several +characters, and a single character may require several keys to produce. This +may not be the case on your machine, but your users are likely not all using the +same keyboard layout, input method or even operating system as you. + + +@subsection input_key Key input + +If you wish to be notified when a physical key is pressed or released or when it +repeats, set a key callback. + +@code +glfwSetKeyCallback(window, key_callback); +@endcode + +The callback function receives the [keyboard key](@ref keys), platform-specific +scancode, key action and [modifier bits](@ref mods). + +@code +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_E && action == GLFW_PRESS) + activate_airship(); +} +@endcode + +The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key +will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example +_E-mail_ and _Play_ keys. + +The scancode is unique for every key, regardless of whether it has a key token. +Scancodes are platform-specific but consistent over time, so keys will have +different scancodes depending on the platform but they are safe to save to disk. + +Key states for [named keys](@ref keys) are also saved in per-window state arrays +that can be polled with @ref glfwGetKey. + +@code +int state = glfwGetKey(window, GLFW_KEY_E); +if (state == GLFW_PRESS) + activate_airship(); +@endcode + +The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. + +This function only returns cached key event state. It does not poll the +system for the current state of the key. + +Whenever you poll state, you risk missing the state change you are looking for. +If a pressed key is released again before you poll its state, you will have +missed the key press. The recommended solution for this is to use a +key callback, but there is also the `GLFW_STICKY_KEYS` input mode. + +@code +glfwSetInputMode(window, GLFW_STICKY_KEYS, 1); +@endcode + +When sticky keys mode is enabled, the pollable state of a key will remain +`GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey. Once +it has been polled, if a key release event had been processed in the meantime, +the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`. + +The `GLFW_KEY_LAST` constant holds the highest value of any +[named key](@ref keys). + + +@subsection input_char Text input + +GLFW supports text input in the form of a stream of +[Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the +operating system text input system. Unlike key input, text input obeys keyboard +layouts and modifier keys and supports composing characters using +[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can +encode the code points into +[UTF-8](https://en.wikipedia.org/wiki/UTF-8) or any other encoding you prefer. + +Because an `unsigned int` is 32 bits long on all platforms supported by GLFW, +you can treat the code point argument as native endian +[UTF-32](https://en.wikipedia.org/wiki/UTF-32). + +There are two callbacks for receiving Unicode code points. If you wish to +offer regular text input, set a character callback. + +@code +glfwSetCharCallback(window, character_callback); +@endcode + +The callback function receives Unicode code points for key events that would +have led to regular text input and generally behaves as a standard text field on +that platform. + +@code +void character_callback(GLFWwindow* window, unsigned int codepoint) +{ +} +@endcode + +If you wish to receive even those Unicode code points generated with modifier +key combinations that a plain text field would ignore, or just want to know +exactly what modifier keys were used, set a character with modifiers callback. + +@code +glfwSetCharModsCallback(window, charmods_callback); +@endcode + +The callback function receives Unicode code points and +[modifier bits](@ref mods). + +@code +void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods) +{ +} +@endcode + + +@subsection input_key_name Key names + +If you wish to refer to keys by name, you can query the keyboard layout +dependent name of printable keys with @ref glfwGetKeyName. + +@code +const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0); +show_tutorial_hint("Press %s to move forward", key_name); +@endcode + +This function can handle both [keys and scancodes](@ref input_key). If the +specified key is `GLFW_KEY_UNKNOWN` then the scancode is used, otherwise it is +ignored. This matches the behavior of the key callback, meaning the callback +arguments can always be passed unmodified to this function. + + +@section input_mouse Mouse input + +Mouse input comes in many forms, including cursor motion, button presses and +scrolling offsets. The cursor appearance can also be changed, either to +a custom image or a standard cursor shape from the system theme. + + +@subsection cursor_pos Cursor position + +If you wish to be notified when the cursor moves over the window, set a cursor +position callback. + +@code +glfwSetCursorPosCallback(window, cursor_pos_callback); +@endcode + +The callback functions receives the cursor position, measured in screen +coordinates but relative to the top-left corner of the window client area. On +platforms that provide it, the full sub-pixel cursor position is passed on. + +@code +static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) +{ +} +@endcode + +The cursor position is also saved per-window and can be polled with @ref +glfwGetCursorPos. + +@code +double xpos, ypos; +glfwGetCursorPos(window, &xpos, &ypos); +@endcode + + +@subsection cursor_mode Cursor modes + +The `GLFW_CURSOR` input mode provides several cursor modes for special forms of +mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`, +meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor) +is used and cursor motion is not limited. + +If you wish to implement mouse motion based camera controls or other input +schemes that require unlimited mouse movement, set the cursor mode to +`GLFW_CURSOR_DISABLED`. + +@code +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); +@endcode + +This will hide the cursor and lock it to the specified window. GLFW will then +take care of all the details of cursor re-centering and offset calculation and +providing the application with a virtual cursor position. This virtual position +is provided normally via both the cursor position callback and through polling. + +@note You should not implement your own version of this functionality using +other features of GLFW. It is not supported and will not work as robustly as +`GLFW_CURSOR_DISABLED`. + +If you just wish the cursor to become hidden when it is over a window, set +the cursor mode to `GLFW_CURSOR_HIDDEN`. + +@code +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); +@endcode + +This mode puts no limit on the motion of the cursor. + +To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL` +cursor mode. + +@code +glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); +@endcode + + +@subsection cursor_object Cursor objects + +GLFW supports creating both custom and system theme cursor images, encapsulated +as @ref GLFWcursor objects. They are created with @ref glfwCreateCursor or @ref +glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref +glfwTerminate, if any remain. + + +@subsubsection cursor_custom Custom cursor creation + +A custom cursor is created with @ref glfwCreateCursor, which returns a handle to +the created cursor object. For example, this creates a 16x16 white square +cursor with the hot-spot in the upper-left corner: + +@code +unsigned char pixels[16 * 16 * 4]; +memset(pixels, 0xff, sizeof(pixels)); + +GLFWimage image; +image.width = 16; +image.height = 16; +image.pixels = pixels; + +GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0); +@endcode + +If cursor creation fails, `NULL` will be returned, so it is necessary to check +the return value. + +The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits +per channel. The pixels are arranged canonically as sequential rows, starting +from the top-left corner. + + +@subsubsection cursor_standard Standard cursor creation + +A cursor with a [standard shape](@ref shapes) from the current system cursor +theme can be can be created with @ref glfwCreateStandardCursor. + +@code +GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); +@endcode + +These cursor objects behave in the exact same way as those created with @ref +glfwCreateCursor except that the system cursor theme provides the actual image. + + +@subsubsection cursor_destruction Cursor destruction + +When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor. + +@code +glfwDestroyCursor(cursor); +@endcode + +Cursor destruction always succeeds. All cursors remaining when @ref +glfwTerminate is called are destroyed as well. + + +@subsubsection cursor_set Cursor setting + +A cursor can be set as current for a window with @ref glfwSetCursor. + +@code +glfwSetCursor(window, cursor); +@endcode + +Once set, the cursor image will be used as long as the system cursor is over the +client area of the window and the [cursor mode](@ref cursor_mode) is set +to `GLFW_CURSOR_NORMAL`. + +A single cursor may be set for any number of windows. + +To remove a cursor from a window, set the cursor of that window to `NULL`. + +@code +glfwSetCursor(window, NULL); +@endcode + +When a cursor is destroyed, it is removed from any window where it is set. This +does not affect the cursor modes of those windows. + + +@subsection cursor_enter Cursor enter/leave events + +If you wish to be notified when the cursor enters or leaves the client area of +a window, set a cursor enter/leave callback. + +@code +glfwSetCursorEnterCallback(window, cursor_enter_callback); +@endcode + +The callback function receives the new classification of the cursor. + +@code +void cursor_enter_callback(GLFWwindow* window, int entered) +{ + if (entered) + { + // The cursor entered the client area of the window + } + else + { + // The cursor left the client area of the window + } +} +@endcode + + +@subsection input_mouse_button Mouse button input + +If you wish to be notified when a mouse button is pressed or released, set +a mouse button callback. + +@code +glfwSetMouseButtonCallback(window, mouse_button_callback); +@endcode + +The callback function receives the [mouse button](@ref buttons), button action +and [modifier bits](@ref mods). + +@code +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS) + popup_menu(); +} +@endcode + +The action is one of `GLFW_PRESS` or `GLFW_RELEASE`. + +Mouse button states for [named buttons](@ref buttons) are also saved in +per-window state arrays that can be polled with @ref glfwGetMouseButton. + +@code +int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT); +if (state == GLFW_PRESS) + upgrade_cow(); +@endcode + +The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`. + +This function only returns cached mouse button event state. It does not poll +the system for the current state of the mouse button. + +Whenever you poll state, you risk missing the state change you are looking for. +If a pressed mouse button is released again before you poll its state, you will have +missed the button press. The recommended solution for this is to use a +mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS` +input mode. + +@code +glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); +@endcode + +When sticky mouse buttons mode is enabled, the pollable state of a mouse button +will remain `GLFW_PRESS` until the state of that button is polled with @ref +glfwGetMouseButton. Once it has been polled, if a mouse button release event +had been processed in the meantime, the state will reset to `GLFW_RELEASE`, +otherwise it will remain `GLFW_PRESS`. + +The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any +[named button](@ref buttons). + + +@subsection scrolling Scroll input + +If you wish to be notified when the user scrolls, whether with a mouse wheel or +touchpad gesture, set a scroll callback. + +@code +glfwSetScrollCallback(window, scroll_callback); +@endcode + +The callback function receives two-dimensional scroll offsets. + +@code +void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) +{ +} +@endcode + +A simple mouse wheel, being vertical, provides offsets along the Y-axis. + + +@section joystick Joystick input + +The joystick functions expose connected joysticks and controllers, with both +referred to as joysticks. It supports up to sixteen joysticks, ranging from +`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to `GLFW_JOYSTICK_LAST`. You can test +whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent. + +@code +int present = glfwJoystickPresent(GLFW_JOYSTICK_1); +@endcode + +When GLFW is initialized, detected joysticks are added to to the beginning of +the array, starting with `GLFW_JOYSTICK_1`. Once a joystick is detected, it +keeps its assigned index until it is disconnected, so as joysticks are connected +and disconnected, they will become spread out. + +Joystick state is updated as needed when a joystick function is called and does +not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents +to be called. + + +@subsection joystick_axis Joystick axis states + +The positions of all axes of a joystick are returned by @ref +glfwGetJoystickAxes. See the reference documentation for the lifetime of the +returned array. + +@code +int count; +const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count); +@endcode + +Each element in the returned array is a value between -1.0 and 1.0. + + +@subsection joystick_button Joystick button states + +The states of all buttons of a joystick are returned by @ref +glfwGetJoystickButtons. See the reference documentation for the lifetime of the +returned array. + +@code +int count; +const unsigned char* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count); +@endcode + +Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`. + + +@subsection joystick_name Joystick name + +The human-readable, UTF-8 encoded name of a joystick is returned by @ref +glfwGetJoystickName. See the reference documentation for the lifetime of the +returned string. + +@code +const char* name = glfwGetJoystickName(GLFW_JOYSTICK_1); +@endcode + +Joystick names are not guaranteed to be unique. Two joysticks of the same model +and make may have the same name. Only the [joystick token](@ref joysticks) is +guaranteed to be unique, and only until that joystick is disconnected. + + +@subsection joystick_event Joystick configuration changes + +If you wish to be notified when a joystick is connected or disconnected, set +a joystick callback. + +@code +glfwSetJoystickCallback(joystick_callback); +@endcode + +The callback function receives the ID of the joystick that has been connected +and disconnected and the event that occurred. + +@code +void joystick_callback(int joy, int event) +{ + if (event == GLFW_CONNECTED) + { + // The joystick was connected + } + else if (event == GLFW_DISCONNECTED) + { + // The joystick was disconnected + } +} +@endcode + + +@section time Time input + +GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime. + +@code +double seconds = glfwGetTime(); +@endcode + +It returns the number of seconds since the timer was started when the library +was initialized with @ref glfwInit. The platform-specific time sources used +usually have micro- or nanosecond resolution. + +You can modify the reference time with @ref glfwSetTime. + +@code +glfwSetTime(4.0); +@endcode + +This sets the timer to the specified time, in seconds. + +You can also access the raw timer value, measured in 1 / frequency +seconds, with @ref glfwGetTimerValue. + +@code +uint64_t value = glfwGetTimerValue(); +@endcode + +The frequency of the raw timer varies depending on what time sources are +available on the machine. You can query its frequency, in Hz, with @ref +glfwGetTimerFrequency. + +@code +uint64_t freqency = glfwGetTimerFrequency(); +@endcode + + +@section clipboard Clipboard input and output + +If the system clipboard contains a UTF-8 encoded string or if it can be +converted to one, you can retrieve it with @ref glfwGetClipboardString. See the +reference documentation for the lifetime of the returned string. + +@code +const char* text = glfwGetClipboardString(window); +if (text) + insert_text(text); +@endcode + +If the clipboard is empty or if its contents could not be converted, `NULL` is +returned. + +The contents of the system clipboard can be set to a UTF-8 encoded string with +@ref glfwSetClipboardString. + +@code +glfwSetClipboardString(window, "A string with words in it"); +@endcode + +The clipboard functions take a window handle argument because some window +systems require a window to communicate with the system clipboard. Any valid +window may be used. + + +@section path_drop Path drop input + +If you wish to receive the paths of files and/or directories dropped on +a window, set a file drop callback. + +@code +glfwSetDropCallback(window, drop_callback); +@endcode + +The callback function receives an array of paths encoded as UTF-8. + +@code +void drop_callback(GLFWwindow* window, int count, const char** paths) +{ + int i; + for (i = 0; i < count; i++) + handle_dropped_file(paths[i]); +} +@endcode + +The path array and its strings are only valid until the file drop callback +returns, as they may have been generated specifically for that event. You need +to make a deep copy of the array if you want to keep the paths. + +*/ diff --git a/extern/glfw-3.2.1/docs/internal.dox b/extern/glfw-3.2.1/docs/internal.dox new file mode 100644 index 0000000..3eb0aee --- /dev/null +++ b/extern/glfw-3.2.1/docs/internal.dox @@ -0,0 +1,116 @@ +/*! + +@page internals_guide Internal structure + +@tableofcontents + +There are several interfaces inside GLFW. Each interface has its own area of +responsibility and its own naming conventions. + + +@section internals_public Public interface + +The most well-known is the public interface, described in the glfw3.h header +file. This is implemented in source files shared by all platforms and these +files contain no platform-specific code. This code usually ends up calling the +platform and internal interfaces to do the actual work. + +The public interface uses the OpenGL naming conventions except with GLFW and +glfw instead of GL and gl. For struct members, where OpenGL sets no precedent, +it use headless camel case. + +Examples: @ref glfwCreateWindow, @ref GLFWwindow, @ref GLFWvidmode.redBits, +`GLFW_RED_BITS` + + +@section internals_native Native interface + +The [native interface](@ref native) is a small set of publicly available +but platform-specific functions, described in the glfw3native.h header file and +used to gain access to the underlying window, context and (on some platforms) +display handles used by the platform interface. + +The function names of the native interface are similar to those of the public +interface, but embeds the name of the interface that the returned handle is +from. + +Examples: @ref glfwGetX11Window, @ref glfwGetWGLContext + + +@section internals_internal Internal interface + +The internal interface consists of utility functions used by all other +interfaces. It is shared code implemented in the same shared source files as +the public and event interfaces. The internal interface is described in the +internal.h header file. + +The internal interface is in charge of GLFW's global data, which it stores in +a `_GLFWlibrary` struct named `_glfw`. + +The internal interface uses the same style as the public interface, except all +global names have a leading underscore. + +Examples: @ref _glfwIsValidContextConfig, @ref _GLFWwindow, `_glfw.currentRamp` + + +@section internals_platform Platform interface + +The platform interface implements all platform-specific operations as a service +to the public interface. This includes event processing. The platform +interface is never directly called by application code and never directly calls +application-provided callbacks. It is also prohibited from modifying the +platform-independent part of the internal structs. Instead, it calls the event +interface when events interesting to GLFW are received. + +The platform interface mirrors those parts of the public interface that needs to +perform platform-specific operations on some or all platforms. The are also +named the same except that the glfw function prefix is replaced by +_glfwPlatform. + +Examples: @ref _glfwPlatformCreateWindow + +The platform interface also defines structs that contain platform-specific +global and per-object state. Their names mirror those of the internal +interface, except that an interface-specific suffix is added. + +Examples: `_GLFWwindowX11`, `_GLFWcontextWGL` + +These structs are incorporated as members into the internal interface structs +using special macros that name them after the specific interface used. This +prevents shared code from accidentally using these members. + +Examples: `window.win32.handle`, `_glfw.x11.display` + + +@section internals_event Event interface + +The event interface is implemented in the same shared source files as the public +interface and is responsible for delivering the events it receives to the +application, either via callbacks, via window state changes or both. + +The function names of the event interface use a `_glfwInput` prefix and the +ObjectEvent pattern. + +Examples: @ref _glfwInputWindowFocus, @ref _glfwInputCursorMotion + + +@section internals_static Static functions + +Static functions may be used by any interface and have no prefixes or suffixes. +These use headless camel case. + +Examples: `clearScrollOffsets` + + +@section internals_config Configuration macros + +GLFW uses a number of configuration macros to select at compile time which +interfaces and code paths to use. They are defined in the glfw_config.h header file, +which is generated from the `glfw_config.h.in` file by CMake. + +Configuration macros the same style as tokens in the public interface, except +with a leading underscore. + +Examples: `_GLFW_HAS_XF86VM` + +*/ diff --git a/extern/glfw-3.2.1/docs/intro.dox b/extern/glfw-3.2.1/docs/intro.dox new file mode 100644 index 0000000..f784080 --- /dev/null +++ b/extern/glfw-3.2.1/docs/intro.dox @@ -0,0 +1,372 @@ +/*! + +@page intro_guide Introduction to the API + +@tableofcontents + +This guide introduces the basic concepts of GLFW and describes initialization, +error handling and API guarantees and limitations. For a broad but shallow +tutorial, see @ref quick_guide instead. For details on a specific function in +this category, see the @ref init. + +There are also guides for the other areas of GLFW. + + - @ref window_guide + - @ref context_guide + - @ref vulkan_guide + - @ref monitor_guide + - @ref input_guide + + +@section intro_init Initialization and termination + +Before most GLFW functions may be called, the library must be initialized. +This initialization checks what features are available on the machine, +enumerates monitors and joysticks, initializes the timer and performs any +required platform-specific initialization. + +Only the following functions may be called before the library has been +successfully initialized, and only from the main thread. + + - @ref glfwGetVersion + - @ref glfwGetVersionString + - @ref glfwSetErrorCallback + - @ref glfwInit + - @ref glfwTerminate + +Calling any other function before successful initialization will cause a @ref +GLFW_NOT_INITIALIZED error. + + +@subsection intro_init_init Initializing GLFW + +The library is initialized with @ref glfwInit, which returns `GLFW_FALSE` if an +error occurred. + +@code +if (!glfwInit()) +{ + // Handle initialization failure +} +@endcode + +If any part of initialization fails, any parts that succeeded are terminated as +if @ref glfwTerminate had been called. The library only needs to be initialized +once and additional calls to an already initialized library will simply return +`GLFW_TRUE` immediately. + +Once the library has been successfully initialized, it should be terminated +before the application exits. Modern systems are very good at freeing resources +allocated by programs that simply exit, but GLFW sometimes has to change global +system settings and these might not be restored without termination. + + +@subsection intro_init_terminate Terminating GLFW + +Before your application exits, you should terminate the GLFW library if it has +been initialized. This is done with @ref glfwTerminate. + +@code +glfwTerminate(); +@endcode + +This will destroy any remaining window, monitor and cursor objects, restore any +modified gamma ramps, re-enable the screensaver if it had been disabled and free +any other resources allocated by GLFW. + +Once the library is terminated, it is as if it had never been initialized and +you will need to initialize it again before being able to use GLFW. If the +library was not initialized or had already been terminated, it return +immediately. + + +@section error_handling Error handling + +Some GLFW functions have return values that indicate an error, but this is often +not very helpful when trying to figure out _why_ the error occurred. Some +functions also return otherwise valid values on error. Finally, far from all +GLFW functions have return values. + +This is where the error callback comes in. This callback is called whenever an +error occurs. It is set with @ref glfwSetErrorCallback, a function that may be +called regardless of whether GLFW is initialized. + +@code +glfwSetErrorCallback(error_callback); +@endcode + +The error callback receives a human-readable description of the error and (when +possible) its cause. The description encoded as UTF-8. The callback is also +provided with an [error code](@ref errors). + +@code +void error_callback(int error, const char* description) +{ + puts(description); +} +@endcode + +The error code indicates the general category of the error. Some error codes, +such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like +@ref GLFW_PLATFORM_ERROR are used for many different errors. + +The description string is only valid until the error callback returns, as it may +have been generated specifically for that error. This lets GLFW provide much +more specific error descriptions but means you must make a copy if you want to +keep the description string. + +@note Relying on erroneous behavior is not forward compatible. In other words, +do not rely on a currently invalid call to generate a specific error, as that +same call may in future versions generate a different error or become valid. + + +@section coordinate_systems Coordinate systems + +GLFW has two primary coordinate systems: the _virtual screen_ and the window +_client area_ or _content area_. Both use the same unit: _virtual screen +coordinates_, or just _screen coordinates_, which don't necessarily correspond +to pixels. + + + +Both the virtual screen and the client area coordinate systems have the X-axis +pointing to the right and the Y-axis pointing down. + +Window and monitor positions are specified as the position of the upper-left +corners of their content areas relative to the virtual screen, while cursor +positions are specified relative to a window's client area. + +Because the origin of the window's client area coordinate system is also the +point from which the window position is specified, you can translate client area +coordinates to the virtual screen by adding the window position. The window +frame, when present, extends out from the client area but does not affect the +window position. + +Almost all positions and sizes in GLFW are measured in screen coordinates +relative to one of the two origins above. This includes cursor positions, +window positions and sizes, window frame sizes, monitor positions and video mode +resolutions. + +Two exceptions are the [monitor physical size](@ref monitor_size), which is +measured in millimetres, and [framebuffer size](@ref window_fbsize), which is +measured in pixels. + +Pixels and screen coordinates may map 1:1 on your machine, but they won't on +every other machine, for example on a Mac with a Retina display. The ratio +between screen coordinates and pixels may also change at run-time depending on +which monitor the window is currently considered to be on. + + +@section guarantees_limitations Guarantees and limitations + +This section describes the conditions under which GLFW can be expected to +function, barring bugs in the operating system or drivers. Use of GLFW outside +of these limits may work on some platforms, or on some machines, or some of the +time, or on some versions of GLFW, but it may break at any time and this will +not be considered a bug. + + +@subsection lifetime Pointer lifetimes + +GLFW will never free any pointer you provide to it and you must never free any +pointer it provides to you. + +Many GLFW functions return pointers to dynamically allocated structures, strings +or arrays, and some callbacks are provided with strings or arrays. These are +always managed by GLFW and should never be freed by the application. The +lifetime of these pointers is documented for each GLFW function and callback. +If you need to keep this data, you must copy it before its lifetime expires. + +Many GLFW functions accept pointers to structures or strings allocated by the +application. These are never freed by GLFW and are always the responsibility of +the application. If GLFW needs to keep the data in these structures or strings, +it is copied before the function returns. + +Pointer lifetimes are guaranteed not to be shortened in future minor or patch +releases. + + +@subsection reentrancy Reentrancy + +GLFW event processing and object creation and destruction are not reentrant. +This means that the following functions must not be called from any callback +function: + + - @ref glfwCreateWindow + - @ref glfwDestroyWindow + - @ref glfwCreateCursor + - @ref glfwCreateStandardCursor + - @ref glfwDestroyCursor + - @ref glfwPollEvents + - @ref glfwWaitEvents + - @ref glfwWaitEventsTimeout + - @ref glfwTerminate + +These functions may be made reentrant in future minor or patch releases, but +functions not on this list will not be made non-reentrant. + + +@subsection thread_safety Thread safety + +Most GLFW functions must only be called from the main thread, but some may be +called from any thread. However, no GLFW function may be called from any thread +but the main thread until GLFW has been successfully initialized, including +functions that may called before initialization. + +The reference documentation for every GLFW function states whether it is limited +to the main thread. + +Initialization and termination, event processing and the creation and +destruction of windows, contexts and cursors are all limited to the main thread +due to limitations of one or several platforms. + +Because event processing must be performed on the main thread, all callbacks +except for the error callback will only be called on that thread. The error +callback may be called on any thread, as any GLFW function may generate errors. + +The posting of empty events may be done from any thread. The window user +pointer and close flag may also be accessed and modified from any thread, but +this is not synchronized by GLFW. The following window related functions may +be called from any thread: + + - @ref glfwPostEmptyEvent + - @ref glfwGetWindowUserPointer + - @ref glfwSetWindowUserPointer + - @ref glfwWindowShouldClose + - @ref glfwSetWindowShouldClose + +Rendering may be done on any thread. The following context related functions +may be called from any thread: + + - @ref glfwMakeContextCurrent + - @ref glfwGetCurrentContext + - @ref glfwSwapBuffers + - @ref glfwSwapInterval + - @ref glfwExtensionSupported + - @ref glfwGetProcAddress + +The raw timer may be queried from any thread. The following raw timer related +functions may be called from any thread: + + - @ref glfwGetTimerFrequency + - @ref glfwGetTimerValue + +The regular timer may be used from any thread, but the reading and writing of +the timer offset is not synchronized by GLFW. The following timer related +functions may be called from any thread: + + - @ref glfwGetTime + - @ref glfwSetTime + +Library version information may be queried from any thread. The following +version related functions may be called from any thread: + + - @ref glfwGetVersion + - @ref glfwGetVersionString + +Vulkan objects may be created and information queried from any thread. The +following Vulkan related functions may be called from any thread: + + - @ref glfwVulkanSupported + - @ref glfwGetRequiredInstanceExtensions + - @ref glfwGetInstanceProcAddress + - @ref glfwGetPhysicalDevicePresentationSupport + - @ref glfwCreateWindowSurface + +GLFW uses no synchronization objects internally except for thread-local storage +to keep track of the current context for each thread. Synchronization is left +to the application. + +Functions that may currently be called from any thread will always remain so, +but functions that are currently limited to the main thread may be updated to +allow calls from any thread in future releases. + + +@subsection compatibility Version compatibility + +GLFW guarantees source and binary backward compatibility with earlier minor +versions of the API. This means that you can drop in a newer version of the +library and existing programs will continue to compile and existing binaries +will continue to run. + +Once a function or constant has been added, the signature of that function or +value of that constant will remain unchanged until the next major version of +GLFW. No compatibility of any kind is guaranteed between major versions. + +Undocumented behavior, i.e. behavior that is not described in the documentation, +may change at any time until it is documented. + +If the reference documentation and the implementation differ, the reference +documentation is correct and the implementation will be fixed in the next +release. + + +@subsection event_order Event order + +The order of arrival of related events is not guaranteed to be consistent +across platforms. The exception is synthetic key and mouse button release +events, which are always delivered after the window defocus event. + + +@section intro_version Version management + +GLFW provides mechanisms for identifying what version of GLFW your application +was compiled against as well as what version it is currently running against. +If you are loading GLFW dynamically (not just linking dynamically), you can use +this to verify that the library binary is compatible with your application. + + +@subsection intro_version_compile Compile-time version + +The compile-time version of GLFW is provided by the GLFW header with the +`GLFW_VERSION_MAJOR`, `GLFW_VERSION_MINOR` and `GLFW_VERSION_REVISION` macros. + +@code +printf("Compiled against GLFW %i.%i.%i\n", + GLFW_VERSION_MAJOR, + GLFW_VERSION_MINOR, + GLFW_VERSION_REVISION); +@endcode + + +@subsection intro_version_runtime Run-time version + +The run-time version can be retrieved with @ref glfwGetVersion, a function that +may be called regardless of whether GLFW is initialized. + +@code +int major, minor, revision; +glfwGetVersion(&major, &minor, &revision); + +printf("Running against GLFW %i.%i.%i\n", major, minor, revision); +@endcode + + +@subsection intro_version_string Version string + +GLFW 3 also provides a compile-time generated version string that describes the +version, platform, compiler and any platform-specific compile-time options. +This is primarily intended for submitting bug reports, to allow developers to +see which code paths are enabled in a binary. + +The version string is returned by @ref glfwGetVersionString, a function that may +be called regardless of whether GLFW is initialized. + +__Do not use the version string__ to parse the GLFW library version. The @ref +glfwGetVersion function already provides the version of the running library +binary. + +The format of the string is as follows: + - The version of GLFW + - The name of the window system API + - The name of the context creation API + - Any additional options or APIs + +For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL +back ends, the version string may look something like this: + +@code +3.0.0 Win32 WGL MinGW +@endcode + +*/ diff --git a/extern/glfw-3.2.1/docs/main.dox b/extern/glfw-3.2.1/docs/main.dox new file mode 100644 index 0000000..19ad306 --- /dev/null +++ b/extern/glfw-3.2.1/docs/main.dox @@ -0,0 +1,47 @@ +/*! + +@mainpage notitle + +@section main_intro Introduction + +GLFW is a free, 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. + +See @ref news_32 for release highlights or the +[version history](http://www.glfw.org/changelog.html) for details. + +@ref quick_guide is a guide for users new to GLFW. It takes you through how to +write a small but complete program. + +There are guides for each section of the API: + + - @ref intro_guide – initialization, error handling and high-level design + - @ref window_guide – creating and working with windows and framebuffers + - @ref context_guide – working with OpenGL and OpenGL ES contexts + - @ref vulkan_guide - working with Vulkan objects and extensions + - @ref monitor_guide – enumerating and working with monitors and video modes + - @ref input_guide – receiving events, polling and processing input + +Once you have written a program, see @ref compile_guide and @ref build_guide. + +The [reference documentation](modules.html) provides more detailed information +about specific functions. + +@ref moving_guide explains what has changed and how to update existing code to +use the new API. + +There is a section on @ref guarantees_limitations for pointer lifetimes, +reentrancy, thread safety, event order and backward and forward compatibility. + +The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the +design, implementation and use of GLFW. + +Finally, @ref compat_guide explains what APIs, standards and protocols GLFW uses +and what happens when they are not present on a given machine. + +This documentation was generated with Doxygen. The sources for it are available +in both the [source distribution](http://www.glfw.org/download.html) and +[GitHub repository](https://github.com/glfw/glfw). + +*/ diff --git a/extern/glfw-3.2.1/docs/monitor.dox b/extern/glfw-3.2.1/docs/monitor.dox new file mode 100644 index 0000000..0aa0b05 --- /dev/null +++ b/extern/glfw-3.2.1/docs/monitor.dox @@ -0,0 +1,216 @@ +/*! + +@page monitor_guide Monitor guide + +@tableofcontents + +This guide introduces the monitor related functions of GLFW. For details on +a specific function in this category, see the @ref monitor. There are also +guides for the other areas of GLFW. + + - @ref intro_guide + - @ref window_guide + - @ref context_guide + - @ref vulkan_guide + - @ref input_guide + + +@section monitor_object Monitor objects + +A monitor object represents a currently connected monitor and is represented as +a pointer to the [opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type +@ref GLFWmonitor. Monitor objects cannot be created or destroyed by the +application and retain their addresses until the monitors they represent are +disconnected or until the library is [terminated](@ref intro_init_terminate). + +Each monitor has a current video mode, a list of supported video modes, +a virtual position, a human-readable name, an estimated physical size and +a gamma ramp. One of the monitors is the primary monitor. + +The virtual position of a monitor is in +[screen coordinates](@ref coordinate_systems) and, together with the current +video mode, describes the viewports that the connected monitors provide into the +virtual desktop that spans them. + +To see how GLFW views your monitor setup and its available video modes, run the +`monitors` test program. + + +@subsection monitor_monitors Retrieving monitors + +The primary monitor is returned by @ref glfwGetPrimaryMonitor. It is the user's +preferred monitor and is usually the one with global UI elements like task bar +or menu bar. + +@code +GLFWmonitor* primary = glfwGetPrimaryMonitor(); +@endcode + +You can retrieve all currently connected monitors with @ref glfwGetMonitors. +See the reference documentation for the lifetime of the returned array. + +@code +int count; +GLFWmonitor** monitors = glfwGetMonitors(&count); +@endcode + +The primary monitor is always the first monitor in the returned array, but other +monitors may be moved to a different index when a monitor is connected or +disconnected. + + +@subsection monitor_event Monitor configuration changes + +If you wish to be notified when a monitor is connected or disconnected, set +a monitor callback. + +@code +glfwSetMonitorCallback(monitor_callback); +@endcode + +The callback function receives the handle for the monitor that has been +connected or disconnected and the event that occurred. + +@code +void monitor_callback(GLFWmonitor* monitor, int event) +{ + if (event == GLFW_CONNECTED) + { + // The monitor was connected + } + else if (event == GLFW_DISCONNECTED) + { + // The monitor was disconnected + } +} +@endcode + +If a monitor is disconnected, any windows that are full screen on it get forced +into windowed mode. + + +@section monitor_properties Monitor properties + +Each monitor has a current video mode, a list of supported video modes, +a virtual position, a human-readable name, an estimated physical size and +a gamma ramp. + + +@subsection monitor_modes Video modes + +GLFW generally does a good job selecting a suitable video mode when you create +a full screen window, change its video mode or or make a windowed one full +screen, but it is sometimes useful to know exactly which video modes are +supported. + +Video modes are represented as @ref GLFWvidmode structures. You can get an +array of the video modes supported by a monitor with @ref glfwGetVideoModes. +See the reference documentation for the lifetime of the returned array. + +@code +int count; +GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); +@endcode + +To get the current video mode of a monitor call @ref glfwGetVideoMode. See the +reference documentation for the lifetime of the returned pointer. + +@code +const GLFWvidmode* mode = glfwGetVideoMode(monitor); +@endcode + +The resolution of a video mode is specified in +[screen coordinates](@ref coordinate_systems), not pixels. + + +@subsection monitor_size Physical size + +The physical size of a monitor in millimetres, or an estimation of it, can be +retrieved with @ref glfwGetMonitorPhysicalSize. This has no relation to its +current _resolution_, i.e. the width and height of its current +[video mode](@ref monitor_modes). + +@code +int widthMM, heightMM; +glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); +@endcode + +This can, for example, be used together with the current video mode to calculate +the DPI of a monitor. + +@code +const double dpi = mode->width / (widthMM / 25.4); +@endcode + + +@subsection monitor_pos Virtual position + +The position of the monitor on the virtual desktop, in +[screen coordinates](@ref coordinate_systems), can be retrieved with @ref +glfwGetMonitorPos. + +@code +int xpos, ypos; +glfwGetMonitorPos(monitor, &xpos, &ypos); +@endcode + + +@subsection monitor_name Human-readable name + +The human-readable, UTF-8 encoded name of a monitor is returned by @ref +glfwGetMonitorName. See the reference documentation for the lifetime of the +returned string. + +@code +const char* name = glfwGetMonitorName(monitor); +@endcode + +Monitor names are not guaranteed to be unique. Two monitors of the same model +and make may have the same name. Only the monitor handle is guaranteed to be +unique, and only until that monitor is disconnected. + + +@subsection monitor_gamma Gamma ramp + +The gamma ramp of a monitor can be set with @ref glfwSetGammaRamp, which accepts +a monitor handle and a pointer to a @ref GLFWgammaramp structure. + +@code +GLFWgammaramp ramp; +unsigned short red[256], green[256], blue[256]; + +ramp.size = 256; +ramp.red = red; +ramp.green = green; +ramp.blue = blue; + +for (i = 0; i < ramp.size; i++) +{ + // Fill out gamma ramp arrays as desired +} + +glfwSetGammaRamp(monitor, &ramp); +@endcode + +The gamma ramp data is copied before the function returns, so there is no need +to keep it around once the ramp has been set. + +@note It is recommended to use gamma ramps of size 256, as that is the size +supported by all graphics cards on all platforms. + +The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See +the reference documentation for the lifetime of the returned structure. + +@code +const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor); +@endcode + +If you wish to set a regular gamma ramp, you can have GLFW calculate it for you +from the desired exponent with @ref glfwSetGamma, which in turn calls @ref +glfwSetGammaRamp with the resulting ramp. + +@code +glfwSetGamma(monitor, 1.0); +@endcode + +*/ diff --git a/extern/glfw-3.2.1/docs/moving.dox b/extern/glfw-3.2.1/docs/moving.dox new file mode 100644 index 0000000..7baab6f --- /dev/null +++ b/extern/glfw-3.2.1/docs/moving.dox @@ -0,0 +1,506 @@ +/*! + +@page moving_guide Moving from GLFW 2 to 3 + +@tableofcontents + +This is a transition guide for moving from GLFW 2 to 3. It describes what has +changed or been removed, but does _not_ include +[new features](@ref news) unless they are required when moving an existing code +base onto the new API. For example, the new multi-monitor functions are +required to create full screen windows with GLFW 3. + + +@section moving_removed Changed and removed features + +@subsection moving_renamed_files Renamed library and header file + +The GLFW 3 header is named @ref glfw3.h and moved to the `GLFW` directory, to +avoid collisions with the headers of other major versions. Similarly, the GLFW +3 library is named `glfw3,` except when it's installed as a shared library on +Unix-like systems, where it uses the +[soname](https://en.wikipedia.org/wiki/soname) `libglfw.so.3`. + +@par Old syntax +@code +#include +@endcode + +@par New syntax +@code +#include +@endcode + + +@subsection moving_threads Removal of threading functions + +The threading functions have been removed, including the per-thread sleep +function. They were fairly primitive, under-used, poorly integrated and took +time away from the focus of GLFW (i.e. context, input and window). There are +better threading libraries available and native threading support is available +in both [C++11](http://en.cppreference.com/w/cpp/thread) and +[C11](http://en.cppreference.com/w/c/thread), both of which are gaining +traction. + +If you wish to use the C++11 or C11 facilities but your compiler doesn't yet +support them, see the +[TinyThread++](https://gitorious.org/tinythread/tinythreadpp) and +[TinyCThread](https://github.com/tinycthread/tinycthread) projects created by +the original author of GLFW. These libraries implement a usable subset of the +threading APIs in C++11 and C11, and in fact some GLFW 3 test programs use +TinyCThread. + +However, GLFW 3 has better support for _use from multiple threads_ than GLFW +2 had. Contexts can be made current on any thread, although only a single +thread at a time, and the documentation explicitly states which functions may be +used from any thread and which must only be used from the main thread. + +@par Removed functions +`glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`, +`glfwGetThreadID`, `glfwCreateMutex`, `glfwDestroyMutex`, `glfwLockMutex`, +`glfwUnlockMutex`, `glfwCreateCond`, `glfwDestroyCond`, `glfwWaitCond`, +`glfwSignalCond`, `glfwBroadcastCond` and `glfwGetNumberOfProcessors`. + +@par Removed types +`GLFWthreadfun` + + +@subsection moving_image Removal of image and texture loading + +The image and texture loading functions have been removed. They only supported +the Targa image format, making them mostly useful for beginner level examples. +To become of sufficiently high quality to warrant keeping them in GLFW 3, they +would need not only to support other formats, but also modern extensions to +OpenGL texturing. This would either add a number of external +dependencies (libjpeg, libpng, etc.), or force GLFW to ship with inline versions +of these libraries. + +As there already are libraries doing this, it is unnecessary both to duplicate +the work and to tie the duplicate to GLFW. The resulting library would also be +platform-independent, as both OpenGL and stdio are available wherever GLFW is. + +@par Removed functions +`glfwReadImage`, `glfwReadMemoryImage`, `glfwFreeImage`, `glfwLoadTexture2D`, +`glfwLoadMemoryTexture2D` and `glfwLoadTextureImage2D`. + + +@subsection moving_stdcall Removal of GLFWCALL macro + +The `GLFWCALL` macro, which made callback functions use +[__stdcall](http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows, +has been removed. GLFW is written in C, not Pascal. Removing this macro means +there's one less thing for application programmers to remember, i.e. the +requirement to mark all callback functions with `GLFWCALL`. It also simplifies +the creation of DLLs and DLL link libraries, as there's no need to explicitly +disable `@n` entry point suffixes. + +@par Old syntax +@code +void GLFWCALL callback_function(...); +@endcode + +@par New syntax +@code +void callback_function(...); +@endcode + + +@subsection moving_window_handles Window handle parameters + +Because GLFW 3 supports multiple windows, window handle parameters have been +added to all window-related GLFW functions and callbacks. The handle of +a newly created window is returned by @ref glfwCreateWindow (formerly +`glfwOpenWindow`). Window handles are pointers to the +[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWwindow. + +@par Old syntax +@code +glfwSetWindowTitle("New Window Title"); +@endcode + +@par New syntax +@code +glfwSetWindowTitle(window, "New Window Title"); +@endcode + + +@subsection moving_monitor Explicit monitor selection + +GLFW 3 provides support for multiple monitors. To request a full screen mode window, +instead of passing `GLFW_FULLSCREEN` you specify which monitor you wish the +window to use. The @ref glfwGetPrimaryMonitor function returns the monitor that +GLFW 2 would have selected, but there are many other +[monitor functions](@ref monitor_guide). Monitor handles are pointers to the +[opaque](https://en.wikipedia.org/wiki/Opaque_data_type) type @ref GLFWmonitor. + +@par Old basic full screen +@code +glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_FULLSCREEN); +@endcode + +@par New basic full screen +@code +window = glfwCreateWindow(640, 480, "My Window", glfwGetPrimaryMonitor(), NULL); +@endcode + +@note The framebuffer bit depth parameters of `glfwOpenWindow` have been turned +into [window hints](@ref window_hints), but as they have been given +[sane defaults](@ref window_hints_values) you rarely need to set these hints. + + +@subsection moving_autopoll Removal of automatic event polling + +GLFW 3 does not automatically poll for events in @ref glfwSwapBuffers, meaning +you need to call @ref glfwPollEvents or @ref glfwWaitEvents yourself. Unlike +buffer swap, which acts on a single window, the event processing functions act +on all windows at once. + +@par Old basic main loop +@code +while (...) +{ + // Process input + // Render output + glfwSwapBuffers(); +} +@endcode + +@par New basic main loop +@code +while (...) +{ + // Process input + // Render output + glfwSwapBuffers(window); + glfwPollEvents(); +} +@endcode + + +@subsection moving_context Explicit context management + +Each GLFW 3 window has its own OpenGL context and only you, the application +programmer, can know which context should be current on which thread at any +given time. Therefore, GLFW 3 leaves that decision to you. + +This means that you need to call @ref glfwMakeContextCurrent after creating +a window before you can call any OpenGL functions. + + +@subsection moving_hidpi Separation of window and framebuffer sizes + +Window positions and sizes now use screen coordinates, which may not be the same +as pixels on machines with high-DPI monitors. This is important as OpenGL uses +pixels, not screen coordinates. For example, the rectangle specified with +`glViewport` needs to use pixels. Therefore, framebuffer size functions have +been added. You can retrieve the size of the framebuffer of a window with @ref +glfwGetFramebufferSize function. A framebuffer size callback has also been +added, which can be set with @ref glfwSetFramebufferSizeCallback. + +@par Old basic viewport setup +@code +glfwGetWindowSize(&width, &height); +glViewport(0, 0, width, height); +@endcode + +@par New basic viewport setup +@code +glfwGetFramebufferSize(window, &width, &height); +glViewport(0, 0, width, height); +@endcode + + +@subsection moving_window_close Window closing changes + +The `GLFW_OPENED` window parameter has been removed. As long as the window has +not been destroyed, whether through @ref glfwDestroyWindow or @ref +glfwTerminate, the window is "open". + +A user attempting to close a window is now just an event like any other. Unlike +GLFW 2, windows and contexts created with GLFW 3 will never be destroyed unless +you choose them to be. Each window now has a close flag that is set to +`GLFW_TRUE` when the user attempts to close that window. By default, nothing else +happens and the window stays visible. It is then up to you to either destroy +the window, take some other action or simply ignore the request. + +You can query the close flag at any time with @ref glfwWindowShouldClose and set +it at any time with @ref glfwSetWindowShouldClose. + +@par Old basic main loop +@code +while (glfwGetWindowParam(GLFW_OPENED)) +{ + ... +} +@endcode + +@par New basic main loop +@code +while (!glfwWindowShouldClose(window)) +{ + ... +} +@endcode + +The close callback no longer returns a value. Instead, it is called after the +close flag has been set so it can override its value, if it chooses to, before +event processing completes. You may however not call @ref glfwDestroyWindow +from the close callback (or any other window related callback). + +@par Old syntax +@code +int GLFWCALL window_close_callback(void); +@endcode + +@par New syntax +@code +void window_close_callback(GLFWwindow* window); +@endcode + +@note GLFW never clears the close flag to `GLFW_FALSE`, meaning you can use it +for other reasons to close the window as well, for example the user choosing +Quit from an in-game menu. + + +@subsection moving_hints Persistent window hints + +The `glfwOpenWindowHint` function has been renamed to @ref glfwWindowHint. + +Window hints are no longer reset to their default values on window creation, but +instead retain their values until modified by @ref glfwWindowHint or @ref +glfwDefaultWindowHints, or until the library is terminated and re-initialized. + + +@subsection moving_video_modes Video mode enumeration + +Video mode enumeration is now per-monitor. The @ref glfwGetVideoModes function +now returns all available modes for a specific monitor instead of requiring you +to guess how large an array you need. The `glfwGetDesktopMode` function, which +had poorly defined behavior, has been replaced by @ref glfwGetVideoMode, which +returns the current mode of a monitor. + + +@subsection moving_char_up Removal of character actions + +The action parameter of the [character callback](@ref GLFWcharfun) has been +removed. This was an artefact of the origin of GLFW, i.e. being developed in +English by a Swede. However, many keyboard layouts require more than one key to +produce characters with diacritical marks. Even the Swedish keyboard layout +requires this for uncommon cases like ü. + +@par Old syntax +@code +void GLFWCALL character_callback(int character, int action); +@endcode + +@par New syntax +@code +void character_callback(GLFWwindow* window, int character); +@endcode + + +@subsection moving_cursorpos Cursor position changes + +The `glfwGetMousePos` function has been renamed to @ref glfwGetCursorPos, +`glfwSetMousePos` to @ref glfwSetCursorPos and `glfwSetMousePosCallback` to @ref +glfwSetCursorPosCallback. + +The cursor position is now `double` instead of `int`, both for the direct +functions and for the callback. Some platforms can provide sub-pixel cursor +movement and this data is now passed on to the application where available. On +platforms where this is not provided, the decimal part is zero. + +GLFW 3 only allows you to position the cursor within a window using @ref +glfwSetCursorPos (formerly `glfwSetMousePos`) when that window is active. +Unless the window is active, the function fails silently. + + +@subsection moving_wheel Wheel position replaced by scroll offsets + +The `glfwGetMouseWheel` function has been removed. Scrolling is the input of +offsets and has no absolute position. The mouse wheel callback has been +replaced by a [scroll callback](@ref GLFWscrollfun) that receives +two-dimensional floating point scroll offsets. This allows you to receive +precise scroll data from for example modern touchpads. + +@par Old syntax +@code +void GLFWCALL mouse_wheel_callback(int position); +@endcode + +@par New syntax +@code +void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); +@endcode + +@par Removed functions +`glfwGetMouseWheel` + + +@subsection moving_repeat Key repeat action + +The `GLFW_KEY_REPEAT` enable has been removed and key repeat is always enabled +for both keys and characters. A new key action, `GLFW_REPEAT`, has been added +to allow the [key callback](@ref GLFWkeyfun) to distinguish an initial key press +from a repeat. Note that @ref glfwGetKey still returns only `GLFW_PRESS` or +`GLFW_RELEASE`. + + +@subsection moving_keys Physical key input + +GLFW 3 key tokens map to physical keys, unlike in GLFW 2 where they mapped to +the values generated by the current keyboard layout. The tokens are named +according to the values they would have using the standard US layout, but this +is only a convenience, as most programmers are assumed to know that layout. +This means that (for example) `GLFW_KEY_LEFT_BRACKET` is always a single key and +is the same key in the same place regardless of what keyboard layouts the users +of your program has. + +The key input facility was never meant for text input, although using it that +way worked slightly better in GLFW 2. If you were using it to input text, you +should be using the character callback instead, on both GLFW 2 and 3. This will +give you the characters being input, as opposed to the keys being pressed. + +GLFW 3 has key tokens for all keys on a standard 105 key keyboard, so instead of +having to remember whether to check for `'a'` or `'A'`, you now check for +`GLFW_KEY_A`. + + +@subsection moving_joystick Joystick function changes + +The `glfwGetJoystickPos` function has been renamed to @ref glfwGetJoystickAxes. + +The `glfwGetJoystickParam` function and the `GLFW_PRESENT`, `GLFW_AXES` and +`GLFW_BUTTONS` tokens have been replaced by the @ref glfwJoystickPresent +function as well as axis and button counts returned by the @ref +glfwGetJoystickAxes and @ref glfwGetJoystickButtons functions. + + +@subsection moving_mbcs Win32 MBCS support + +The Win32 port of GLFW 3 will not compile in +[MBCS mode](http://msdn.microsoft.com/en-us/library/5z097dxa.aspx). +However, because the use of the Unicode version of the Win32 API doesn't affect +the process as a whole, but only those windows created using it, it's perfectly +possible to call MBCS functions from other parts of the same application. +Therefore, even if an application using GLFW has MBCS mode code, there's no need +for GLFW itself to support it. + + +@subsection moving_windows Support for versions of Windows older than XP + +All explicit support for version of Windows older than XP has been removed. +There is no code that actively prevents GLFW 3 from running on these earlier +versions, but it uses Win32 functions that those versions lack. + +Windows XP was released in 2001, and by now (January 2015) it has not only +replaced almost all earlier versions of Windows, but is itself rapidly being +replaced by Windows 7 and 8. The MSDN library doesn't even provide +documentation for version older than Windows 2000, making it difficult to +maintain compatibility with these versions even if it was deemed worth the +effort. + +The Win32 API has also not stood still, and GLFW 3 uses many functions only +present on Windows XP or later. Even supporting an OS as new as XP (new +from the perspective of GLFW 2, which still supports Windows 95) requires +runtime checking for a number of functions that are present only on modern +version of Windows. + + +@subsection moving_syskeys Capture of system-wide hotkeys + +The ability to disable and capture system-wide hotkeys like Alt+Tab has been +removed. Modern applications, whether they're games, scientific visualisations +or something else, are nowadays expected to be good desktop citizens and allow +these hotkeys to function even when running in full screen mode. + + +@subsection moving_terminate Automatic termination + +GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization, +because `exit` calls registered functions from the calling thread and while it +is permitted to call `exit` from any thread, @ref glfwTerminate must only be +called from the main thread. + +To release all resources allocated by GLFW, you should call @ref glfwTerminate +yourself, from the main thread, before the program terminates. Note that this +destroys all windows not already destroyed with @ref glfwDestroyWindow, +invalidating any window handles you may still have. + + +@subsection moving_glu GLU header inclusion + +GLFW 3 does not by default include the GLU header and GLU itself has been +deprecated by [Khronos](https://en.wikipedia.org/wiki/Khronos_Group). __New +projects should not use GLU__, but if you need it for legacy code that +has been moved to GLFW 3, you can request that the GLFW header includes it by +defining `GLFW_INCLUDE_GLU` before the inclusion of the GLFW header. + +@par Old syntax +@code +#include +@endcode + +@par New syntax +@code +#define GLFW_INCLUDE_GLU +#include +@endcode + + +@section moving_tables Name change tables + + +@subsection moving_renamed_functions Renamed functions + +| GLFW 2 | GLFW 3 | Notes | +| --------------------------- | ----------------------------- | ----- | +| `glfwOpenWindow` | @ref glfwCreateWindow | All channel bit depths are now hints +| `glfwCloseWindow` | @ref glfwDestroyWindow | | +| `glfwOpenWindowHint` | @ref glfwWindowHint | Now accepts all `GLFW_*_BITS` tokens | +| `glfwEnable` | @ref glfwSetInputMode | | +| `glfwDisable` | @ref glfwSetInputMode | | +| `glfwGetMousePos` | @ref glfwGetCursorPos | | +| `glfwSetMousePos` | @ref glfwSetCursorPos | | +| `glfwSetMousePosCallback` | @ref glfwSetCursorPosCallback | | +| `glfwSetMouseWheelCallback` | @ref glfwSetScrollCallback | Accepts two-dimensional scroll offsets as doubles | +| `glfwGetJoystickPos` | @ref glfwGetJoystickAxes | | +| `glfwGetWindowParam` | @ref glfwGetWindowAttrib | | +| `glfwGetGLVersion` | @ref glfwGetWindowAttrib | Use `GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and `GLFW_CONTEXT_REVISION` | +| `glfwGetDesktopMode` | @ref glfwGetVideoMode | Returns the current mode of a monitor | +| `glfwGetJoystickParam` | @ref glfwJoystickPresent | The axis and button counts are provided by @ref glfwGetJoystickAxes and @ref glfwGetJoystickButtons | + + +@subsection moving_renamed_types Renamed types + +| GLFW 2 | GLFW 3 | Notes | +| ------------------- | --------------------- | | +| `GLFWmousewheelfun` | @ref GLFWscrollfun | | +| `GLFWmouseposfun` | @ref GLFWcursorposfun | | + + +@subsection moving_renamed_tokens Renamed tokens + +| GLFW 2 | GLFW 3 | Notes | +| --------------------------- | ---------------------------- | ----- | +| `GLFW_OPENGL_VERSION_MAJOR` | `GLFW_CONTEXT_VERSION_MAJOR` | Renamed as it applies to OpenGL ES as well | +| `GLFW_OPENGL_VERSION_MINOR` | `GLFW_CONTEXT_VERSION_MINOR` | Renamed as it applies to OpenGL ES as well | +| `GLFW_FSAA_SAMPLES` | `GLFW_SAMPLES` | Renamed to match the OpenGL API | +| `GLFW_ACTIVE` | `GLFW_FOCUSED` | Renamed to match the window focus callback | +| `GLFW_WINDOW_NO_RESIZE` | `GLFW_RESIZABLE` | The default has been inverted | +| `GLFW_MOUSE_CURSOR` | `GLFW_CURSOR` | Used with @ref glfwSetInputMode | +| `GLFW_KEY_ESC` | `GLFW_KEY_ESCAPE` | | +| `GLFW_KEY_DEL` | `GLFW_KEY_DELETE` | | +| `GLFW_KEY_PAGEUP` | `GLFW_KEY_PAGE_UP` | | +| `GLFW_KEY_PAGEDOWN` | `GLFW_KEY_PAGE_DOWN` | | +| `GLFW_KEY_KP_NUM_LOCK` | `GLFW_KEY_NUM_LOCK` | | +| `GLFW_KEY_LCTRL` | `GLFW_KEY_LEFT_CONTROL` | | +| `GLFW_KEY_LSHIFT` | `GLFW_KEY_LEFT_SHIFT` | | +| `GLFW_KEY_LALT` | `GLFW_KEY_LEFT_ALT` | | +| `GLFW_KEY_LSUPER` | `GLFW_KEY_LEFT_SUPER` | | +| `GLFW_KEY_RCTRL` | `GLFW_KEY_RIGHT_CONTROL` | | +| `GLFW_KEY_RSHIFT` | `GLFW_KEY_RIGHT_SHIFT` | | +| `GLFW_KEY_RALT` | `GLFW_KEY_RIGHT_ALT` | | +| `GLFW_KEY_RSUPER` | `GLFW_KEY_RIGHT_SUPER` | | + +*/ diff --git a/extern/glfw-3.2.1/docs/news.dox b/extern/glfw-3.2.1/docs/news.dox new file mode 100644 index 0000000..b7cd43f --- /dev/null +++ b/extern/glfw-3.2.1/docs/news.dox @@ -0,0 +1,376 @@ +/*! + +@page news New features + +@section news_32 New features in 3.2 + + +@subsection news_32_vulkan Support for Vulkan + +GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported, +@ref glfwGetRequiredInstanceExtensions, @ref glfwGetInstanceProcAddress, @ref +glfwGetPhysicalDevicePresentationSupport and @ref glfwCreateWindowSurface. +Vulkan header inclusion can be selected with +[GLFW_INCLUDE_VULKAN](@ref build_macros). + + +@subsection news_32_setwindowmonitor Window mode switching + +GLFW now supports switching between windowed and full screen modes and updating +the monitor and desired resolution and refresh rate of full screen windows with +@ref glfwSetWindowMonitor. + + +@subsection news_32_maximize Window maxmimization support + +GLFW now supports window maximization with @ref glfwMaximizeWindow and the +[GLFW_MAXIMIZED](@ref window_attribs_wnd) window hint and attribute. + + +@subsection news_32_focus Window input focus control + +GLFW now supports giving windows input focus with @ref glfwFocusWindow. + + +@subsection news_32_sizelimits Window size limit support + +GLFW now supports setting both absolute and relative window size limits with +@ref glfwSetWindowSizeLimits and @ref glfwSetWindowAspectRatio. + + +@subsection news_32_keyname Localized key names + +GLFW now supports querying the localized name of printable keys with @ref +glfwGetKeyName, either by key token or by scancode. + + +@subsection news_32_waittimeout Wait for events with timeout + +GLFW now supports waiting for events for a set amount of time with @ref +glfwWaitEventsTimeout. + + +@subsection news_32_icon Window icon support + +GLFW now supports setting the icon of windows with @ref glfwSetWindowIcon. + + +@subsection news_32_timer Raw timer access + +GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref +glfwGetTimerFrequency. + + +@subsection news_32_joystick Joystick connection callback + +GLFW now supports notifying when a joystick has been connected or disconnected +with @ref glfwSetJoystickCallback. + + +@subsection news_32_noapi Context-less windows + +GLFW now supports creating windows without a OpenGL or OpenGL ES context with +[GLFW_NO_API](@ref window_hints_ctx). + + +@subsection news_32_contextapi Run-time context creation API selection + +GLFW now supports selecting the context creation API at run-time with the +[GLFW_CONTEXT_CREATION_API](@ref window_hints_ctx) window hint value. + + +@subsection news_32_noerror Error-free context creation + +GLFW now supports creating OpenGL and OpenGL ES contexts that do not emit errors +with the [GLFW_CONTEXT_NO_ERROR](@ref window_hints_ctx) window hint, provided +the machine supports the `GL_KHR_no_error` extension. + + +@subsection news_32_cmake CMake config-file package support + +GLFW now supports being used as a +[config-file package](@ref build_link_cmake_package) from other projects for +easy linking with the library and its dependencies. + + +@section news_31 New features in 3.1 + +These are the release highlights. For a full list of changes see the +[version history](http://www.glfw.org/changelog.html). + + +@subsection news_31_cursor Custom mouse cursor images + +GLFW now supports creating and setting both custom cursor images and standard +cursor shapes. They are created with @ref glfwCreateCursor or @ref +glfwCreateStandardCursor, set with @ref glfwSetCursor and destroyed with @ref +glfwDestroyCursor. + +@see @ref cursor_object + + +@subsection news_31_drop Path drop event + +GLFW now provides a callback for receiving the paths of files and directories +dropped onto GLFW windows. The callback is set with @ref glfwSetDropCallback. + +@see @ref path_drop + + +@subsection news_31_emptyevent Main thread wake-up + +GLFW now provides the @ref glfwPostEmptyEvent function for posting an empty +event from another thread to the main thread event queue, causing @ref +glfwWaitEvents to return. + +@see @ref events + + +@subsection news_31_framesize Window frame size query + +GLFW now supports querying the size, on each side, of the frame around the +client area of a window, with @ref glfwGetWindowFrameSize. + +@see [Window size](@ref window_size) + + +@subsection news_31_autoiconify Simultaneous multi-monitor rendering + +GLFW now supports disabling auto-iconification of full screen windows with +the [GLFW_AUTO_ICONIFY](@ref window_hints_wnd) window hint. This is intended +for people building multi-monitor installations, where you need windows to stay +in full screen despite losing input focus. + + +@subsection news_31_floating Floating windows + +GLFW now supports floating windows, also called topmost or always on top, for +easier debugging with the [GLFW_FLOATING](@ref window_hints_wnd) window hint. + + +@subsection news_31_focused Initially unfocused windows + +GLFW now supports preventing a windowed mode window from gaining input focus on +creation, with the [GLFW_FOCUSED](@ref window_hints_wnd) window hint. + + +@subsection news_31_direct Direct access for window attributes and cursor position + +GLFW now queries the window input focus, visibility and iconification attributes +and the cursor position directly instead of returning cached data. + + +@subsection news_31_charmods Character with modifiers callback + +GLFW now provides a callback for character events with modifier key bits. The +callback is set with @ref glfwSetCharModsCallback. Unlike the regular character +callback, this will report character events that will not result in a character +being input, for example if the Control key is held down. + +@see @ref input_char + + +@subsection news_31_single Single buffered framebuffers + +GLFW now supports the creation of single buffered windows, with the +[GLFW_DOUBLEBUFFER](@ref window_hints_fb) window hint. + + +@subsection news_31_glext Macro for including extension header + +GLFW now includes the extension header appropriate for the chosen OpenGL or +OpenGL ES header when [GLFW_INCLUDE_GLEXT](@ref build_macros) is defined. GLFW +does not provide these headers. They must be provided by your development +environment or your OpenGL or OpenGL ES SDK. + + +@subsection news_31_release Context release behaviors + +GLFW now supports controlling whether the pipeline is flushed when a context is +made non-current, with the +[GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint, provided the +machine supports the `GL_KHR_context_flush_control` extension. + + +@subsection news_31_wayland (Experimental) Wayland support + +GLFW now has an _experimental_ Wayland display protocol backend that can be +selected on Linux with a CMake option. + + +@subsection news_31_mir (Experimental) Mir support + +GLFW now has an _experimental_ Mir display server backend that can be selected +on Linux with a CMake option. + + +@section news_30 New features in 3.0 + +These are the release highlights. For a full list of changes see the +[version history](http://www.glfw.org/changelog.html). + + +@subsection news_30_cmake CMake build system + +GLFW now uses the CMake build system instead of the various makefiles and +project files used by earlier versions. CMake is available for all platforms +supported by GLFW, is present in most package systems and can generate +makefiles and/or project files for most popular development environments. + +For more information on how to use CMake, see the +[CMake manual](http://cmake.org/cmake/help/documentation.html). + + +@subsection news_30_multiwnd Multi-window support + +GLFW now supports the creation of multiple windows, each with their own OpenGL +or OpenGL ES context, and all window functions now take a window handle. Event +callbacks are now per-window and are provided with the handle of the window that +received the event. The @ref glfwMakeContextCurrent function has been added to +select which context is current on a given thread. + + +@subsection news_30_multimon Multi-monitor support + +GLFW now explicitly supports multiple monitors. They can be enumerated with +@ref glfwGetMonitors, queried with @ref glfwGetVideoModes, @ref +glfwGetMonitorPos, @ref glfwGetMonitorName and @ref glfwGetMonitorPhysicalSize, +and specified at window creation to make the newly created window full screen on +that specific monitor. + + +@subsection news_30_unicode Unicode support + +All string arguments to GLFW functions and all strings returned by GLFW now use +the UTF-8 encoding. This includes the window title, error string, clipboard +text, monitor and joystick names as well as the extension function arguments (as +ASCII is a subset of UTF-8). + + +@subsection news_30_clipboard Clipboard text I/O + +GLFW now supports reading and writing plain text to and from the system +clipboard, with the @ref glfwGetClipboardString and @ref glfwSetClipboardString +functions. + + +@subsection news_30_gamma Gamma ramp support + +GLFW now supports setting and reading back the gamma ramp of monitors, with the +@ref glfwGetGammaRamp and @ref glfwSetGammaRamp functions. There is also @ref +glfwSetGamma, which generates a ramp from a gamma value and then sets it. + + +@subsection news_30_gles OpenGL ES support + +GLFW now supports the creation of OpenGL ES contexts, by setting the +`GLFW_CLIENT_API` window hint to `GLFW_OPENGL_ES_API`, where creation of such +contexts are supported. Note that GLFW _does not implement_ OpenGL ES, so your +driver must provide support in a way usable by GLFW. Modern Nvidia and Intel +drivers support creation of OpenGL ES context using the GLX and WGL APIs, while +AMD provides an EGL implementation instead. + + +@subsection news_30_egl (Experimental) EGL support + +GLFW now has an experimental EGL context creation back end that can be selected +through CMake options. + + +@subsection news_30_hidpi High-DPI support + +GLFW now supports high-DPI monitors on both Windows and OS X, giving windows full +resolution framebuffers where other UI elements are scaled up. To achieve this, +@ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have been +added. These work with pixels, while the rest of the GLFW API works with screen +coordinates. This is important as OpenGL uses pixels, not screen coordinates. + + +@subsection news_30_error Error callback + +GLFW now has an error callback, which can provide your application with much +more detailed diagnostics than was previously possible. The callback is passed +an error code and a description string. + + +@subsection news_30_wndptr Per-window user pointer + +Each window now has a user-defined pointer, retrieved with @ref +glfwGetWindowUserPointer and set with @ref glfwSetWindowUserPointer, to make it +easier to integrate GLFW into C++ code. + + +@subsection news_30_iconifyfun Window iconification callback + +Each window now has a callback for iconification and restoration events, +which is set with @ref glfwSetWindowIconifyCallback. + + +@subsection news_30_wndposfun Window position callback + +Each window now has a callback for position events, which is set with @ref +glfwSetWindowPosCallback. + + +@subsection news_30_wndpos Window position query + +The position of a window can now be retrieved using @ref glfwGetWindowPos. + + +@subsection news_30_focusfun Window focus callback + +Each windows now has a callback for focus events, which is set with @ref +glfwSetWindowFocusCallback. + + +@subsection news_30_enterleave Cursor enter/leave callback + +Each window now has a callback for when the mouse cursor enters or leaves its +client area, which is set with @ref glfwSetCursorEnterCallback. + + +@subsection news_30_wndtitle Initial window title + +The title of a window is now specified at creation time, as one of the arguments +to @ref glfwCreateWindow. + + +@subsection news_30_hidden Hidden windows + +Windows can now be hidden with @ref glfwHideWindow, shown using @ref +glfwShowWindow and created initially hidden with the `GLFW_VISIBLE` window hint. +This allows for off-screen rendering in a way compatible with most drivers, as +well as moving a window to a specific position before showing it. + + +@subsection news_30_undecorated Undecorated windows + +Windowed mode windows can now be created without decorations, e.g. things like +a frame, a title bar, with the `GLFW_DECORATED` window hint. This allows for +the creation of things like splash screens. + + +@subsection news_30_keymods Modifier key bit masks + +[Modifier key bit mask](@ref mods) parameters have been added to the +[mouse button](@ref GLFWmousebuttonfun) and [key](@ref GLFWkeyfun) callbacks. + + +@subsection news_30_scancode Platform-specific scancodes + +A scancode parameter has been added to the [key callback](@ref GLFWkeyfun). Keys +that don't have a [key token](@ref keys) still get passed on with the key +parameter set to `GLFW_KEY_UNKNOWN`. These scancodes will vary between machines +and are intended to be used for key bindings. + + +@subsection news_30_jsname Joystick names + +The name of a joystick can now be retrieved using @ref glfwGetJoystickName. + + +@subsection news_30_doxygen Doxygen documentation + +You are reading it. + +*/ diff --git a/extern/glfw-3.2.1/docs/quick.dox b/extern/glfw-3.2.1/docs/quick.dox new file mode 100644 index 0000000..dccc834 --- /dev/null +++ b/extern/glfw-3.2.1/docs/quick.dox @@ -0,0 +1,364 @@ +/*! + +@page quick_guide Getting started + +@tableofcontents + +This guide takes you through writing a simple application using GLFW 3. The +application will create a window and OpenGL context, render a rotating triangle +and exit when the user closes the window or presses _Escape_. This guide will +introduce a few of the most commonly used functions, but there are many more. + +This guide assumes no experience with earlier versions of GLFW. If you +have used GLFW 2 in the past, read @ref moving_guide, as some functions +behave differently in GLFW 3. + + +@section quick_steps Step by step + +@subsection quick_include Including the GLFW header + +In the source files of your application where you use OpenGL or GLFW, you need +to include the GLFW 3 header file. + +@code +#include +@endcode + +This defines all the constants, types and function prototypes of the GLFW API. +It also includes the OpenGL header from your development environment and +defines all the constants and types necessary for it to work on your platform +without including any platform-specific headers. + +In other words: + +- Do _not_ include the OpenGL header yourself, as GLFW does this for you in + a platform-independent way +- Do _not_ include `windows.h` or other platform-specific headers unless + you plan on using those APIs yourself +- If you _do_ need to include such headers, include them _before_ the GLFW + header and it will detect this + +On some platforms supported by GLFW the OpenGL header and link library only +expose older versions of OpenGL. The most extreme case is Windows, which only +exposes OpenGL 1.2. The easiest way to work around this is to use an +[extension loader library](@ref context_glext_auto). + +If you are using such a library then you should include its header _before_ the +GLFW header. This lets it replace the OpenGL header included by GLFW without +conflicts. This example uses +[glad](https://github.com/Dav1dde/glad), but the same rule applies to all such +libraries. + +@code +#include +#include +@endcode + + +@subsection quick_init_term Initializing and terminating GLFW + +Before you can use most GLFW functions, the library must be initialized. On +successful initialization, `GLFW_TRUE` is returned. If an error occurred, +`GLFW_FALSE` is returned. + +@code +if (!glfwInit()) +{ + // Initialization failed +} +@endcode + +Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be just one and zero. + +When you are done using GLFW, typically just before the application exits, you +need to terminate GLFW. + +@code +glfwTerminate(); +@endcode + +This destroys any remaining windows and releases any other resources allocated by +GLFW. After this call, you must initialize GLFW again before using any GLFW +functions that require it. + + +@subsection quick_capture_error Setting an error callback + +Most events are reported through callbacks, whether it's a key being pressed, +a GLFW window being moved, or an error occurring. Callbacks are simply +C functions (or C++ static methods) that are called by GLFW with arguments +describing the event. + +In case a GLFW function fails, an error is reported to the GLFW error callback. +You can receive these reports with an error callback. This function must have +the signature below. This simple error callback just prints the error +description to `stderr`. + +@code +void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} +@endcode + +Callback functions must be set, so GLFW knows to call them. The function to set +the error callback is one of the few GLFW functions that may be called before +initialization, which lets you be notified of errors both during and after +initialization. + +@code +glfwSetErrorCallback(error_callback); +@endcode + + +@subsection quick_create_window Creating a window and context + +The window and its OpenGL context are created with a single call to @ref +glfwCreateWindow, which returns a handle to the created combined window and +context object + +@code +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); +if (!window) +{ + // Window or OpenGL context creation failed +} +@endcode + +This creates a 640 by 480 windowed mode window with an OpenGL context. If +window or OpenGL context creation fails, `NULL` will be returned. You should +always check the return value. While window creation rarely fails, context +creation depends on properly installed drivers and may fail even on machines +with the necessary hardware. + +By default, the OpenGL context GLFW creates may have any version. You can +require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and +`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum +version is not supported on the machine, context (and window) creation fails. + +@code +glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); +glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); +if (!window) +{ + // Window or context creation failed +} +@endcode + +The window handle is passed to all window related functions and is provided to +along to all window related callbacks, so they can tell which window received +the event. + +When a window and context is no longer needed, destroy it. + +@code +glfwDestroyWindow(window); +@endcode + +Once this function is called, no more events will be delivered for that window +and its handle becomes invalid. + + +@subsection quick_context_current Making the OpenGL context current + +Before you can use the OpenGL API, you must have a current OpenGL context. + +@code +glfwMakeContextCurrent(window); +@endcode + +The context will remain current until you make another context current or until +the window owning the current context is destroyed. + +If you are using an [extension loader library](@ref context_glext_auto) to +access modern OpenGL then this is when to initialize it, as the loader needs +a current context to load from. This example uses +[glad](https://github.com/Dav1dde/glad), but the same rule applies to all such +libraries. + +@code +gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); +@endcode + + +@subsection quick_window_close Checking the window close flag + +Each window has a flag indicating whether the window should be closed. + +When the user attempts to close the window, either by pressing the close widget +in the title bar or using a key combination like Alt+F4, this flag is set to 1. +Note that __the window isn't actually closed__, so you are expected to monitor +this flag and either destroy the window or give some kind of feedback to the +user. + +@code +while (!glfwWindowShouldClose(window)) +{ + // Keep running +} +@endcode + +You can be notified when the user is attempting to close the window by setting +a close callback with @ref glfwSetWindowCloseCallback. The callback will be +called immediately after the close flag has been set. + +You can also set it yourself with @ref glfwSetWindowShouldClose. This can be +useful if you want to interpret other kinds of input as closing the window, like +for example pressing the _Escape_ key. + + +@subsection quick_key_input Receiving input events + +Each window has a large number of callbacks that can be set to receive all the +various kinds of events. To receive key press and release events, create a key +callback function. + +@code +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} +@endcode + +The key callback, like other window related callbacks, are set per-window. + +@code +glfwSetKeyCallback(window, key_callback); +@endcode + +In order for event callbacks to be called when events occur, you need to process +events as described below. + + +@subsection quick_render Rendering with OpenGL + +Once you have a current OpenGL context, you can use OpenGL normally. In this +tutorial, a multi-colored rotating triangle will be rendered. The framebuffer +size needs to be retrieved for `glViewport`. + +@code +int width, height; +glfwGetFramebufferSize(window, &width, &height); +glViewport(0, 0, width, height); +@endcode + +You can also set a framebuffer size callback using @ref +glfwSetFramebufferSizeCallback and be notified when the size changes. + +Actual rendering with OpenGL is outside the scope of this tutorial, but there +are [many](https://open.gl/) [excellent](http://learnopengl.com/) +[tutorial](http://openglbook.com/) [sites](http://ogldev.atspace.co.uk/) that +teach modern OpenGL. Some of them use GLFW to create the context and window +while others use GLUT or SDL, but remember that OpenGL itself always works the +same. + + +@subsection quick_timer Reading the timer + +To create smooth animation, a time source is needed. GLFW provides a timer that +returns the number of seconds since initialization. The time source used is the +most accurate on each platform and generally has micro- or nanosecond +resolution. + +@code +double time = glfwGetTime(); +@endcode + + +@subsection quick_swap_buffers Swapping buffers + +GLFW windows by default use double buffering. That means that each window has +two rendering buffers; a front buffer and a back buffer. The front buffer is +the one being displayed and the back buffer the one you render to. + +When the entire frame has been rendered, the buffers need to be swapped with one +another, so the back buffer becomes the front buffer and vice versa. + +@code +glfwSwapBuffers(window); +@endcode + +The swap interval indicates how many frames to wait until swapping the buffers, +commonly known as _vsync_. By default, the swap interval is zero, meaning +buffer swapping will occur immediately. On fast machines, many of those frames +will never be seen, as the screen is still only updated typically 60-75 times +per second, so this wastes a lot of CPU and GPU cycles. + +Also, because the buffers will be swapped in the middle the screen update, +leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing). + +For these reasons, applications will typically want to set the swap interval to +one. It can be set to higher values, but this is usually not recommended, +because of the input latency it leads to. + +@code +glfwSwapInterval(1); +@endcode + +This function acts on the current context and will fail unless a context is +current. + + +@subsection quick_process_events Processing events + +GLFW needs to communicate regularly with the window system both in order to +receive events and to show that the application hasn't locked up. Event +processing must be done regularly while you have visible windows and is normally +done each frame after buffer swapping. + +There are two methods for processing pending events; polling and waiting. This +example will use event polling, which processes only those events that have +already been received and then returns immediately. + +@code +glfwPollEvents(); +@endcode + +This is the best choice when rendering continually, like most games do. If +instead you only need to update your rendering once you have received new input, +@ref glfwWaitEvents is a better choice. It waits until at least one event has +been received, putting the thread to sleep in the meantime, and then processes +all received events. This saves a great deal of CPU cycles and is useful for, +for example, many kinds of editing tools. + + +@section quick_example Putting it together + +Now that you know how to initialize GLFW, create a window and poll for +keyboard input, it's possible to create a simple program. + +This program creates a 640 by 480 windowed mode window and starts a loop that +clears the screen, renders a triangle and processes events until the user either +presses _Escape_ or closes the window. + +@snippet simple.c code + +The program above can be found in the +[source package](http://www.glfw.org/download.html) as `examples/simple.c` +and is compiled along with all other examples when you build GLFW. If you +built GLFW from the source package then already have this as `simple.exe` on +Windows, `simple` on Linux or `simple.app` on OS X. + +This tutorial used only a few of the many functions GLFW provides. There are +guides for each of the areas covered by GLFW. Each guide will introduce all the +functions for that category. + + - @ref intro_guide + - @ref window_guide + - @ref context_guide + - @ref monitor_guide + - @ref input_guide + +You can access reference documentation for any GLFW function by clicking it and +the reference for each function links to related functions and guide sections. + +The tutorial ends here. Once you have written a program that uses GLFW, you +will need to compile and link it. How to do that depends on the development +environment you are using and is best explained by the documentation for that +environment. To learn about the details that are specific to GLFW, see +@ref build_guide. + +*/ diff --git a/extern/glfw-3.2.1/docs/spaces.svg b/extern/glfw-3.2.1/docs/spaces.svg new file mode 100644 index 0000000..562fa8b --- /dev/null +++ b/extern/glfw-3.2.1/docs/spaces.svg @@ -0,0 +1,872 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extern/glfw-3.2.1/docs/vulkan.dox b/extern/glfw-3.2.1/docs/vulkan.dox new file mode 100644 index 0000000..e704222 --- /dev/null +++ b/extern/glfw-3.2.1/docs/vulkan.dox @@ -0,0 +1,211 @@ +/*! + +@page vulkan_guide Vulkan guide + +@tableofcontents + +This guide is intended to fill the gaps between the [Vulkan +documentation](https://www.khronos.org/vulkan/) and the rest of the GLFW +documentation and is not a replacement for either. It assumes some familiarity +with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to +the Vulkan documentation to explain the details of Vulkan functions. + +To develop for Vulkan you should install an SDK for your platform, for example +the [LunarG Vulkan SDK](https://vulkan.lunarg.com/). Apart from the headers and +libraries, it also provides the validation layers necessary for development. + +The GLFW library does not need the Vulkan SDK to enable support for Vulkan. +However, any Vulkan-specific test and example programs are built only if the +CMake files find a Vulkan SDK. + +For details on a specific function in this category, see the @ref vulkan. There +are also guides for the other areas of the GLFW API. + + - @ref intro_guide + - @ref window_guide + - @ref context_guide + - @ref monitor_guide + - @ref input_guide + + +@section vulkan_include Including the Vulkan and GLFW header files + +To include the Vulkan header, define [GLFW_INCLUDE_VULKAN](@ref build_macros) +before including the GLFW header. + +@code +#define GLFW_INCLUDE_VULKAN +#include +@endcode + +If you instead want to include the Vulkan header from a custom location or use +your own custom Vulkan header then do this before the GLFW header. + +@code +#include +#include +@endcode + +Unless a Vulkan header is included, either by the GLFW header or above it, any +GLFW functions that take or return Vulkan types will not be declared. + +The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part +of GLFW to work. Define them only if you are using these extensions directly. + + +@section vulkan_support Querying for Vulkan support + +If you are linking directly against the Vulkan loader then you can skip this +section. The canonical desktop loader library exports all Vulkan core and +Khronos extension functions, allowing them to be called directly. + +If you are loading the Vulkan loader dynamically instead of linking directly +against it, you can check for the availability of a loader with @ref +glfwVulkanSupported. + +@code +if (glfwVulkanSupported()) +{ + // Vulkan is available, at least for compute +} +@endcode + +This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is +performed by @ref glfwInit. + +If no loader was found, calling any other Vulkan related GLFW function will +generate a @ref GLFW_API_UNAVAILABLE error. + + +@subsection vulkan_proc Querying Vulkan function pointers + +To load any Vulkan core or extension function from the found loader, call @ref +glfwGetInstanceProcAddress. To load functions needed for instance creation, +pass `NULL` as the instance. + +@code +PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance) + glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); +@endcode + +Once you have created an instance, you can load from it all other Vulkan core +functions and functions from any instance extensions you enabled. + +@code +PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice) + glfwGetInstanceProcAddress(instance, "vkCreateDevice"); +@endcode + +This function in turn calls `vkGetInstanceProcAddr`. If that fails, the +function falls back to a platform-specific query of the Vulkan loader (i.e. +`dlsym` or `GetProcAddress`). If that also fails, the function returns `NULL`. +For more information about `vkGetInstanceProcAddr`, see the Vulkan +documentation. + +Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions +of Vulkan function. This function can be retrieved from an instance with @ref +glfwGetInstanceProcAddress. + +@code +PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) + glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); +@endcode + +Device-specific functions may execute a little bit faster, due to not having to +dispatch internally based on the device passed to them. For more information +about `vkGetDeviceProcAddr`, see the Vulkan documentation. + + +@section vulkan_ext Querying required Vulkan extensions + +To do anything useful with Vulkan you need to create an instance. If you want +to use Vulkan to render to a window, you must enable the instance extensions +GLFW requires to create Vulkan surfaces. + +To query the instance extensions required, call @ref +glfwGetRequiredInstanceExtensions. + +@code +uint32_t count; +const char** extensions = glfwGetRequiredInstanceExtensions(&count); +@endcode + +These extensions must all be enabled when creating instances that are going to +be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref +glfwCreateWindowSurface. The set of extensions will vary depending on platform +and may also vary depending on graphics drivers and other factors. + +If it fails it will return `NULL` and GLFW will not be able to create Vulkan +window surfaces. You can still use Vulkan for off-screen rendering and compute +work. + +The returned array will always contain `VK_KHR_surface`, so if you don't +require any additional extensions you can pass this list directly to the +`VkInstanceCreateInfo` struct. + +@code +VkInstanceCreateInfo ici; + +memset(&ici, 0, sizeof(ici)); +ici.enabledExtensionCount = count; +ici.ppEnabledExtensionNames = extensions; +... +@endcode + +Additional extensions may be required by future versions of GLFW. You should +check whether any extensions you wish to enable are already in the returned +array, as it is an error to specify an extension more than once in the +`VkInstanceCreateInfo` struct. + + +@section vulkan_present Querying for Vulkan presentation support + +Not every queue family of every Vulkan device can present images to surfaces. +To check whether a specific queue family of a physical device supports image +presentation without first having to create a window and surface, call @ref +glfwGetPhysicalDevicePresentationSupport. + +@code +if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index)) +{ + // Queue family supports image presentation +} +@endcode + +The `VK_KHR_surface` extension additionally provides the +`vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on +an existing Vulkan surface. + + +@section vulkan_window Creating the window + +Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan, +there is no need to create a context. You can disable context creation with the +[GLFW_CLIENT_API](@ref window_hints_ctx) hint. + +@code +glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); +GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL); +@endcode + +See @ref context_less for more information. + + +@section vulkan_surface Creating a Vulkan window surface + +You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension) +for a GLFW window with @ref glfwCreateWindowSurface. + +@code +VkSurfaceKHR surface; +VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface); +if (err) +{ + // Window surface creation failed +} +@endcode + +It is your responsibility to destroy the surface. GLFW does not destroy it for +you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it. + +*/ diff --git a/extern/glfw-3.2.1/docs/window.dox b/extern/glfw-3.2.1/docs/window.dox new file mode 100644 index 0000000..40a1b97 --- /dev/null +++ b/extern/glfw-3.2.1/docs/window.dox @@ -0,0 +1,1008 @@ +/*! + +@page window_guide Window guide + +@tableofcontents + +This guide introduces the window related functions of GLFW. For details on +a specific function in this category, see the @ref window. There are also +guides for the other areas of GLFW. + + - @ref intro_guide + - @ref context_guide + - @ref vulkan_guide + - @ref monitor_guide + - @ref input_guide + + +@section window_object Window objects + +The @ref GLFWwindow object encapsulates both a window and a context. They are +created with @ref glfwCreateWindow and destroyed with @ref glfwDestroyWindow, or +@ref glfwTerminate, if any remain. As the window and context are inseparably +linked, the object pointer is used as both a context and window handle. + +To see the event stream provided to the various window related callbacks, run +the `events` test program. + + +@subsection window_creation Window creation + +A window and its OpenGL or OpenGL ES context are created with @ref +glfwCreateWindow, which returns a handle to the created window object. For +example, this creates a 640 by 480 windowed mode window: + +@code +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); +@endcode + +If window creation fails, `NULL` will be returned, so it is necessary to check +the return value. + +The window handle is passed to all window related functions and is provided to +along with all input events, so event handlers can tell which window received +the event. + + +@subsubsection window_full_screen Full screen windows + +To create a full screen window, you need to specify which monitor the window +should use. In most cases, the user's primary monitor is a good choice. +For more information about retrieving monitors, see @ref monitor_monitors. + +@code +GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL); +@endcode + +Full screen windows cover the entire display area of a monitor, have no border +or decorations. + +Windowed mode windows can be made full screen by setting a monitor with @ref +glfwSetWindowMonitor, and full screen ones can be made windowed by unsetting it +with the same function. + +Each field of the @ref GLFWvidmode structure corresponds to a function parameter +or window hint and combine to form the _desired video mode_ for that window. +The supported video mode most closely matching the desired video mode will be +set for the chosen monitor as long as the window has input focus. For more +information about retrieving video modes, see @ref monitor_modes. + +Video mode field | Corresponds to +----------------------- | ------------------------ +GLFWvidmode.width | `width` parameter +GLFWvidmode.height | `height` parameter +GLFWvidmode.redBits | `GLFW_RED_BITS` hint +GLFWvidmode.greenBits | `GLFW_GREEN_BITS` hint +GLFWvidmode.blueBits | `GLFW_BLUE_BITS` hint +GLFWvidmode.refreshRate | `GLFW_REFRESH_RATE` hint + +Once you have a full screen window, you can change its resolution, refresh rate +and monitor with @ref glfwSetWindowMonitor. If you just need change its +resolution you can also call @ref glfwSetWindowSize. In all cases, the new +video mode will be selected the same way as the video mode chosen by @ref +glfwCreateWindow. If the window has an OpenGL or OpenGL ES context, it will be +unaffected. + +By default, the original video mode of the monitor will be restored and the +window iconified if it loses input focus, to allow the user to switch back to +the desktop. This behavior can be disabled with the `GLFW_AUTO_ICONIFY` window +hint, for example if you wish to simultaneously cover multiple windows with full +screen windows. + + +@subsubsection window_windowed_full_screen "Windowed full screen" windows + +If the closest match for the desired video mode is the current one, the video +mode will not be changed, making window creation faster and application +switching much smoother. This is sometimes called _windowed full screen_ or +_borderless full screen_ window and counts as a full screen window. To create +such a window, simply request the current video mode. + +@code +const GLFWvidmode* mode = glfwGetVideoMode(monitor); + +glfwWindowHint(GLFW_RED_BITS, mode->redBits); +glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); +glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); +glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + +GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL); +@endcode + +This also works for windowed mode windows that are made full screen. + +@code +const GLFWvidmode* mode = glfwGetVideoMode(monitor); + +glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); +@endcode + +Note that @ref glfwGetVideoMode returns the _current_ video mode of a monitor, +so if you already have a full screen window on that monitor that you want to +make windowed full screen, you need to have saved the desktop resolution before. + + +@subsection window_destruction Window destruction + +When a window is no longer needed, destroy it with @ref glfwDestroyWindow. + +@code +glfwDestroyWindow(window); +@endcode + +Window destruction always succeeds. Before the actual destruction, all +callbacks are removed so no further events will be delivered for the window. +All windows remaining when @ref glfwTerminate is called are destroyed as well. + +When a full screen window is destroyed, the original video mode of its monitor +is restored, but the gamma ramp is left untouched. + + +@subsection window_hints Window creation hints + +There are a number of hints that can be set before the creation of a window and +context. Some affect the window itself, others affect the framebuffer or +context. These hints are set to their default values each time the library is +initialized with @ref glfwInit, can be set individually with @ref glfwWindowHint +and reset all at once to their defaults with @ref glfwDefaultWindowHints. + +Note that hints need to be set _before_ the creation of the window and context +you wish to have the specified attributes. + + +@subsubsection window_hints_hard Hard and soft constraints + +Some window hints are hard constraints. These must match the available +capabilities _exactly_ for window and context creation to succeed. Hints +that are not hard constraints are matched as closely as possible, but the +resulting context and framebuffer may differ from what these hints requested. + +The following hints are always hard constraints: +- `GLFW_STEREO` +- `GLFW_DOUBLEBUFFER` +- `GLFW_CLIENT_API` +- `GLFW_CONTEXT_CREATION_API` + +The following additional hints are hard constraints when requesting an OpenGL +context, but are ignored when requesting an OpenGL ES context: +- `GLFW_OPENGL_FORWARD_COMPAT` +- `GLFW_OPENGL_PROFILE` + + +@subsubsection window_hints_wnd Window related hints + +`GLFW_RESIZABLE` specifies whether the windowed mode window will be resizable +_by the user_. The window will still be resizable using the @ref +glfwSetWindowSize function. This hint is ignored for full screen windows. + +`GLFW_VISIBLE` specifies whether the windowed mode window will be initially +visible. This hint is ignored for full screen windows. + +`GLFW_DECORATED` specifies whether the windowed mode window will have window +decorations such as a border, a close widget, etc. An undecorated window may +still allow the user to generate close events on some platforms. This hint is +ignored for full screen windows. + +`GLFW_FOCUSED` specifies whether the windowed mode window will be given input +focus when created. This hint is ignored for full screen and initially hidden +windows. + +`GLFW_AUTO_ICONIFY` specifies whether the full screen window will +automatically iconify and restore the previous video mode on input focus loss. +This hint is ignored for windowed mode windows. + +`GLFW_FLOATING` specifies whether the windowed mode window will be floating +above other regular windows, also called topmost or always-on-top. This is +intended primarily for debugging purposes and cannot be used to implement proper +full screen windows. This hint is ignored for full screen windows. + +`GLFW_MAXIMIZED` specifies whether the windowed mode window will be maximized +when created. This hint is ignored for full screen windows. + + +@subsubsection window_hints_fb Framebuffer related hints + +`GLFW_RED_BITS`, `GLFW_GREEN_BITS`, `GLFW_BLUE_BITS`, `GLFW_ALPHA_BITS`, +`GLFW_DEPTH_BITS` and `GLFW_STENCIL_BITS` specify the desired bit depths of the +various components of the default framebuffer. `GLFW_DONT_CARE` means the +application has no preference. + +`GLFW_ACCUM_RED_BITS`, `GLFW_ACCUM_GREEN_BITS`, `GLFW_ACCUM_BLUE_BITS` and +`GLFW_ACCUM_ALPHA_BITS` specify the desired bit depths of the various components +of the accumulation buffer. `GLFW_DONT_CARE` means the application has no +preference. + +@par +Accumulation buffers are a legacy OpenGL feature and should not be used in new +code. + +`GLFW_AUX_BUFFERS` specifies the desired number of auxiliary buffers. +`GLFW_DONT_CARE` means the application has no preference. + +@par +Auxiliary buffers are a legacy OpenGL feature and should not be used in new +code. + +`GLFW_STEREO` specifies whether to use stereoscopic rendering. This is a hard +constraint. + +`GLFW_SAMPLES` specifies the desired number of samples to use for multisampling. +Zero disables multisampling. `GLFW_DONT_CARE` means the application has no +preference. + +`GLFW_SRGB_CAPABLE` specifies whether the framebuffer should be sRGB capable. +If supported, a created OpenGL context will support the `GL_FRAMEBUFFER_SRGB` +enable, also called `GL_FRAMEBUFFER_SRGB_EXT`) for controlling sRGB rendering +and a created OpenGL ES context will always have sRGB rendering enabled. + +`GLFW_DOUBLEBUFFER` specifies whether the framebuffer should be double buffered. +You nearly always want to use double buffering. This is a hard constraint. + + +@subsubsection window_hints_mtr Monitor related hints + +`GLFW_REFRESH_RATE` specifies the desired refresh rate for full screen windows. +If set to `GLFW_DONT_CARE`, the highest available refresh rate will be used. +This hint is ignored for windowed mode windows. + + +@subsubsection window_hints_ctx Context related hints + +`GLFW_CLIENT_API` specifies which client API to create the context for. +Possible values are `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` and `GLFW_NO_API`. +This is a hard constraint. + +`GLFW_CONTEXT_CREATION_API` specifies which context creation API to use to +create the context. Possible values are `GLFW_NATIVE_CONTEXT_API` and +`GLFW_EGL_CONTEXT_API`. This is a hard constraint. If no client API is +requested, this hint is ignored. + +@par +__OS X:__ The EGL API is not available on this platform and requests to use it +will fail. + +@par +__Wayland, Mir:__ The EGL API _is_ the native context creation API, so this hint +will have no effect. + +@note An OpenGL extension loader library that assumes it knows which context +creation API is used on a given platform may fail if you change this hint. This +can be resolved by having it load via @ref glfwGetProcAddress, which always uses +the selected API. + +@bug On some Linux systems, creating contexts via both the native and EGL APIs +in a single process will cause the application to segfault. Stick to one API or +the other on Linux for now. + +`GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` specify the client +API version that the created context must be compatible with. The exact +behavior of these hints depend on the requested client API. + +@par +__OpenGL:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are +not hard constraints, but creation will fail if the OpenGL version of the +created context is less than the one requested. It is therefore perfectly safe +to use the default of version 1.0 for legacy code and you will still get +backwards-compatible contexts of version 3.0 and above when available. + +@par +While there is no way to ask the driver for a context of the highest supported +version, GLFW will attempt to provide this when you ask for a version 1.0 +context, which is the default for these hints. + +@par +__OpenGL ES:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are +not hard constraints, but creation will fail if the OpenGL ES version of the +created context is less than the one requested. Additionally, OpenGL ES 1.x +cannot be returned if 2.0 or later was requested, and vice versa. This is +because OpenGL ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not +backward compatible with 1.x. + +`GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be +forward-compatible, i.e. one where all functionality deprecated in the requested +version of OpenGL is removed. This must only be used if the requested OpenGL +version is 3.0 or above. If OpenGL ES is requested, this hint is ignored. + +@par +Forward-compatibility is described in detail in the +[OpenGL Reference Manual](https://www.opengl.org/registry/). + +`GLFW_OPENGL_DEBUG_CONTEXT` specifies whether to create a debug OpenGL context, +which may have additional error and performance issue reporting functionality. +If OpenGL ES is requested, this hint is ignored. + +`GLFW_OPENGL_PROFILE` specifies which OpenGL profile to create the context for. +Possible values are one of `GLFW_OPENGL_CORE_PROFILE` or +`GLFW_OPENGL_COMPAT_PROFILE`, or `GLFW_OPENGL_ANY_PROFILE` to not request +a specific profile. If requesting an OpenGL version below 3.2, +`GLFW_OPENGL_ANY_PROFILE` must be used. If OpenGL ES is requested, +this hint is ignored. + +@par +OpenGL profiles are described in detail in the +[OpenGL Reference Manual](https://www.opengl.org/registry/). + +`GLFW_CONTEXT_ROBUSTNESS` specifies the robustness strategy to be used by the +context. This can be one of `GLFW_NO_RESET_NOTIFICATION` or +`GLFW_LOSE_CONTEXT_ON_RESET`, or `GLFW_NO_ROBUSTNESS` to not request +a robustness strategy. + +`GLFW_CONTEXT_RELEASE_BEHAVIOR` specifies the release behavior to be +used by the context. Possible values are one of `GLFW_ANY_RELEASE_BEHAVIOR`, +`GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`. If the +behavior is `GLFW_ANY_RELEASE_BEHAVIOR`, the default behavior of the context +creation API will be used. If the behavior is `GLFW_RELEASE_BEHAVIOR_FLUSH`, +the pipeline will be flushed whenever the context is released from being the +current one. If the behavior is `GLFW_RELEASE_BEHAVIOR_NONE`, the pipeline will +not be flushed on release. + +@par +Context release behaviors are described in detail by the +[GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt) +extension. + +`GLFW_CONTEXT_NO_ERROR` specifies whether errors should be generated by the +context. If enabled, situations that would have generated errors instead cause +undefined behavior. + +@par +The no error mode for OpenGL and OpenGL ES is described in detail by the +[GL_KHR_no_error](https://www.opengl.org/registry/specs/KHR/no_error.txt) +extension. + +@note This hint is experimental in its current state. There are currently +(October 2015) no corresponding WGL or GLX extensions. That makes this hint +a [hard constraint](@ref window_hints_hard) for those backends, as creation will +fail if unsupported context flags are requested. Once the extensions are +available, they will be required and creation of `GL_KHR_no_error` contexts may +fail on early drivers where this flag is supported without those extensions +being listed. + + +@subsubsection window_hints_values Supported and default values + +Window hint | Default value | Supported values +------------------------------- | --------------------------- | ---------------- +`GLFW_RESIZABLE` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_VISIBLE` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_DECORATED` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_FOCUSED` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_AUTO_ICONIFY` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_FLOATING` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_MAXIMIZED` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_GREEN_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ALPHA_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_DEPTH_BITS` | 24 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_STENCIL_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_RED_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_GREEN_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_BLUE_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_ACCUM_ALPHA_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_AUX_BUFFERS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_SAMPLES` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_REFRESH_RATE` | `GLFW_DONT_CARE` | 0 to `INT_MAX` or `GLFW_DONT_CARE` +`GLFW_STEREO` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_SRGB_CAPABLE` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_DOUBLEBUFFER` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_CLIENT_API` | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API` +`GLFW_CONTEXT_CREATION_API` | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API` or `GLFW_EGL_CONTEXT_API` +`GLFW_CONTEXT_VERSION_MAJOR` | 1 | Any valid major version number of the chosen client API +`GLFW_CONTEXT_VERSION_MINOR` | 0 | Any valid minor version number of the chosen client API +`GLFW_CONTEXT_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` +`GLFW_CONTEXT_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` +`GLFW_OPENGL_FORWARD_COMPAT` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_OPENGL_DEBUG_CONTEXT` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +`GLFW_OPENGL_PROFILE` | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` + + +@section window_events Window event processing + +See @ref events. + + +@section window_properties Window properties and events + +@subsection window_userptr User pointer + +Each window has a user pointer that can be set with @ref +glfwSetWindowUserPointer and fetched with @ref glfwGetWindowUserPointer. This +can be used for any purpose you need and will not be modified by GLFW throughout +the life-time of the window. + +The initial value of the pointer is `NULL`. + + +@subsection window_close Window closing and close flag + +When the user attempts to close the window, for example by clicking the close +widget or using a key chord like Alt+F4, the _close flag_ of the window is set. +The window is however not actually destroyed and, unless you watch for this +state change, nothing further happens. + +The current state of the close flag is returned by @ref glfwWindowShouldClose +and can be set or cleared directly with @ref glfwSetWindowShouldClose. A common +pattern is to use the close flag as a main loop condition. + +@code +while (!glfwWindowShouldClose(window)) +{ + render(window); + + glfwSwapBuffers(window); + glfwPollEvents(); +} +@endcode + +If you wish to be notified when the user attempts to close a window, set a close +callback. + +@code +glfwSetWindowCloseCallback(window, window_close_callback); +@endcode + +The callback function is called directly _after_ the close flag has been set. +It can be used for example to filter close requests and clear the close flag +again unless certain conditions are met. + +@code +void window_close_callback(GLFWwindow* window) +{ + if (!time_to_close) + glfwSetWindowShouldClose(window, GLFW_FALSE); +} +@endcode + + +@subsection window_size Window size + +The size of a window can be changed with @ref glfwSetWindowSize. For windowed +mode windows, this sets the size, in +[screen coordinates](@ref coordinate_systems) of the _client area_ or _content +area_ of the window. The window system may impose limits on window size. + +@code +glfwSetWindowSize(window, 640, 480); +@endcode + +For full screen windows, the specified size becomes the new resolution of the +window's desired video mode. The video mode most closely matching the new +desired video mode is set immediately. The window is resized to fit the +resolution of the set video mode. + +If you wish to be notified when a window is resized, whether by the user or +the system, set a size callback. + +@code +glfwSetWindowSizeCallback(window, window_size_callback); +@endcode + +The callback function receives the new size, in screen coordinates, of the +client area of the window when it is resized. + +@code +void window_size_callback(GLFWwindow* window, int width, int height) +{ +} +@endcode + +There is also @ref glfwGetWindowSize for directly retrieving the current size of +a window. + +@code +int width, height; +glfwGetWindowSize(window, &width, &height); +@endcode + +@note Do not pass the window size to `glViewport` or other pixel-based OpenGL +calls. The window size is in screen coordinates, not pixels. Use the +[framebuffer size](@ref window_fbsize), which is in pixels, for pixel-based +calls. + +The above functions work with the size of the client area, but decorated windows +typically have title bars and window frames around this rectangle. You can +retrieve the extents of these with @ref glfwGetWindowFrameSize. + +@code +int left, top, right, bottom; +glfwGetWindowFrameSize(window, &left, &top, &right, &bottom); +@endcode + +The returned values are the distances, in screen coordinates, from the edges of +the client area to the corresponding edges of the full window. As they are +distances and not coordinates, they are always zero or positive. + + +@subsection window_fbsize Framebuffer size + +While the size of a window is measured in screen coordinates, OpenGL works with +pixels. The size you pass into `glViewport`, for example, should be in pixels. +On some machines screen coordinates and pixels are the same, but on others they +will not be. There is a second set of functions to retrieve the size, in +pixels, of the framebuffer of a window. + +If you wish to be notified when the framebuffer of a window is resized, whether +by the user or the system, set a size callback. + +@code +glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); +@endcode + +The callback function receives the new size of the framebuffer when it is +resized, which can for example be used to update the OpenGL viewport. + +@code +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} +@endcode + +There is also @ref glfwGetFramebufferSize for directly retrieving the current +size of the framebuffer of a window. + +@code +int width, height; +glfwGetFramebufferSize(window, &width, &height); +glViewport(0, 0, width, height); +@endcode + +The size of a framebuffer may change independently of the size of a window, for +example if the window is dragged between a regular monitor and a high-DPI one. + + +@subsection window_sizelimits Window size limits + +The minimum and maximum size of the client area of a windowed mode window can be +enforced with @ref glfwSetWindowSizeLimits. The user may resize the window to +any size and aspect ratio within the specified limits, unless the aspect ratio +is also set. + +@code +glfwSetWindowSizeLimits(window, 200, 200, 400, 400); +@endcode + +To specify only a minimum size or only a maximum one, set the other pair to +`GLFW_DONT_CARE`. + +@code +glfwSetWindowSizeLimits(window, 640, 480, GLFW_DONT_CARE, GLFW_DONT_CARE); +@endcode + +To disable size limits for a window, set them all to `GLFW_DONT_CARE`. + +The aspect ratio of the client area of a windowed mode window can be enforced +with @ref glfwSetWindowAspectRatio. The user may resize the window freely +unless size limits are also set, but the size will be constrained to maintain +the aspect ratio. + +@code +glfwSetWindowAspectRatio(window, 16, 9); +@endcode + +The aspect ratio is specified as a numerator and denominator, corresponding to +the width and height, respectively. If you want a window to maintain its +current aspect ratio, simply use its current size as the ratio. + +@code +int width, height; +glfwGetWindowSize(window, &width, &height); +glfwSetWindowAspectRatio(window, width, height); +@endcode + +To disable the aspect ratio limit for a window, set both terms to +`GLFW_DONT_CARE`. + +You can have both size limits and aspect ratio set for a window, but the results +are undefined if they conflict. + + +@subsection window_pos Window position + +The position of a windowed-mode window can be changed with @ref +glfwSetWindowPos. This moves the window so that the upper-left corner of its +client area has the specified [screen coordinates](@ref coordinate_systems). +The window system may put limitations on window placement. + +@code +glfwSetWindowPos(window, 100, 100); +@endcode + +If you wish to be notified when a window is moved, whether by the user, system +or your own code, set a position callback. + +@code +glfwSetWindowPosCallback(window, window_pos_callback); +@endcode + +The callback function receives the new position of the upper-left corner of the +client area when the window is moved. + +@code +void window_pos_callback(GLFWwindow* window, int xpos, int ypos) +{ +} +@endcode + +There is also @ref glfwGetWindowPos for directly retrieving the current position +of the client area of the window. + +@code +int xpos, ypos; +glfwGetWindowPos(window, &xpos, &ypos); +@endcode + + +@subsection window_title Window title + +All GLFW windows have a title, although undecorated or full screen windows may +not display it or only display it in a task bar or similar interface. You can +set a UTF-8 encoded window title with @ref glfwSetWindowTitle. + +@code +glfwSetWindowTitle(window, "My Window"); +@endcode + +The specified string is copied before the function returns, so there is no need +to keep it around. + +As long as your source file is encoded as UTF-8, you can use any Unicode +characters directly in the source. + +@code +glfwSetWindowTitle(window, "カウボーイビバップ"); +@endcode + +If you are using C++11 or C11, you can use a UTF-8 string literal. + +@code +glfwSetWindowTitle(window, u8"This is always a UTF-8 string"); +@endcode + + +@subsection window_icon Window icon + +Decorated windows have icons on some platforms. You can set this icon by +specifying a list of candidate images with @ref glfwSetWindowIcon. + +@code +GLFWimage images[2]; +images[0] = load_icon("my_icon.png"); +images[1] = load_icon("my_icon_small.png"); + +glfwSetWindowIcon(window, 2, images); +@endcode + +To revert to the default window icon, pass in an empty image array. + +@code +glfwSetWindowIcon(window, 0, NULL); +@endcode + + +@subsection window_monitor Window monitor + +Full screen windows are associated with a specific monitor. You can get the +handle for this monitor with @ref glfwGetWindowMonitor. + +@code +GLFWmonitor* monitor = glfwGetWindowMonitor(window); +@endcode + +This monitor handle is one of those returned by @ref glfwGetMonitors. + +For windowed mode windows, this function returns `NULL`. This is how to tell +full screen windows from windowed mode windows. + +You can move windows between monitors or between full screen and windowed mode +with @ref glfwSetWindowMonitor. When making a window full screen on the same or +on a different monitor, specify the desired monitor, resolution and refresh +rate. The position arguments are ignored. + +@code +const GLFWvidmode* mode = glfwGetVideoMode(monitor); + +glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); +@endcode + +When making the window windowed, specify the desired position and size. The +refresh rate argument is ignored. + +@code +glfwSetWindowMonitor(window, NULL, xpos, ypos, width, height, 0); +@endcode + +This restores any previous window settings such as whether it is decorated, +floating, resizable, has size or aspect ratio limits, etc.. To restore a window +that was originally windowed to its original size and position, save these +before making it full screen and then pass them in as above. + + +@subsection window_iconify Window iconification + +Windows can be iconified (i.e. minimized) with @ref glfwIconifyWindow. + +@code +glfwIconifyWindow(window); +@endcode + +When a full screen window is iconified, the original video mode of its monitor +is restored until the user or application restores the window. + +Iconified windows can be restored with @ref glfwRestoreWindow. + +@code +glfwRestoreWindow(window); +@endcode + +When a full screen window is restored, the desired video mode is restored to its +monitor as well. + +If you wish to be notified when a window is iconified or restored, whether by +the user, system or your own code, set a iconify callback. + +@code +glfwSetWindowIconifyCallback(window, window_iconify_callback); +@endcode + +The callback function receives changes in the iconification state of the window. + +@code +void window_iconify_callback(GLFWwindow* window, int iconified) +{ + if (iconified) + { + // The window was iconified + } + else + { + // The window was restored + } +} +@endcode + +You can also get the current iconification state with @ref glfwGetWindowAttrib. + +@code +int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED); +@endcode + + +@subsection window_hide Window visibility + +Windowed mode windows can be hidden with @ref glfwHideWindow. + +@code +glfwHideWindow(window); +@endcode + +This makes the window completely invisible to the user, including removing it +from the task bar, dock or window list. Full screen windows cannot be hidden +and calling @ref glfwHideWindow on a full screen window does nothing. + +Hidden windows can be shown with @ref glfwShowWindow. + +@code +glfwShowWindow(window); +@endcode + +Windowed mode windows can be created initially hidden with the `GLFW_VISIBLE` +[window hint](@ref window_hints_wnd). Windows created hidden are completely +invisible to the user until shown. This can be useful if you need to set up +your window further before showing it, for example moving it to a specific +location. + +You can also get the current visibility state with @ref glfwGetWindowAttrib. + +@code +int visible = glfwGetWindowAttrib(window, GLFW_VISIBLE); +@endcode + + +@subsection window_focus Window input focus + +Windows can be given input focus and brought to the front with @ref +glfwFocusWindow. + +@code +glfwFocusWindow(window); +@endcode + +If you wish to be notified when a window gains or loses input focus, whether by +the user, system or your own code, set a focus callback. + +@code +glfwSetWindowFocusCallback(window, window_focus_callback); +@endcode + +The callback function receives changes in the input focus state of the window. + +@code +void window_focus_callback(GLFWwindow* window, int focused) +{ + if (focused) + { + // The window gained input focus + } + else + { + // The window lost input focus + } +} +@endcode + +You can also get the current input focus state with @ref glfwGetWindowAttrib. + +@code +int focused = glfwGetWindowAttrib(window, GLFW_FOCUSED); +@endcode + + +@subsection window_refresh Window damage and refresh + +If you wish to be notified when the contents of a window is damaged and needs +to be refreshed, set a window refresh callback. + +@code +glfwSetWindowRefreshCallback(m_handle, window_refresh_callback); +@endcode + +The callback function is called when the contents of the window needs to be +refreshed. + +@code +void window_refresh_callback(GLFWwindow* window) +{ + draw_editor_ui(window); + glfwSwapBuffers(window); +} +@endcode + +@note On compositing window systems such as Aero, Compiz or Aqua, where the +window contents are saved off-screen, this callback might only be called when +the window or framebuffer is resized. + + +@subsection window_attribs Window attributes + +Windows have a number of attributes that can be returned using @ref +glfwGetWindowAttrib. Some reflect state that may change during the lifetime of +the window, while others reflect the corresponding hints and are fixed at the +time of creation. Some are related to the actual window and others to its +context. + +@code +if (glfwGetWindowAttrib(window, GLFW_FOCUSED)) +{ + // window has input focus +} +@endcode + + +@subsubsection window_attribs_wnd Window related attributes + +`GLFW_FOCUSED` indicates whether the specified window has input focus. Initial +input focus is controlled by the [window hint](@ref window_hints_wnd) with the +same name. + +`GLFW_ICONIFIED` indicates whether the specified window is iconified, whether by +the user or with @ref glfwIconifyWindow. + +`GLFW_MAXIMIZED` indicates whether the specified window is maximized, whether by +the user or with @ref glfwMaximizeWindow. + +`GLFW_VISIBLE` indicates whether the specified window is visible. Window +visibility can be controlled with @ref glfwShowWindow and @ref glfwHideWindow +and initial visibility is controlled by the [window hint](@ref window_hints_wnd) +with the same name. + +`GLFW_RESIZABLE` indicates whether the specified window is resizable _by the +user_. This is set on creation with the [window hint](@ref window_hints_wnd) + with the same name. + +`GLFW_DECORATED` indicates whether the specified window has decorations such as +a border, a close widget, etc. This is set on creation with the +[window hint](@ref window_hints_wnd) with the same name. + +`GLFW_FLOATING` indicates whether the specified window is floating, also called +topmost or always-on-top. This is controlled by the +[window hint](@ref window_hints_wnd) with the same name. + + +@subsubsection window_attribs_ctx Context related attributes + +`GLFW_CLIENT_API` indicates the client API provided by the window's context; +either `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`. + +`GLFW_CONTEXT_CREATION_API` indicates the context creation API used to create +the window's context; either `GLFW_NATIVE_CONTEXT_API` or +`GLFW_EGL_CONTEXT_API`. + +`GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and +`GLFW_CONTEXT_REVISION` indicate the client API version of the window's context. + +`GLFW_OPENGL_FORWARD_COMPAT` is `GLFW_TRUE` if the window's context is an OpenGL +forward-compatible one, or `GLFW_FALSE` otherwise. + +`GLFW_OPENGL_DEBUG_CONTEXT` is `GLFW_TRUE` if the window's context is an OpenGL +debug context, or `GLFW_FALSE` otherwise. + +`GLFW_OPENGL_PROFILE` indicates the OpenGL profile used by the context. This is +`GLFW_OPENGL_CORE_PROFILE` or `GLFW_OPENGL_COMPAT_PROFILE` if the context uses +a known profile, or `GLFW_OPENGL_ANY_PROFILE` if the OpenGL profile is unknown +or the context is an OpenGL ES context. Note that the returned profile may not +match the profile bits of the context flags, as GLFW will try other means of +detecting the profile when no bits are set. + +`GLFW_CONTEXT_ROBUSTNESS` indicates the robustness strategy used by the context. +This is `GLFW_LOSE_CONTEXT_ON_RESET` or `GLFW_NO_RESET_NOTIFICATION` if the +window's context supports robustness, or `GLFW_NO_ROBUSTNESS` otherwise. + + +@subsubsection window_attribs_fb Framebuffer related attributes + +GLFW does not expose attributes of the default framebuffer (i.e. the framebuffer +attached to the window) as these can be queried directly with either OpenGL, +OpenGL ES or Vulkan. + +If you are using version 3.0 or later of OpenGL or OpenGL ES, the +`glGetFramebufferAttachmentParameteriv` function can be used to retrieve the +number of bits for the red, green, blue, alpha, depth and stencil buffer +channels. Otherwise, the `glGetIntegerv` function can be used. + +The number of MSAA samples are always retrieved with `glGetIntegerv`. For +contexts supporting framebuffer objects, the number of samples of the currently +bound framebuffer is returned. + +Attribute | glGetIntegerv | glGetFramebufferAttachmentParameteriv +------------ | ----------------- | ------------------------------------- +Red bits | `GL_RED_BITS` | `GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE` +Green bits | `GL_GREEN_BITS` | `GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE` +Blue bits | `GL_BLUE_BITS` | `GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE` +Alpha bits | `GL_ALPHA_BITS` | `GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE` +Depth bits | `GL_DEPTH_BITS` | `GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE` +Stencil bits | `GL_STENCIL_BITS` | `GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE` +MSAA samples | `GL_SAMPLES` | _Not provided by this function_ + +When calling `glGetFramebufferAttachmentParameteriv`, the red, green, blue and +alpha sizes are queried from the `GL_BACK_LEFT`, while the depth and stencil +sizes are queried from the `GL_DEPTH` and `GL_STENCIL` attachments, +respectively. + + +@section buffer_swap Buffer swapping + +GLFW windows are by default double buffered. That means that you have two +rendering buffers; a front buffer and a back buffer. The front buffer is +the one being displayed and the back buffer the one you render to. + +When the entire frame has been rendered, it is time to swap the back and the +front buffers in order to display what has been rendered and begin rendering +a new frame. This is done with @ref glfwSwapBuffers. + +@code +glfwSwapBuffers(window); +@endcode + +Sometimes it can be useful to select when the buffer swap will occur. With the +function @ref glfwSwapInterval it is possible to select the minimum number of +monitor refreshes the driver wait should from the time @ref glfwSwapBuffers was +called before swapping the buffers: + +@code +glfwSwapInterval(1); +@endcode + +If the interval is zero, the swap will take place immediately when @ref +glfwSwapBuffers is called without waiting for a refresh. Otherwise at least +interval retraces will pass between each buffer swap. Using a swap interval of +zero can be useful for benchmarking purposes, when it is not desirable to +measure the time it takes to wait for the vertical retrace. However, a swap +interval of one lets you avoid tearing. + +Note that this may not work on all machines, as some drivers have +user-controlled settings that override any swap interval the application +requests. + +*/ diff --git a/extern/glfw-3.2.1/examples/CMakeLists.txt b/extern/glfw-3.2.1/examples/CMakeLists.txt new file mode 100644 index 0000000..138a781 --- /dev/null +++ b/extern/glfw-3.2.1/examples/CMakeLists.txt @@ -0,0 +1,67 @@ + +link_libraries(glfw) + +include_directories(${glfw_INCLUDE_DIRS}) + +if (BUILD_SHARED_LIBS) + link_libraries("${MATH_LIBRARY}") +endif() + +if (MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories("${GLFW_SOURCE_DIR}/deps") + +if (WIN32) + set(ICON glfw.rc) +elseif (APPLE) + set(ICON glfw.icns) + set_source_files_properties(glfw.icns PROPERTIES + MAXOSX_PACKAGE_LOCATION "Resources") +endif() + +set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h" + "${GLFW_SOURCE_DIR}/deps/glad.c") +set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" + "${GLFW_SOURCE_DIR}/deps/getopt.c") +set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" + "${GLFW_SOURCE_DIR}/deps/tinycthread.c") + +add_executable(boing WIN32 MACOSX_BUNDLE boing.c ${ICON} ${GLAD}) +add_executable(gears WIN32 MACOSX_BUNDLE gears.c ${ICON} ${GLAD}) +add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD}) +add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD}) +add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD}) +add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD}) +add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD}) + +target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") + +set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave) + +set_target_properties(${WINDOWS_BINARIES} PROPERTIES FOLDER "GLFW3/Examples") + +if (MSVC) + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing") + set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") + set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap") + set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles") + set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple") + set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView") + set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") + + set_target_properties(${WINDOWS_BINARIES} PROPERTIES + RESOURCE glfw.icns + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL} + MACOSX_BUNDLE_ICON_FILE glfw.icns + MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in") +endif() + diff --git a/extern/glfw-3.2.1/examples/boing.c b/extern/glfw-3.2.1/examples/boing.c new file mode 100644 index 0000000..45c867f --- /dev/null +++ b/extern/glfw-3.2.1/examples/boing.c @@ -0,0 +1,678 @@ +/***************************************************************************** + * Title: GLBoing + * Desc: Tribute to Amiga Boing. + * Author: Jim Brooks + * Original Amiga authors were R.J. Mical and Dale Luck. + * GLFW conversion by Marcus Geelnard + * Notes: - 360' = 2*PI [radian] + * + * - Distances between objects are created by doing a relative + * Z translations. + * + * - Although OpenGL enticingly supports alpha-blending, + * the shadow of the original Boing didn't affect the color + * of the grid. + * + * - [Marcus] Changed timing scheme from interval driven to frame- + * time based animation steps (which results in much smoother + * movement) + * + * History of Amiga Boing: + * + * Boing was demonstrated on the prototype Amiga (codenamed "Lorraine") in + * 1985. According to legend, it was written ad-hoc in one night by + * R. J. Mical and Dale Luck. Because the bouncing ball animation was so fast + * and smooth, attendees did not believe the Amiga prototype was really doing + * the rendering. Suspecting a trick, they began looking around the booth for + * a hidden computer or VCR. + *****************************************************************************/ + +#if defined(_MSC_VER) + // Make MS math.h define M_PI + #define _USE_MATH_DEFINES +#endif + +#include +#include +#include + +#include +#include + +#include + + +/***************************************************************************** + * Various declarations and macros + *****************************************************************************/ + +/* Prototypes */ +void init( void ); +void display( void ); +void reshape( GLFWwindow* window, int w, int h ); +void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ); +void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ); +void cursor_position_callback( GLFWwindow* window, double x, double y ); +void DrawBoingBall( void ); +void BounceBall( double dt ); +void DrawBoingBallBand( GLfloat long_lo, GLfloat long_hi ); +void DrawGrid( void ); + +#define RADIUS 70.f +#define STEP_LONGITUDE 22.5f /* 22.5 makes 8 bands like original Boing */ +#define STEP_LATITUDE 22.5f + +#define DIST_BALL (RADIUS * 2.f + RADIUS * 0.1f) + +#define VIEW_SCENE_DIST (DIST_BALL * 3.f + 200.f)/* distance from viewer to middle of boing area */ +#define GRID_SIZE (RADIUS * 4.5f) /* length (width) of grid */ +#define BOUNCE_HEIGHT (RADIUS * 2.1f) +#define BOUNCE_WIDTH (RADIUS * 2.1f) + +#define SHADOW_OFFSET_X -20.f +#define SHADOW_OFFSET_Y 10.f +#define SHADOW_OFFSET_Z 0.f + +#define WALL_L_OFFSET 0.f +#define WALL_R_OFFSET 5.f + +/* Animation speed (50.0 mimics the original GLUT demo speed) */ +#define ANIMATION_SPEED 50.f + +/* Maximum allowed delta time per physics iteration */ +#define MAX_DELTA_T 0.02f + +/* Draw ball, or its shadow */ +typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM; + +/* Vertex type */ +typedef struct {float x; float y; float z;} vertex_t; + +/* Global vars */ +int windowed_xpos, windowed_ypos, windowed_width, windowed_height; +int width, height; +GLfloat deg_rot_y = 0.f; +GLfloat deg_rot_y_inc = 2.f; +int override_pos = GLFW_FALSE; +GLfloat cursor_x = 0.f; +GLfloat cursor_y = 0.f; +GLfloat ball_x = -RADIUS; +GLfloat ball_y = -RADIUS; +GLfloat ball_x_inc = 1.f; +GLfloat ball_y_inc = 2.f; +DRAW_BALL_ENUM drawBallHow; +double t; +double t_old = 0.f; +double dt; + +/* Random number generator */ +#ifndef RAND_MAX + #define RAND_MAX 4095 +#endif + + +/***************************************************************************** + * Truncate a degree. + *****************************************************************************/ +GLfloat TruncateDeg( GLfloat deg ) +{ + if ( deg >= 360.f ) + return (deg - 360.f); + else + return deg; +} + +/***************************************************************************** + * Convert a degree (360-based) into a radian. + * 360' = 2 * PI + *****************************************************************************/ +double deg2rad( double deg ) +{ + return deg / 360 * (2 * M_PI); +} + +/***************************************************************************** + * 360' sin(). + *****************************************************************************/ +double sin_deg( double deg ) +{ + return sin( deg2rad( deg ) ); +} + +/***************************************************************************** + * 360' cos(). + *****************************************************************************/ +double cos_deg( double deg ) +{ + return cos( deg2rad( deg ) ); +} + +/***************************************************************************** + * Compute a cross product (for a normal vector). + * + * c = a x b + *****************************************************************************/ +void CrossProduct( vertex_t a, vertex_t b, vertex_t c, vertex_t *n ) +{ + GLfloat u1, u2, u3; + GLfloat v1, v2, v3; + + u1 = b.x - a.x; + u2 = b.y - a.y; + u3 = b.y - a.z; + + v1 = c.x - a.x; + v2 = c.y - a.y; + v3 = c.z - a.z; + + n->x = u2 * v3 - v2 * v3; + n->y = u3 * v1 - v3 * u1; + n->z = u1 * v2 - v1 * u2; +} + + +#define BOING_DEBUG 0 + + +/***************************************************************************** + * init() + *****************************************************************************/ +void init( void ) +{ + /* + * Clear background. + */ + glClearColor( 0.55f, 0.55f, 0.55f, 0.f ); + + glShadeModel( GL_FLAT ); +} + + +/***************************************************************************** + * display() + *****************************************************************************/ +void display(void) +{ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glPushMatrix(); + + drawBallHow = DRAW_BALL_SHADOW; + DrawBoingBall(); + + DrawGrid(); + + drawBallHow = DRAW_BALL; + DrawBoingBall(); + + glPopMatrix(); + glFlush(); +} + + +/***************************************************************************** + * reshape() + *****************************************************************************/ +void reshape( GLFWwindow* window, int w, int h ) +{ + mat4x4 projection, view; + + glViewport( 0, 0, (GLsizei)w, (GLsizei)h ); + + glMatrixMode( GL_PROJECTION ); + mat4x4_perspective( projection, + 2.f * (float) atan2( RADIUS, 200.f ), + (float)w / (float)h, + 1.f, VIEW_SCENE_DIST ); + glLoadMatrixf((const GLfloat*) projection); + + glMatrixMode( GL_MODELVIEW ); + { + vec3 eye = { 0.f, 0.f, VIEW_SCENE_DIST }; + vec3 center = { 0.f, 0.f, 0.f }; + vec3 up = { 0.f, -1.f, 0.f }; + mat4x4_look_at( view, eye, center, up ); + } + glLoadMatrixf((const GLfloat*) view); +} + +void key_callback( GLFWwindow* window, int key, int scancode, int action, int mods ) +{ + if (action != GLFW_PRESS) + return; + + if (key == GLFW_KEY_ESCAPE && mods == 0) + glfwSetWindowShouldClose(window, GLFW_TRUE); + if ((key == GLFW_KEY_ENTER && mods == GLFW_MOD_ALT) || + (key == GLFW_KEY_F11 && mods == GLFW_MOD_ALT)) + { + if (glfwGetWindowMonitor(window)) + { + glfwSetWindowMonitor(window, NULL, + windowed_xpos, windowed_ypos, + windowed_width, windowed_height, 0); + } + else + { + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos); + glfwGetWindowSize(window, &windowed_width, &windowed_height); + glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); + } + } + } +} + +static void set_ball_pos ( GLfloat x, GLfloat y ) +{ + ball_x = (width / 2) - x; + ball_y = y - (height / 2); +} + +void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) +{ + if (button != GLFW_MOUSE_BUTTON_LEFT) + return; + + if (action == GLFW_PRESS) + { + override_pos = GLFW_TRUE; + set_ball_pos(cursor_x, cursor_y); + } + else + { + override_pos = GLFW_FALSE; + } +} + +void cursor_position_callback( GLFWwindow* window, double x, double y ) +{ + cursor_x = (float) x; + cursor_y = (float) y; + + if ( override_pos ) + set_ball_pos(cursor_x, cursor_y); +} + +/***************************************************************************** + * Draw the Boing ball. + * + * The Boing ball is sphere in which each facet is a rectangle. + * Facet colors alternate between red and white. + * The ball is built by stacking latitudinal circles. Each circle is composed + * of a widely-separated set of points, so that each facet is noticably large. + *****************************************************************************/ +void DrawBoingBall( void ) +{ + GLfloat lon_deg; /* degree of longitude */ + double dt_total, dt2; + + glPushMatrix(); + glMatrixMode( GL_MODELVIEW ); + + /* + * Another relative Z translation to separate objects. + */ + glTranslatef( 0.0, 0.0, DIST_BALL ); + + /* Update ball position and rotation (iterate if necessary) */ + dt_total = dt; + while( dt_total > 0.0 ) + { + dt2 = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; + dt_total -= dt2; + BounceBall( dt2 ); + deg_rot_y = TruncateDeg( deg_rot_y + deg_rot_y_inc*((float)dt2*ANIMATION_SPEED) ); + } + + /* Set ball position */ + glTranslatef( ball_x, ball_y, 0.0 ); + + /* + * Offset the shadow. + */ + if ( drawBallHow == DRAW_BALL_SHADOW ) + { + glTranslatef( SHADOW_OFFSET_X, + SHADOW_OFFSET_Y, + SHADOW_OFFSET_Z ); + } + + /* + * Tilt the ball. + */ + glRotatef( -20.0, 0.0, 0.0, 1.0 ); + + /* + * Continually rotate ball around Y axis. + */ + glRotatef( deg_rot_y, 0.0, 1.0, 0.0 ); + + /* + * Set OpenGL state for Boing ball. + */ + glCullFace( GL_FRONT ); + glEnable( GL_CULL_FACE ); + glEnable( GL_NORMALIZE ); + + /* + * Build a faceted latitude slice of the Boing ball, + * stepping same-sized vertical bands of the sphere. + */ + for ( lon_deg = 0; + lon_deg < 180; + lon_deg += STEP_LONGITUDE ) + { + /* + * Draw a latitude circle at this longitude. + */ + DrawBoingBallBand( lon_deg, + lon_deg + STEP_LONGITUDE ); + } + + glPopMatrix(); + + return; +} + + +/***************************************************************************** + * Bounce the ball. + *****************************************************************************/ +void BounceBall( double delta_t ) +{ + GLfloat sign; + GLfloat deg; + + if ( override_pos ) + return; + + /* Bounce on walls */ + if ( ball_x > (BOUNCE_WIDTH/2 + WALL_R_OFFSET ) ) + { + ball_x_inc = -0.5f - 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; + deg_rot_y_inc = -deg_rot_y_inc; + } + if ( ball_x < -(BOUNCE_HEIGHT/2 + WALL_L_OFFSET) ) + { + ball_x_inc = 0.5f + 0.75f * (GLfloat)rand() / (GLfloat)RAND_MAX; + deg_rot_y_inc = -deg_rot_y_inc; + } + + /* Bounce on floor / roof */ + if ( ball_y > BOUNCE_HEIGHT/2 ) + { + ball_y_inc = -0.75f - 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; + } + if ( ball_y < -BOUNCE_HEIGHT/2*0.85 ) + { + ball_y_inc = 0.75f + 1.f * (GLfloat)rand() / (GLfloat)RAND_MAX; + } + + /* Update ball position */ + ball_x += ball_x_inc * ((float)delta_t*ANIMATION_SPEED); + ball_y += ball_y_inc * ((float)delta_t*ANIMATION_SPEED); + + /* + * Simulate the effects of gravity on Y movement. + */ + if ( ball_y_inc < 0 ) sign = -1.0; else sign = 1.0; + + deg = (ball_y + BOUNCE_HEIGHT/2) * 90 / BOUNCE_HEIGHT; + if ( deg > 80 ) deg = 80; + if ( deg < 10 ) deg = 10; + + ball_y_inc = sign * 4.f * (float) sin_deg( deg ); +} + + +/***************************************************************************** + * Draw a faceted latitude band of the Boing ball. + * + * Parms: long_lo, long_hi + * Low and high longitudes of slice, resp. + *****************************************************************************/ +void DrawBoingBallBand( GLfloat long_lo, + GLfloat long_hi ) +{ + vertex_t vert_ne; /* "ne" means south-east, so on */ + vertex_t vert_nw; + vertex_t vert_sw; + vertex_t vert_se; + vertex_t vert_norm; + GLfloat lat_deg; + static int colorToggle = 0; + + /* + * Iterate thru the points of a latitude circle. + * A latitude circle is a 2D set of X,Z points. + */ + for ( lat_deg = 0; + lat_deg <= (360 - STEP_LATITUDE); + lat_deg += STEP_LATITUDE ) + { + /* + * Color this polygon with red or white. + */ + if ( colorToggle ) + glColor3f( 0.8f, 0.1f, 0.1f ); + else + glColor3f( 0.95f, 0.95f, 0.95f ); +#if 0 + if ( lat_deg >= 180 ) + if ( colorToggle ) + glColor3f( 0.1f, 0.8f, 0.1f ); + else + glColor3f( 0.5f, 0.5f, 0.95f ); +#endif + colorToggle = ! colorToggle; + + /* + * Change color if drawing shadow. + */ + if ( drawBallHow == DRAW_BALL_SHADOW ) + glColor3f( 0.35f, 0.35f, 0.35f ); + + /* + * Assign each Y. + */ + vert_ne.y = vert_nw.y = (float) cos_deg(long_hi) * RADIUS; + vert_sw.y = vert_se.y = (float) cos_deg(long_lo) * RADIUS; + + /* + * Assign each X,Z with sin,cos values scaled by latitude radius indexed by longitude. + * Eg, long=0 and long=180 are at the poles, so zero scale is sin(longitude), + * while long=90 (sin(90)=1) is at equator. + */ + vert_ne.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_se.x = (float) cos_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); + vert_nw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_sw.x = (float) cos_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); + + vert_ne.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_se.z = (float) sin_deg( lat_deg ) * (RADIUS * (float) sin_deg( long_lo )); + vert_nw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo + STEP_LONGITUDE )); + vert_sw.z = (float) sin_deg( lat_deg + STEP_LATITUDE ) * (RADIUS * (float) sin_deg( long_lo )); + + /* + * Draw the facet. + */ + glBegin( GL_POLYGON ); + + CrossProduct( vert_ne, vert_nw, vert_sw, &vert_norm ); + glNormal3f( vert_norm.x, vert_norm.y, vert_norm.z ); + + glVertex3f( vert_ne.x, vert_ne.y, vert_ne.z ); + glVertex3f( vert_nw.x, vert_nw.y, vert_nw.z ); + glVertex3f( vert_sw.x, vert_sw.y, vert_sw.z ); + glVertex3f( vert_se.x, vert_se.y, vert_se.z ); + + glEnd(); + +#if BOING_DEBUG + printf( "----------------------------------------------------------- \n" ); + printf( "lat = %f long_lo = %f long_hi = %f \n", lat_deg, long_lo, long_hi ); + printf( "vert_ne x = %.8f y = %.8f z = %.8f \n", vert_ne.x, vert_ne.y, vert_ne.z ); + printf( "vert_nw x = %.8f y = %.8f z = %.8f \n", vert_nw.x, vert_nw.y, vert_nw.z ); + printf( "vert_se x = %.8f y = %.8f z = %.8f \n", vert_se.x, vert_se.y, vert_se.z ); + printf( "vert_sw x = %.8f y = %.8f z = %.8f \n", vert_sw.x, vert_sw.y, vert_sw.z ); +#endif + + } + + /* + * Toggle color so that next band will opposite red/white colors than this one. + */ + colorToggle = ! colorToggle; + + /* + * This circular band is done. + */ + return; +} + + +/***************************************************************************** + * Draw the purple grid of lines, behind the Boing ball. + * When the Workbench is dropped to the bottom, Boing shows 12 rows. + *****************************************************************************/ +void DrawGrid( void ) +{ + int row, col; + const int rowTotal = 12; /* must be divisible by 2 */ + const int colTotal = rowTotal; /* must be same as rowTotal */ + const GLfloat widthLine = 2.0; /* should be divisible by 2 */ + const GLfloat sizeCell = GRID_SIZE / rowTotal; + const GLfloat z_offset = -40.0; + GLfloat xl, xr; + GLfloat yt, yb; + + glPushMatrix(); + glDisable( GL_CULL_FACE ); + + /* + * Another relative Z translation to separate objects. + */ + glTranslatef( 0.0, 0.0, DIST_BALL ); + + /* + * Draw vertical lines (as skinny 3D rectangles). + */ + for ( col = 0; col <= colTotal; col++ ) + { + /* + * Compute co-ords of line. + */ + xl = -GRID_SIZE / 2 + col * sizeCell; + xr = xl + widthLine; + + yt = GRID_SIZE / 2; + yb = -GRID_SIZE / 2 - widthLine; + + glBegin( GL_POLYGON ); + + glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ + + glVertex3f( xr, yt, z_offset ); /* NE */ + glVertex3f( xl, yt, z_offset ); /* NW */ + glVertex3f( xl, yb, z_offset ); /* SW */ + glVertex3f( xr, yb, z_offset ); /* SE */ + + glEnd(); + } + + /* + * Draw horizontal lines (as skinny 3D rectangles). + */ + for ( row = 0; row <= rowTotal; row++ ) + { + /* + * Compute co-ords of line. + */ + yt = GRID_SIZE / 2 - row * sizeCell; + yb = yt - widthLine; + + xl = -GRID_SIZE / 2; + xr = GRID_SIZE / 2 + widthLine; + + glBegin( GL_POLYGON ); + + glColor3f( 0.6f, 0.1f, 0.6f ); /* purple */ + + glVertex3f( xr, yt, z_offset ); /* NE */ + glVertex3f( xl, yt, z_offset ); /* NW */ + glVertex3f( xl, yb, z_offset ); /* SW */ + glVertex3f( xr, yb, z_offset ); /* SE */ + + glEnd(); + } + + glPopMatrix(); + + return; +} + + +/*======================================================================* + * main() + *======================================================================*/ + +int main( void ) +{ + GLFWwindow* window; + + /* Init GLFW */ + if( !glfwInit() ) + exit( EXIT_FAILURE ); + + window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL ); + if (!window) + { + glfwTerminate(); + exit( EXIT_FAILURE ); + } + + glfwSetWindowAspectRatio(window, 1, 1); + + glfwSetFramebufferSizeCallback(window, reshape); + glfwSetKeyCallback(window, key_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); + glfwSetCursorPosCallback(window, cursor_position_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval( 1 ); + + glfwGetFramebufferSize(window, &width, &height); + reshape(window, width, height); + + glfwSetTime( 0.0 ); + + init(); + + /* Main loop */ + for (;;) + { + /* Timing */ + t = glfwGetTime(); + dt = t - t_old; + t_old = t; + + /* Draw one frame */ + display(); + + /* Swap buffers */ + glfwSwapBuffers(window); + glfwPollEvents(); + + /* Check if we are still running */ + if (glfwWindowShouldClose(window)) + break; + } + + glfwTerminate(); + exit( EXIT_SUCCESS ); +} + diff --git a/extern/glfw-3.2.1/examples/gears.c b/extern/glfw-3.2.1/examples/gears.c new file mode 100644 index 0000000..29e63f5 --- /dev/null +++ b/extern/glfw-3.2.1/examples/gears.c @@ -0,0 +1,357 @@ +/* + * 3-D gear wheels. This program is in the public domain. + * + * Command line options: + * -info print GL implementation information + * -exit automatically exit after 30 seconds + * + * + * Brian Paul + * + * + * Marcus Geelnard: + * - Conversion to GLFW + * - Time based rendering (frame rate independent) + * - Slightly modified camera that should work better for stereo viewing + * + * + * Camilla Berglund: + * - Removed FPS counter (this is not a benchmark) + * - Added a few comments + * - Enabled vsync + */ + +#if defined(_MSC_VER) + // Make MS math.h define M_PI + #define _USE_MATH_DEFINES +#endif + +#include +#include +#include +#include + +#include +#include + +/** + + Draw a gear wheel. You'll probably want to call this function when + building a display list since we do a lot of trig here. + + Input: inner_radius - radius of hole at center + outer_radius - radius at center of teeth + width - width of gear teeth - number of teeth + tooth_depth - depth of tooth + + **/ + +static void +gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, + GLint teeth, GLfloat tooth_depth) +{ + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.f; + r2 = outer_radius + tooth_depth / 2.f; + + da = 2.f * (float) M_PI / teeth / 4.f; + + glShadeModel(GL_FLAT); + + glNormal3f(0.f, 0.f, 1.f); + + /* draw front face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); + if (i < teeth) { + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); + } + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = 2.f * (float) M_PI / teeth / 4.f; + for (i = 0; i < teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); + } + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + + /* draw back face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); + if (i < teeth) { + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); + } + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = 2.f * (float) M_PI / teeth / 4.f; + for (i = 0; i < teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f); + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), width * 0.5f); + glVertex3f(r1 * (float) cos(angle), r1 * (float) sin(angle), -width * 0.5f); + u = r2 * (float) cos(angle + da) - r1 * (float) cos(angle); + v = r2 * (float) sin(angle + da) - r1 * (float) sin(angle); + len = (float) sqrt(u * u + v * v); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + da), r2 * (float) sin(angle + da), -width * 0.5f); + glNormal3f((float) cos(angle), (float) sin(angle), 0.f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), width * 0.5f); + glVertex3f(r2 * (float) cos(angle + 2 * da), r2 * (float) sin(angle + 2 * da), -width * 0.5f); + u = r1 * (float) cos(angle + 3 * da) - r2 * (float) cos(angle + 2 * da); + v = r1 * (float) sin(angle + 3 * da) - r2 * (float) sin(angle + 2 * da); + glNormal3f(v, -u, 0.f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), width * 0.5f); + glVertex3f(r1 * (float) cos(angle + 3 * da), r1 * (float) sin(angle + 3 * da), -width * 0.5f); + glNormal3f((float) cos(angle), (float) sin(angle), 0.f); + } + + glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), width * 0.5f); + glVertex3f(r1 * (float) cos(0), r1 * (float) sin(0), -width * 0.5f); + + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.f * (float) M_PI / teeth; + glNormal3f(-(float) cos(angle), -(float) sin(angle), 0.f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), -width * 0.5f); + glVertex3f(r0 * (float) cos(angle), r0 * (float) sin(angle), width * 0.5f); + } + glEnd(); + +} + + +static GLfloat view_rotx = 20.f, view_roty = 30.f, view_rotz = 0.f; +static GLint gear1, gear2, gear3; +static GLfloat angle = 0.f; + +/* OpenGL draw function & timing */ +static void draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + glCallList(gear1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1f, -2.f, 0.f); + glRotatef(-2.f * angle - 9.f, 0.f, 0.f, 1.f); + glCallList(gear2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1f, 4.2f, 0.f); + glRotatef(-2.f * angle - 25.f, 0.f, 0.f, 1.f); + glCallList(gear3); + glPopMatrix(); + + glPopMatrix(); +} + + +/* update animation parameters */ +static void animate(void) +{ + angle = 100.f * (float) glfwGetTime(); +} + + +/* change view angle, exit upon ESC */ +void key( GLFWwindow* window, int k, int s, int action, int mods ) +{ + if( action != GLFW_PRESS ) return; + + switch (k) { + case GLFW_KEY_Z: + if( mods & GLFW_MOD_SHIFT ) + view_rotz -= 5.0; + else + view_rotz += 5.0; + break; + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + case GLFW_KEY_UP: + view_rotx += 5.0; + break; + case GLFW_KEY_DOWN: + view_rotx -= 5.0; + break; + case GLFW_KEY_LEFT: + view_roty += 5.0; + break; + case GLFW_KEY_RIGHT: + view_roty -= 5.0; + break; + default: + return; + } +} + + +/* new window size */ +void reshape( GLFWwindow* window, int width, int height ) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + GLfloat xmax, znear, zfar; + + znear = 5.0f; + zfar = 30.0f; + xmax = znear * 0.5f; + + glViewport( 0, 0, (GLint) width, (GLint) height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -xmax, xmax, -xmax*h, xmax*h, znear, zfar ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -20.0 ); +} + + +/* program & OpenGL initialization */ +static void init(void) +{ + static GLfloat pos[4] = {5.f, 5.f, 10.f, 0.f}; + static GLfloat red[4] = {0.8f, 0.1f, 0.f, 1.f}; + static GLfloat green[4] = {0.f, 0.8f, 0.2f, 1.f}; + static GLfloat blue[4] = {0.2f, 0.2f, 1.f, 1.f}; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + /* make the gears */ + gear1 = glGenLists(1); + glNewList(gear1, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear(1.f, 4.f, 1.f, 20, 0.7f); + glEndList(); + + gear2 = glGenLists(1); + glNewList(gear2, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear(0.5f, 2.f, 2.f, 10, 0.7f); + glEndList(); + + gear3 = glGenLists(1); + glNewList(gear3, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear(1.3f, 2.f, 0.5f, 10, 0.7f); + glEndList(); + + glEnable(GL_NORMALIZE); +} + + +/* program entry */ +int main(int argc, char *argv[]) +{ + GLFWwindow* window; + int width, height; + + if( !glfwInit() ) + { + fprintf( stderr, "Failed to initialize GLFW\n" ); + exit( EXIT_FAILURE ); + } + + glfwWindowHint(GLFW_DEPTH_BITS, 16); + + window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL ); + if (!window) + { + fprintf( stderr, "Failed to open GLFW window\n" ); + glfwTerminate(); + exit( EXIT_FAILURE ); + } + + // Set callback functions + glfwSetFramebufferSizeCallback(window, reshape); + glfwSetKeyCallback(window, key); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval( 1 ); + + glfwGetFramebufferSize(window, &width, &height); + reshape(window, width, height); + + // Parse command-line options + init(); + + // Main loop + while( !glfwWindowShouldClose(window) ) + { + // Draw gears + draw(); + + // Update animation + animate(); + + // Swap buffers + glfwSwapBuffers(window); + glfwPollEvents(); + } + + // Terminate GLFW + glfwTerminate(); + + // Exit program + exit( EXIT_SUCCESS ); +} + diff --git a/extern/glfw-3.2.1/examples/glfw.icns b/extern/glfw-3.2.1/examples/glfw.icns new file mode 100644 index 0000000..ad98f39 Binary files /dev/null and b/extern/glfw-3.2.1/examples/glfw.icns differ diff --git a/extern/glfw-3.2.1/examples/glfw.ico b/extern/glfw-3.2.1/examples/glfw.ico new file mode 100644 index 0000000..882a660 Binary files /dev/null and b/extern/glfw-3.2.1/examples/glfw.ico differ diff --git a/extern/glfw-3.2.1/examples/glfw.rc b/extern/glfw-3.2.1/examples/glfw.rc new file mode 100644 index 0000000..f2b62f6 --- /dev/null +++ b/extern/glfw-3.2.1/examples/glfw.rc @@ -0,0 +1,3 @@ + +GLFW_ICON ICON "glfw.ico" + diff --git a/extern/glfw-3.2.1/examples/heightmap.c b/extern/glfw-3.2.1/examples/heightmap.c new file mode 100644 index 0000000..b57815e --- /dev/null +++ b/extern/glfw-3.2.1/examples/heightmap.c @@ -0,0 +1,511 @@ +//======================================================================== +// Heightmap example program using OpenGL 3 core profile +// Copyright (c) 2010 Olivier Delannoy +// +// 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 +#include +#include +#include +#include + +#include +#include + +/* Map height updates */ +#define MAX_CIRCLE_SIZE (5.0f) +#define MAX_DISPLACEMENT (1.0f) +#define DISPLACEMENT_SIGN_LIMIT (0.3f) +#define MAX_ITER (200) +#define NUM_ITER_AT_A_TIME (1) + +/* Map general information */ +#define MAP_SIZE (10.0f) +#define MAP_NUM_VERTICES (80) +#define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES) +#define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \ + 2 * (MAP_NUM_VERTICES - 1)) + + +/********************************************************************** + * Default shader programs + *********************************************************************/ + +static const char* vertex_shader_text = +"#version 150\n" +"uniform mat4 project;\n" +"uniform mat4 modelview;\n" +"in float x;\n" +"in float y;\n" +"in float z;\n" +"\n" +"void main()\n" +"{\n" +" gl_Position = project * modelview * vec4(x, y, z, 1.0);\n" +"}\n"; + +static const char* fragment_shader_text = +"#version 150\n" +"out vec4 color;\n" +"void main()\n" +"{\n" +" color = vec4(0.2, 1.0, 0.2, 1.0); \n" +"}\n"; + +/********************************************************************** + * Values for shader uniforms + *********************************************************************/ + +/* Frustum configuration */ +static GLfloat view_angle = 45.0f; +static GLfloat aspect_ratio = 4.0f/3.0f; +static GLfloat z_near = 1.0f; +static GLfloat z_far = 100.f; + +/* Projection matrix */ +static GLfloat projection_matrix[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/* Model view matrix */ +static GLfloat modelview_matrix[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/********************************************************************** + * Heightmap vertex and index data + *********************************************************************/ + +static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES]; +static GLuint map_line_indices[2*MAP_NUM_LINES]; + +/* Store uniform location for the shaders + * Those values are setup as part of the process of creating + * the shader program. They should not be used before creating + * the program. + */ +static GLuint mesh; +static GLuint mesh_vbo[4]; + +/********************************************************************** + * OpenGL helper functions + *********************************************************************/ + +/* Creates a shader object of the specified type using the specified text + */ +static GLuint make_shader(GLenum type, const char* text) +{ + GLuint shader; + GLint shader_ok; + GLsizei log_length; + char info_log[8192]; + + shader = glCreateShader(type); + if (shader != 0) + { + glShaderSource(shader, 1, (const GLchar**)&text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); + if (shader_ok != GL_TRUE) + { + fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" ); + glGetShaderInfoLog(shader, 8192, &log_length,info_log); + fprintf(stderr, "ERROR: \n%s\n\n", info_log); + glDeleteShader(shader); + shader = 0; + } + } + return shader; +} + +/* Creates a program object using the specified vertex and fragment text + */ +static GLuint make_shader_program(const char* vs_text, const char* fs_text) +{ + GLuint program = 0u; + GLint program_ok; + GLuint vertex_shader = 0u; + GLuint fragment_shader = 0u; + GLsizei log_length; + char info_log[8192]; + + vertex_shader = make_shader(GL_VERTEX_SHADER, vs_text); + if (vertex_shader != 0u) + { + fragment_shader = make_shader(GL_FRAGMENT_SHADER, fs_text); + if (fragment_shader != 0u) + { + /* make the program that connect the two shader and link it */ + program = glCreateProgram(); + if (program != 0u) + { + /* attach both shader and link */ + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &program_ok); + + if (program_ok != GL_TRUE) + { + fprintf(stderr, "ERROR, failed to link shader program\n"); + glGetProgramInfoLog(program, 8192, &log_length, info_log); + fprintf(stderr, "ERROR: \n%s\n\n", info_log); + glDeleteProgram(program); + glDeleteShader(fragment_shader); + glDeleteShader(vertex_shader); + program = 0u; + } + } + } + else + { + fprintf(stderr, "ERROR: Unable to load fragment shader\n"); + glDeleteShader(vertex_shader); + } + } + else + { + fprintf(stderr, "ERROR: Unable to load vertex shader\n"); + } + return program; +} + +/********************************************************************** + * Geometry creation functions + *********************************************************************/ + +/* Generate vertices and indices for the heightmap + */ +static void init_map(void) +{ + int i; + int j; + int k; + GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1); + GLfloat x = 0.0f; + GLfloat z = 0.0f; + /* Create a flat grid */ + k = 0; + for (i = 0 ; i < MAP_NUM_VERTICES ; ++i) + { + for (j = 0 ; j < MAP_NUM_VERTICES ; ++j) + { + map_vertices[0][k] = x; + map_vertices[1][k] = 0.0f; + map_vertices[2][k] = z; + z += step; + ++k; + } + x += step; + z = 0.0f; + } +#if DEBUG_ENABLED + for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i) + { + printf ("Vertice %d (%f, %f, %f)\n", + i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]); + + } +#endif + /* create indices */ + /* line fan based on i + * i+1 + * | / i + n + 1 + * | / + * |/ + * i --- i + n + */ + + /* close the top of the square */ + k = 0; + for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i) + { + map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1; + map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1; + } + /* close the right of the square */ + for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i) + { + map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i; + map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1; + } + + for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i) + { + for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j) + { + int ref = i * (MAP_NUM_VERTICES) + j; + map_line_indices[k++] = ref; + map_line_indices[k++] = ref + 1; + + map_line_indices[k++] = ref; + map_line_indices[k++] = ref + MAP_NUM_VERTICES; + + map_line_indices[k++] = ref; + map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1; + } + } + +#ifdef DEBUG_ENABLED + for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2) + { + int beg, end; + beg = map_line_indices[k]; + end = map_line_indices[k+1]; + printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n", + k / 2, beg, end, + map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg], + map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]); + } +#endif +} + +static void generate_heightmap__circle(float* center_x, float* center_y, + float* size, float* displacement) +{ + float sign; + /* random value for element in between [0-1.0] */ + *center_x = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); + *center_y = (MAP_SIZE * rand()) / (1.0f * RAND_MAX); + *size = (MAX_CIRCLE_SIZE * rand()) / (1.0f * RAND_MAX); + sign = (1.0f * rand()) / (1.0f * RAND_MAX); + sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f; + *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (1.0f * RAND_MAX); +} + +/* Run the specified number of iterations of the generation process for the + * heightmap + */ +static void update_map(int num_iter) +{ + assert(num_iter > 0); + while(num_iter) + { + /* center of the circle */ + float center_x; + float center_z; + float circle_size; + float disp; + size_t ii; + generate_heightmap__circle(¢er_x, ¢er_z, &circle_size, &disp); + disp = disp / 2.0f; + for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii) + { + GLfloat dx = center_x - map_vertices[0][ii]; + GLfloat dz = center_z - map_vertices[2][ii]; + GLfloat pd = (2.0f * (float) sqrt((dx * dx) + (dz * dz))) / circle_size; + if (fabs(pd) <= 1.0f) + { + /* tx,tz is within the circle */ + GLfloat new_height = disp + (float) (cos(pd*3.14f)*disp); + map_vertices[1][ii] += new_height; + } + } + --num_iter; + } +} + +/********************************************************************** + * OpenGL helper functions + *********************************************************************/ + +/* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to + * the specified program object + */ +static void make_mesh(GLuint program) +{ + GLuint attrloc; + + glGenVertexArrays(1, &mesh); + glGenBuffers(4, mesh_vbo); + glBindVertexArray(mesh); + /* Prepare the data for drawing through a buffer inidices */ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_vbo[3]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* MAP_NUM_LINES * 2, map_line_indices, GL_STATIC_DRAW); + + /* Prepare the attributes for rendering */ + attrloc = glGetAttribLocation(program, "x"); + glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[0][0], GL_STATIC_DRAW); + glEnableVertexAttribArray(attrloc); + glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); + + attrloc = glGetAttribLocation(program, "z"); + glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[2]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW); + glEnableVertexAttribArray(attrloc); + glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); + + attrloc = glGetAttribLocation(program, "y"); + glBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(attrloc); + glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0); +} + +/* Update VBO vertices from source data + */ +static void update_mesh(void) +{ + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0]); +} + +/********************************************************************** + * GLFW callback functions + *********************************************************************/ + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + switch(key) + { + case GLFW_KEY_ESCAPE: + /* Exit program on Escape */ + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +int main(int argc, char** argv) +{ + GLFWwindow* window; + int iter; + double dt; + double last_update_time; + int frame; + float f; + GLint uloc_modelview; + GLint uloc_project; + int width, height; + + GLuint shader_program; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); + + window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL); + if (! window ) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + /* Register events callback */ + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + + /* Prepare opengl resources for rendering */ + shader_program = make_shader_program(vertex_shader_text, fragment_shader_text); + + if (shader_program == 0u) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glUseProgram(shader_program); + uloc_project = glGetUniformLocation(shader_program, "project"); + uloc_modelview = glGetUniformLocation(shader_program, "modelview"); + + /* Compute the projection matrix */ + f = 1.0f / tanf(view_angle / 2.0f); + projection_matrix[0] = f / aspect_ratio; + projection_matrix[5] = f; + projection_matrix[10] = (z_far + z_near)/ (z_near - z_far); + projection_matrix[11] = -1.0f; + projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far); + glUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix); + + /* Set the camera position */ + modelview_matrix[12] = -5.0f; + modelview_matrix[13] = -5.0f; + modelview_matrix[14] = -20.0f; + glUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix); + + /* Create mesh data */ + init_map(); + make_mesh(shader_program); + + /* Create vao + vbo to store the mesh */ + /* Create the vbo to store all the information for the grid and the height */ + + /* setup the scene ready for rendering */ + glfwGetFramebufferSize(window, &width, &height); + glViewport(0, 0, width, height); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + /* main loop */ + frame = 0; + iter = 0; + last_update_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) + { + ++frame; + /* render the next frame */ + glClear(GL_COLOR_BUFFER_BIT); + glDrawElements(GL_LINES, 2* MAP_NUM_LINES , GL_UNSIGNED_INT, 0); + + /* display and process events through callbacks */ + glfwSwapBuffers(window); + glfwPollEvents(); + /* Check the frame rate and update the heightmap if needed */ + dt = glfwGetTime(); + if ((dt - last_update_time) > 0.2) + { + /* generate the next iteration of the heightmap */ + if (iter < MAX_ITER) + { + update_map(NUM_ITER_AT_A_TIME); + update_mesh(); + iter += NUM_ITER_AT_A_TIME; + } + last_update_time = dt; + frame = 0; + } + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/examples/particles.c b/extern/glfw-3.2.1/examples/particles.c new file mode 100644 index 0000000..a035cb1 --- /dev/null +++ b/extern/glfw-3.2.1/examples/particles.c @@ -0,0 +1,1068 @@ +//======================================================================== +// A simple particle engine with threaded physics +// Copyright (c) Marcus Geelnard +// Copyright (c) Camilla Berglund +// +// 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(_MSC_VER) + // Make MS math.h define M_PI + #define _USE_MATH_DEFINES +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +// Define tokens for GL_EXT_separate_specular_color if not already defined +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif // GL_EXT_separate_specular_color + + +//======================================================================== +// Type definitions +//======================================================================== + +typedef struct +{ + float x, y, z; +} Vec3; + +// This structure is used for interleaved vertex arrays (see the +// draw_particles function) +// +// NOTE: This structure SHOULD be packed on most systems. It uses 32-bit fields +// on 32-bit boundaries, and is a multiple of 64 bits in total (6x32=3x64). If +// it does not work, try using pragmas or whatever to force the structure to be +// packed. +typedef struct +{ + GLfloat s, t; // Texture coordinates + GLuint rgba; // Color (four ubytes packed into an uint) + GLfloat x, y, z; // Vertex coordinates +} Vertex; + + +//======================================================================== +// Program control global variables +//======================================================================== + +// Window dimensions +float aspect_ratio; + +// "wireframe" flag (true if we use wireframe view) +int wireframe; + +// Thread synchronization +struct { + double t; // Time (s) + float dt; // Time since last frame (s) + int p_frame; // Particle physics frame number + int d_frame; // Particle draw frame number + cnd_t p_done; // Condition: particle physics done + cnd_t d_done; // Condition: particle draw done + mtx_t particles_lock; // Particles data sharing mutex +} thread_sync; + + +//======================================================================== +// Texture declarations (we hard-code them into the source code, since +// they are so simple) +//======================================================================== + +#define P_TEX_WIDTH 8 // Particle texture dimensions +#define P_TEX_HEIGHT 8 +#define F_TEX_WIDTH 16 // Floor texture dimensions +#define F_TEX_HEIGHT 16 + +// Texture object IDs +GLuint particle_tex_id, floor_tex_id; + +// Particle texture (a simple spot) +const unsigned char particle_texture[ P_TEX_WIDTH * P_TEX_HEIGHT ] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x22, 0x22, 0x11, 0x00, 0x00, + 0x00, 0x11, 0x33, 0x88, 0x77, 0x33, 0x11, 0x00, + 0x00, 0x22, 0x88, 0xff, 0xee, 0x77, 0x22, 0x00, + 0x00, 0x22, 0x77, 0xee, 0xff, 0x88, 0x22, 0x00, + 0x00, 0x11, 0x33, 0x77, 0x88, 0x33, 0x11, 0x00, + 0x00, 0x00, 0x11, 0x33, 0x22, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// Floor texture (your basic checkered floor) +const unsigned char floor_texture[ F_TEX_WIDTH * F_TEX_HEIGHT ] = { + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xff, 0xf0, 0xcc, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xf0, 0xcc, 0xee, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x30, 0x66, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xee, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xcc, 0xf0, 0xf0, 0xf0, 0x30, 0x30, 0x55, 0x30, 0x30, 0x44, 0x30, 0x30, + 0xf0, 0xdd, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x30, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x33, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, 0xf0, 0xff, 0xf0, 0xf0, 0xdd, 0xf0, 0xf0, 0xff, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x55, 0x33, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, + 0x30, 0x44, 0x66, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xaa, 0xf0, 0xf0, 0xcc, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xdd, 0xf0, + 0x30, 0x30, 0x30, 0x77, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, +}; + + +//======================================================================== +// These are fixed constants that control the particle engine. In a +// modular world, these values should be variables... +//======================================================================== + +// Maximum number of particles +#define MAX_PARTICLES 3000 + +// Life span of a particle (in seconds) +#define LIFE_SPAN 8.f + +// A new particle is born every [BIRTH_INTERVAL] second +#define BIRTH_INTERVAL (LIFE_SPAN/(float)MAX_PARTICLES) + +// Particle size (meters) +#define PARTICLE_SIZE 0.7f + +// Gravitational constant (m/s^2) +#define GRAVITY 9.8f + +// Base initial velocity (m/s) +#define VELOCITY 8.f + +// Bounce friction (1.0 = no friction, 0.0 = maximum friction) +#define FRICTION 0.75f + +// "Fountain" height (m) +#define FOUNTAIN_HEIGHT 3.f + +// Fountain radius (m) +#define FOUNTAIN_RADIUS 1.6f + +// Minimum delta-time for particle phisics (s) +#define MIN_DELTA_T (BIRTH_INTERVAL * 0.5f) + + +//======================================================================== +// Particle system global variables +//======================================================================== + +// This structure holds all state for a single particle +typedef struct { + float x,y,z; // Position in space + float vx,vy,vz; // Velocity vector + float r,g,b; // Color of particle + float life; // Life of particle (1.0 = newborn, < 0.0 = dead) + int active; // Tells if this particle is active +} PARTICLE; + +// Global vectors holding all particles. We use two vectors for double +// buffering. +static PARTICLE particles[MAX_PARTICLES]; + +// Global variable holding the age of the youngest particle +static float min_age; + +// Color of latest born particle (used for fountain lighting) +static float glow_color[4]; + +// Position of latest born particle (used for fountain lighting) +static float glow_pos[4]; + + +//======================================================================== +// Object material and fog configuration constants +//======================================================================== + +const GLfloat fountain_diffuse[4] = { 0.7f, 1.f, 1.f, 1.f }; +const GLfloat fountain_specular[4] = { 1.f, 1.f, 1.f, 1.f }; +const GLfloat fountain_shininess = 12.f; +const GLfloat floor_diffuse[4] = { 1.f, 0.6f, 0.6f, 1.f }; +const GLfloat floor_specular[4] = { 0.6f, 0.6f, 0.6f, 1.f }; +const GLfloat floor_shininess = 18.f; +const GLfloat fog_color[4] = { 0.1f, 0.1f, 0.1f, 1.f }; + + +//======================================================================== +// Print usage information +//======================================================================== + +static void usage(void) +{ + printf("Usage: particles [-bfhs]\n"); + printf("Options:\n"); + printf(" -f Run in full screen\n"); + printf(" -h Display this help\n"); + printf(" -s Run program as single thread (default is to use two threads)\n"); + printf("\n"); + printf("Program runtime controls:\n"); + printf(" W Toggle wireframe mode\n"); + printf(" Esc Exit program\n"); +} + + +//======================================================================== +// Initialize a new particle +//======================================================================== + +static void init_particle(PARTICLE *p, double t) +{ + float xy_angle, velocity; + + // Start position of particle is at the fountain blow-out + p->x = 0.f; + p->y = 0.f; + p->z = FOUNTAIN_HEIGHT; + + // Start velocity is up (Z)... + p->vz = 0.7f + (0.3f / 4096.f) * (float) (rand() & 4095); + + // ...and a randomly chosen X/Y direction + xy_angle = (2.f * (float) M_PI / 4096.f) * (float) (rand() & 4095); + p->vx = 0.4f * (float) cos(xy_angle); + p->vy = 0.4f * (float) sin(xy_angle); + + // Scale velocity vector according to a time-varying velocity + velocity = VELOCITY * (0.8f + 0.1f * (float) (sin(0.5 * t) + sin(1.31 * t))); + p->vx *= velocity; + p->vy *= velocity; + p->vz *= velocity; + + // Color is time-varying + p->r = 0.7f + 0.3f * (float) sin(0.34 * t + 0.1); + p->g = 0.6f + 0.4f * (float) sin(0.63 * t + 1.1); + p->b = 0.6f + 0.4f * (float) sin(0.91 * t + 2.1); + + // Store settings for fountain glow lighting + glow_pos[0] = 0.4f * (float) sin(1.34 * t); + glow_pos[1] = 0.4f * (float) sin(3.11 * t); + glow_pos[2] = FOUNTAIN_HEIGHT + 1.f; + glow_pos[3] = 1.f; + glow_color[0] = p->r; + glow_color[1] = p->g; + glow_color[2] = p->b; + glow_color[3] = 1.f; + + // The particle is new-born and active + p->life = 1.f; + p->active = 1; +} + + +//======================================================================== +// Update a particle +//======================================================================== + +#define FOUNTAIN_R2 (FOUNTAIN_RADIUS+PARTICLE_SIZE/2)*(FOUNTAIN_RADIUS+PARTICLE_SIZE/2) + +static void update_particle(PARTICLE *p, float dt) +{ + // If the particle is not active, we need not do anything + if (!p->active) + return; + + // The particle is getting older... + p->life -= dt * (1.f / LIFE_SPAN); + + // Did the particle die? + if (p->life <= 0.f) + { + p->active = 0; + return; + } + + // Apply gravity + p->vz = p->vz - GRAVITY * dt; + + // Update particle position + p->x = p->x + p->vx * dt; + p->y = p->y + p->vy * dt; + p->z = p->z + p->vz * dt; + + // Simple collision detection + response + if (p->vz < 0.f) + { + // Particles should bounce on the fountain (with friction) + if ((p->x * p->x + p->y * p->y) < FOUNTAIN_R2 && + p->z < (FOUNTAIN_HEIGHT + PARTICLE_SIZE / 2)) + { + p->vz = -FRICTION * p->vz; + p->z = FOUNTAIN_HEIGHT + PARTICLE_SIZE / 2 + + FRICTION * (FOUNTAIN_HEIGHT + + PARTICLE_SIZE / 2 - p->z); + } + + // Particles should bounce on the floor (with friction) + else if (p->z < PARTICLE_SIZE / 2) + { + p->vz = -FRICTION * p->vz; + p->z = PARTICLE_SIZE / 2 + + FRICTION * (PARTICLE_SIZE / 2 - p->z); + } + } +} + + +//======================================================================== +// The main frame for the particle engine. Called once per frame. +//======================================================================== + +static void particle_engine(double t, float dt) +{ + int i; + float dt2; + + // Update particles (iterated several times per frame if dt is too large) + while (dt > 0.f) + { + // Calculate delta time for this iteration + dt2 = dt < MIN_DELTA_T ? dt : MIN_DELTA_T; + + for (i = 0; i < MAX_PARTICLES; i++) + update_particle(&particles[i], dt2); + + min_age += dt2; + + // Should we create any new particle(s)? + while (min_age >= BIRTH_INTERVAL) + { + min_age -= BIRTH_INTERVAL; + + // Find a dead particle to replace with a new one + for (i = 0; i < MAX_PARTICLES; i++) + { + if (!particles[i].active) + { + init_particle(&particles[i], t + min_age); + update_particle(&particles[i], min_age); + break; + } + } + } + + dt -= dt2; + } +} + + +//======================================================================== +// Draw all active particles. We use OpenGL 1.1 vertex +// arrays for this in order to accelerate the drawing. +//======================================================================== + +#define BATCH_PARTICLES 70 // Number of particles to draw in each batch + // (70 corresponds to 7.5 KB = will not blow + // the L1 data cache on most CPUs) +#define PARTICLE_VERTS 4 // Number of vertices per particle + +static void draw_particles(GLFWwindow* window, double t, float dt) +{ + int i, particle_count; + Vertex vertex_array[BATCH_PARTICLES * PARTICLE_VERTS]; + Vertex* vptr; + float alpha; + GLuint rgba; + Vec3 quad_lower_left, quad_lower_right; + GLfloat mat[16]; + PARTICLE* pptr; + + // Here comes the real trick with flat single primitive objects (s.c. + // "billboards"): We must rotate the textured primitive so that it + // always faces the viewer (is coplanar with the view-plane). + // We: + // 1) Create the primitive around origo (0,0,0) + // 2) Rotate it so that it is coplanar with the view plane + // 3) Translate it according to the particle position + // Note that 1) and 2) is the same for all particles (done only once). + + // Get modelview matrix. We will only use the upper left 3x3 part of + // the matrix, which represents the rotation. + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + + // 1) & 2) We do it in one swift step: + // Although not obvious, the following six lines represent two matrix/ + // vector multiplications. The matrix is the inverse 3x3 rotation + // matrix (i.e. the transpose of the same matrix), and the two vectors + // represent the lower left corner of the quad, PARTICLE_SIZE/2 * + // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0). + // The upper left/right corners of the quad is always the negative of + // the opposite corners (regardless of rotation). + quad_lower_left.x = (-PARTICLE_SIZE / 2) * (mat[0] + mat[1]); + quad_lower_left.y = (-PARTICLE_SIZE / 2) * (mat[4] + mat[5]); + quad_lower_left.z = (-PARTICLE_SIZE / 2) * (mat[8] + mat[9]); + quad_lower_right.x = (PARTICLE_SIZE / 2) * (mat[0] - mat[1]); + quad_lower_right.y = (PARTICLE_SIZE / 2) * (mat[4] - mat[5]); + quad_lower_right.z = (PARTICLE_SIZE / 2) * (mat[8] - mat[9]); + + // Don't update z-buffer, since all particles are transparent! + glDepthMask(GL_FALSE); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + // Select particle texture + if (!wireframe) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, particle_tex_id); + } + + // Set up vertex arrays. We use interleaved arrays, which is easier to + // handle (in most situations) and it gives a linear memeory access + // access pattern (which may give better performance in some + // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords, + // 4 ubytes for color and 3 floats for vertex coord (in that order). + // Most OpenGL cards / drivers are optimized for this format. + glInterleavedArrays(GL_T2F_C4UB_V3F, 0, vertex_array); + + // Wait for particle physics thread to be done + mtx_lock(&thread_sync.particles_lock); + while (!glfwWindowShouldClose(window) && + thread_sync.p_frame <= thread_sync.d_frame) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += 100000000; + cnd_timedwait(&thread_sync.p_done, &thread_sync.particles_lock, &ts); + } + + // Store the frame time and delta time for the physics thread + thread_sync.t = t; + thread_sync.dt = dt; + + // Update frame counter + thread_sync.d_frame++; + + // Loop through all particles and build vertex arrays. + particle_count = 0; + vptr = vertex_array; + pptr = particles; + + for (i = 0; i < MAX_PARTICLES; i++) + { + if (pptr->active) + { + // Calculate particle intensity (we set it to max during 75% + // of its life, then it fades out) + alpha = 4.f * pptr->life; + if (alpha > 1.f) + alpha = 1.f; + + // Convert color from float to 8-bit (store it in a 32-bit + // integer using endian independent type casting) + ((GLubyte*) &rgba)[0] = (GLubyte)(pptr->r * 255.f); + ((GLubyte*) &rgba)[1] = (GLubyte)(pptr->g * 255.f); + ((GLubyte*) &rgba)[2] = (GLubyte)(pptr->b * 255.f); + ((GLubyte*) &rgba)[3] = (GLubyte)(alpha * 255.f); + + // 3) Translate the quad to the correct position in modelview + // space and store its parameters in vertex arrays (we also + // store texture coord and color information for each vertex). + + // Lower left corner + vptr->s = 0.f; + vptr->t = 0.f; + vptr->rgba = rgba; + vptr->x = pptr->x + quad_lower_left.x; + vptr->y = pptr->y + quad_lower_left.y; + vptr->z = pptr->z + quad_lower_left.z; + vptr ++; + + // Lower right corner + vptr->s = 1.f; + vptr->t = 0.f; + vptr->rgba = rgba; + vptr->x = pptr->x + quad_lower_right.x; + vptr->y = pptr->y + quad_lower_right.y; + vptr->z = pptr->z + quad_lower_right.z; + vptr ++; + + // Upper right corner + vptr->s = 1.f; + vptr->t = 1.f; + vptr->rgba = rgba; + vptr->x = pptr->x - quad_lower_left.x; + vptr->y = pptr->y - quad_lower_left.y; + vptr->z = pptr->z - quad_lower_left.z; + vptr ++; + + // Upper left corner + vptr->s = 0.f; + vptr->t = 1.f; + vptr->rgba = rgba; + vptr->x = pptr->x - quad_lower_right.x; + vptr->y = pptr->y - quad_lower_right.y; + vptr->z = pptr->z - quad_lower_right.z; + vptr ++; + + // Increase count of drawable particles + particle_count ++; + } + + // If we have filled up one batch of particles, draw it as a set + // of quads using glDrawArrays. + if (particle_count >= BATCH_PARTICLES) + { + // The first argument tells which primitive type we use (QUAD) + // The second argument tells the index of the first vertex (0) + // The last argument is the vertex count + glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); + particle_count = 0; + vptr = vertex_array; + } + + // Next particle + pptr++; + } + + // We are done with the particle data + mtx_unlock(&thread_sync.particles_lock); + cnd_signal(&thread_sync.d_done); + + // Draw final batch of particles (if any) + glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); + + // Disable vertex arrays (Note: glInterleavedArrays implicitly called + // glEnableClientState for vertex, texture coord and color arrays) + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + glDepthMask(GL_TRUE); +} + + +//======================================================================== +// Fountain geometry specification +//======================================================================== + +#define FOUNTAIN_SIDE_POINTS 14 +#define FOUNTAIN_SWEEP_STEPS 32 + +static const float fountain_side[FOUNTAIN_SIDE_POINTS * 2] = +{ + 1.2f, 0.f, 1.f, 0.2f, 0.41f, 0.3f, 0.4f, 0.35f, + 0.4f, 1.95f, 0.41f, 2.f, 0.8f, 2.2f, 1.2f, 2.4f, + 1.5f, 2.7f, 1.55f,2.95f, 1.6f, 3.f, 1.f, 3.f, + 0.5f, 3.f, 0.f, 3.f +}; + +static const float fountain_normal[FOUNTAIN_SIDE_POINTS * 2] = +{ + 1.0000f, 0.0000f, 0.6428f, 0.7660f, 0.3420f, 0.9397f, 1.0000f, 0.0000f, + 1.0000f, 0.0000f, 0.3420f,-0.9397f, 0.4226f,-0.9063f, 0.5000f,-0.8660f, + 0.7660f,-0.6428f, 0.9063f,-0.4226f, 0.0000f,1.00000f, 0.0000f,1.00000f, + 0.0000f,1.00000f, 0.0000f,1.00000f +}; + + +//======================================================================== +// Draw a fountain +//======================================================================== + +static void draw_fountain(void) +{ + static GLuint fountain_list = 0; + double angle; + float x, y; + int m, n; + + // The first time, we build the fountain display list + if (!fountain_list) + { + fountain_list = glGenLists(1); + glNewList(fountain_list, GL_COMPILE_AND_EXECUTE); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, fountain_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, fountain_specular); + glMaterialf(GL_FRONT, GL_SHININESS, fountain_shininess); + + // Build fountain using triangle strips + for (n = 0; n < FOUNTAIN_SIDE_POINTS - 1; n++) + { + glBegin(GL_TRIANGLE_STRIP); + for (m = 0; m <= FOUNTAIN_SWEEP_STEPS; m++) + { + angle = (double) m * (2.0 * M_PI / (double) FOUNTAIN_SWEEP_STEPS); + x = (float) cos(angle); + y = (float) sin(angle); + + // Draw triangle strip + glNormal3f(x * fountain_normal[n * 2 + 2], + y * fountain_normal[n * 2 + 2], + fountain_normal[n * 2 + 3]); + glVertex3f(x * fountain_side[n * 2 + 2], + y * fountain_side[n * 2 + 2], + fountain_side[n * 2 +3 ]); + glNormal3f(x * fountain_normal[n * 2], + y * fountain_normal[n * 2], + fountain_normal[n * 2 + 1]); + glVertex3f(x * fountain_side[n * 2], + y * fountain_side[n * 2], + fountain_side[n * 2 + 1]); + } + + glEnd(); + } + + glEndList(); + } + else + glCallList(fountain_list); +} + + +//======================================================================== +// Recursive function for building variable tesselated floor +//======================================================================== + +static void tessellate_floor(float x1, float y1, float x2, float y2, int depth) +{ + float delta, x, y; + + // Last recursion? + if (depth >= 5) + delta = 999999.f; + else + { + x = (float) (fabs(x1) < fabs(x2) ? fabs(x1) : fabs(x2)); + y = (float) (fabs(y1) < fabs(y2) ? fabs(y1) : fabs(y2)); + delta = x*x + y*y; + } + + // Recurse further? + if (delta < 0.1f) + { + x = (x1 + x2) * 0.5f; + y = (y1 + y2) * 0.5f; + tessellate_floor(x1, y1, x, y, depth + 1); + tessellate_floor(x, y1, x2, y, depth + 1); + tessellate_floor(x1, y, x, y2, depth + 1); + tessellate_floor(x, y, x2, y2, depth + 1); + } + else + { + glTexCoord2f(x1 * 30.f, y1 * 30.f); + glVertex3f( x1 * 80.f, y1 * 80.f, 0.f); + glTexCoord2f(x2 * 30.f, y1 * 30.f); + glVertex3f( x2 * 80.f, y1 * 80.f, 0.f); + glTexCoord2f(x2 * 30.f, y2 * 30.f); + glVertex3f( x2 * 80.f, y2 * 80.f, 0.f); + glTexCoord2f(x1 * 30.f, y2 * 30.f); + glVertex3f( x1 * 80.f, y2 * 80.f, 0.f); + } +} + + +//======================================================================== +// Draw floor. We build the floor recursively and let the tessellation in the +// center (near x,y=0,0) be high, while the tessellation around the edges be +// low. +//======================================================================== + +static void draw_floor(void) +{ + static GLuint floor_list = 0; + + if (!wireframe) + { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, floor_tex_id); + } + + // The first time, we build the floor display list + if (!floor_list) + { + floor_list = glGenLists(1); + glNewList(floor_list, GL_COMPILE_AND_EXECUTE); + + glMaterialfv(GL_FRONT, GL_DIFFUSE, floor_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, floor_specular); + glMaterialf(GL_FRONT, GL_SHININESS, floor_shininess); + + // Draw floor as a bunch of triangle strips (high tesselation + // improves lighting) + glNormal3f(0.f, 0.f, 1.f); + glBegin(GL_QUADS); + tessellate_floor(-1.f, -1.f, 0.f, 0.f, 0); + tessellate_floor( 0.f, -1.f, 1.f, 0.f, 0); + tessellate_floor( 0.f, 0.f, 1.f, 1.f, 0); + tessellate_floor(-1.f, 0.f, 0.f, 1.f, 0); + glEnd(); + + glEndList(); + } + else + glCallList(floor_list); + + glDisable(GL_TEXTURE_2D); + +} + + +//======================================================================== +// Position and configure light sources +//======================================================================== + +static void setup_lights(void) +{ + float l1pos[4], l1amb[4], l1dif[4], l1spec[4]; + float l2pos[4], l2amb[4], l2dif[4], l2spec[4]; + + // Set light source 1 parameters + l1pos[0] = 0.f; l1pos[1] = -9.f; l1pos[2] = 8.f; l1pos[3] = 1.f; + l1amb[0] = 0.2f; l1amb[1] = 0.2f; l1amb[2] = 0.2f; l1amb[3] = 1.f; + l1dif[0] = 0.8f; l1dif[1] = 0.4f; l1dif[2] = 0.2f; l1dif[3] = 1.f; + l1spec[0] = 1.f; l1spec[1] = 0.6f; l1spec[2] = 0.2f; l1spec[3] = 0.f; + + // Set light source 2 parameters + l2pos[0] = -15.f; l2pos[1] = 12.f; l2pos[2] = 1.5f; l2pos[3] = 1.f; + l2amb[0] = 0.f; l2amb[1] = 0.f; l2amb[2] = 0.f; l2amb[3] = 1.f; + l2dif[0] = 0.2f; l2dif[1] = 0.4f; l2dif[2] = 0.8f; l2dif[3] = 1.f; + l2spec[0] = 0.2f; l2spec[1] = 0.6f; l2spec[2] = 1.f; l2spec[3] = 0.f; + + glLightfv(GL_LIGHT1, GL_POSITION, l1pos); + glLightfv(GL_LIGHT1, GL_AMBIENT, l1amb); + glLightfv(GL_LIGHT1, GL_DIFFUSE, l1dif); + glLightfv(GL_LIGHT1, GL_SPECULAR, l1spec); + glLightfv(GL_LIGHT2, GL_POSITION, l2pos); + glLightfv(GL_LIGHT2, GL_AMBIENT, l2amb); + glLightfv(GL_LIGHT2, GL_DIFFUSE, l2dif); + glLightfv(GL_LIGHT2, GL_SPECULAR, l2spec); + glLightfv(GL_LIGHT3, GL_POSITION, glow_pos); + glLightfv(GL_LIGHT3, GL_DIFFUSE, glow_color); + glLightfv(GL_LIGHT3, GL_SPECULAR, glow_color); + + glEnable(GL_LIGHT1); + glEnable(GL_LIGHT2); + glEnable(GL_LIGHT3); +} + + +//======================================================================== +// Main rendering function +//======================================================================== + +static void draw_scene(GLFWwindow* window, double t) +{ + double xpos, ypos, zpos, angle_x, angle_y, angle_z; + static double t_old = 0.0; + float dt; + mat4x4 projection; + + // Calculate frame-to-frame delta time + dt = (float) (t - t_old); + t_old = t; + + mat4x4_perspective(projection, + 65.f * (float) M_PI / 180.f, + aspect_ratio, + 1.0, 60.0); + + glClearColor(0.1f, 0.1f, 0.1f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((const GLfloat*) projection); + + // Setup camera + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Rotate camera + angle_x = 90.0 - 10.0; + angle_y = 10.0 * sin(0.3 * t); + angle_z = 10.0 * t; + glRotated(-angle_x, 1.0, 0.0, 0.0); + glRotated(-angle_y, 0.0, 1.0, 0.0); + glRotated(-angle_z, 0.0, 0.0, 1.0); + + // Translate camera + xpos = 15.0 * sin((M_PI / 180.0) * angle_z) + + 2.0 * sin((M_PI / 180.0) * 3.1 * t); + ypos = -15.0 * cos((M_PI / 180.0) * angle_z) + + 2.0 * cos((M_PI / 180.0) * 2.9 * t); + zpos = 4.0 + 2.0 * cos((M_PI / 180.0) * 4.9 * t); + glTranslated(-xpos, -ypos, -zpos); + + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + + setup_lights(); + glEnable(GL_LIGHTING); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogf(GL_FOG_DENSITY, 0.05f); + glFogfv(GL_FOG_COLOR, fog_color); + + draw_floor(); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + + draw_fountain(); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + + // Particles must be drawn after all solid objects have been drawn + draw_particles(window, t, dt); + + // Z-buffer not needed anymore + glDisable(GL_DEPTH_TEST); +} + + +//======================================================================== +// Window resize callback function +//======================================================================== + +static void resize_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); + aspect_ratio = height ? width / (float) height : 1.f; +} + + +//======================================================================== +// Key callback functions +//======================================================================== + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action == GLFW_PRESS) + { + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + case GLFW_KEY_W: + wireframe = !wireframe; + glPolygonMode(GL_FRONT_AND_BACK, + wireframe ? GL_LINE : GL_FILL); + break; + default: + break; + } + } +} + + +//======================================================================== +// Thread for updating particle physics +//======================================================================== + +static int physics_thread_main(void* arg) +{ + GLFWwindow* window = arg; + + for (;;) + { + mtx_lock(&thread_sync.particles_lock); + + // Wait for particle drawing to be done + while (!glfwWindowShouldClose(window) && + thread_sync.p_frame > thread_sync.d_frame) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += 100000000; + cnd_timedwait(&thread_sync.d_done, &thread_sync.particles_lock, &ts); + } + + if (glfwWindowShouldClose(window)) + break; + + // Update particles + particle_engine(thread_sync.t, thread_sync.dt); + + // Update frame counter + thread_sync.p_frame++; + + // Unlock mutex and signal drawing thread + mtx_unlock(&thread_sync.particles_lock); + cnd_signal(&thread_sync.p_done); + } + + return 0; +} + + +//======================================================================== +// main +//======================================================================== + +int main(int argc, char** argv) +{ + int ch, width, height; + thrd_t physics_thread = 0; + GLFWwindow* window; + GLFWmonitor* monitor = NULL; + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + while ((ch = getopt(argc, argv, "fh")) != -1) + { + switch (ch) + { + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + case 'h': + usage(); + exit(EXIT_SUCCESS); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + window = glfwCreateWindow(width, height, "Particle Engine", monitor, NULL); + if (!window) + { + fprintf(stderr, "Failed to create GLFW window\n"); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + if (monitor) + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, resize_callback); + glfwSetKeyCallback(window, key_callback); + + // Set initial aspect ratio + glfwGetFramebufferSize(window, &width, &height); + resize_callback(window, width, height); + + // Upload particle texture + glGenTextures(1, &particle_tex_id); + glBindTexture(GL_TEXTURE_2D, particle_tex_id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, P_TEX_WIDTH, P_TEX_HEIGHT, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, particle_texture); + + // Upload floor texture + glGenTextures(1, &floor_tex_id); + glBindTexture(GL_TEXTURE_2D, floor_tex_id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, F_TEX_WIDTH, F_TEX_HEIGHT, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, floor_texture); + + if (glfwExtensionSupported("GL_EXT_separate_specular_color")) + { + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, + GL_SEPARATE_SPECULAR_COLOR_EXT); + } + + // Set filled polygon mode as default (not wireframe) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + wireframe = 0; + + // Set initial times + thread_sync.t = 0.0; + thread_sync.dt = 0.001f; + thread_sync.p_frame = 0; + thread_sync.d_frame = 0; + + mtx_init(&thread_sync.particles_lock, mtx_timed); + cnd_init(&thread_sync.p_done); + cnd_init(&thread_sync.d_done); + + if (thrd_create(&physics_thread, physics_thread_main, window) != thrd_success) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetTime(0.0); + + while (!glfwWindowShouldClose(window)) + { + draw_scene(window, glfwGetTime()); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + thrd_join(physics_thread, NULL); + + glfwDestroyWindow(window); + glfwTerminate(); + + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/examples/simple.c b/extern/glfw-3.2.1/examples/simple.c new file mode 100644 index 0000000..43d11fa --- /dev/null +++ b/extern/glfw-3.2.1/examples/simple.c @@ -0,0 +1,163 @@ +//======================================================================== +// Simple GLFW example +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +//! [code] + +#include +#include + +#include "linmath.h" + +#include +#include + +static const struct +{ + float x, y; + float r, g, b; +} vertices[3] = +{ + { -0.6f, -0.4f, 1.f, 0.f, 0.f }, + { 0.6f, -0.4f, 0.f, 1.f, 0.f }, + { 0.f, 0.6f, 0.f, 0.f, 1.f } +}; + +static const char* vertex_shader_text = +"uniform mat4 MVP;\n" +"attribute vec3 vCol;\n" +"attribute vec2 vPos;\n" +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" +" color = vCol;\n" +"}\n"; + +static const char* fragment_shader_text = +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_FragColor = vec4(color, 1.0);\n" +"}\n"; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +int main(void) +{ + GLFWwindow* window; + GLuint vertex_buffer, vertex_shader, fragment_shader, program; + GLint mvp_location, vpos_location, vcol_location; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + + window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + // NOTE: OpenGL error checks have been omitted for brevity + + glGenBuffers(1, &vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); + glCompileShader(vertex_shader); + + fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); + glCompileShader(fragment_shader); + + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + mvp_location = glGetUniformLocation(program, "MVP"); + vpos_location = glGetAttribLocation(program, "vPos"); + vcol_location = glGetAttribLocation(program, "vCol"); + + glEnableVertexAttribArray(vpos_location); + glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) 0); + glEnableVertexAttribArray(vcol_location); + glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) (sizeof(float) * 2)); + + while (!glfwWindowShouldClose(window)) + { + float ratio; + int width, height; + mat4x4 m, p, mvp; + + glfwGetFramebufferSize(window, &width, &height); + ratio = width / (float) height; + + glViewport(0, 0, width, height); + glClear(GL_COLOR_BUFFER_BIT); + + mat4x4_identity(m); + mat4x4_rotate_Z(m, m, (float) glfwGetTime()); + mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); + mat4x4_mul(mvp, p, m); + + glUseProgram(program); + glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + +//! [code] diff --git a/extern/glfw-3.2.1/examples/splitview.c b/extern/glfw-3.2.1/examples/splitview.c new file mode 100644 index 0000000..12f837d --- /dev/null +++ b/extern/glfw-3.2.1/examples/splitview.c @@ -0,0 +1,545 @@ +//======================================================================== +// This is an example program for the GLFW library +// +// The program uses a "split window" view, rendering four views of the +// same scene in one window (e.g. uesful for 3D modelling software). This +// demo uses scissors to separete the four different rendering areas from +// each other. +// +// (If the code seems a little bit strange here and there, it may be +// because I am not a friend of orthogonal projections) +//======================================================================== + +#include +#include + +#if defined(_MSC_VER) + // Make MS math.h define M_PI + #define _USE_MATH_DEFINES +#endif + +#include +#include +#include + +#include + + +//======================================================================== +// Global variables +//======================================================================== + +// Mouse position +static double xpos = 0, ypos = 0; + +// Window size +static int width, height; + +// Active view: 0 = none, 1 = upper left, 2 = upper right, 3 = lower left, +// 4 = lower right +static int active_view = 0; + +// Rotation around each axis +static int rot_x = 0, rot_y = 0, rot_z = 0; + +// Do redraw? +static int do_redraw = 1; + + +//======================================================================== +// Draw a solid torus (use a display list for the model) +//======================================================================== + +#define TORUS_MAJOR 1.5 +#define TORUS_MINOR 0.5 +#define TORUS_MAJOR_RES 32 +#define TORUS_MINOR_RES 32 + +static void drawTorus(void) +{ + static GLuint torus_list = 0; + int i, j, k; + double s, t, x, y, z, nx, ny, nz, scale, twopi; + + if (!torus_list) + { + // Start recording displaylist + torus_list = glGenLists(1); + glNewList(torus_list, GL_COMPILE_AND_EXECUTE); + + // Draw torus + twopi = 2.0 * M_PI; + for (i = 0; i < TORUS_MINOR_RES; i++) + { + glBegin(GL_QUAD_STRIP); + for (j = 0; j <= TORUS_MAJOR_RES; j++) + { + for (k = 1; k >= 0; k--) + { + s = (i + k) % TORUS_MINOR_RES + 0.5; + t = j % TORUS_MAJOR_RES; + + // Calculate point on surface + x = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * cos(t * twopi / TORUS_MAJOR_RES); + y = TORUS_MINOR * sin(s * twopi / TORUS_MINOR_RES); + z = (TORUS_MAJOR + TORUS_MINOR * cos(s * twopi / TORUS_MINOR_RES)) * sin(t * twopi / TORUS_MAJOR_RES); + + // Calculate surface normal + nx = x - TORUS_MAJOR * cos(t * twopi / TORUS_MAJOR_RES); + ny = y; + nz = z - TORUS_MAJOR * sin(t * twopi / TORUS_MAJOR_RES); + scale = 1.0 / sqrt(nx*nx + ny*ny + nz*nz); + nx *= scale; + ny *= scale; + nz *= scale; + + glNormal3f((float) nx, (float) ny, (float) nz); + glVertex3f((float) x, (float) y, (float) z); + } + } + + glEnd(); + } + + // Stop recording displaylist + glEndList(); + } + else + { + // Playback displaylist + glCallList(torus_list); + } +} + + +//======================================================================== +// Draw the scene (a rotating torus) +//======================================================================== + +static void drawScene(void) +{ + const GLfloat model_diffuse[4] = {1.0f, 0.8f, 0.8f, 1.0f}; + const GLfloat model_specular[4] = {0.6f, 0.6f, 0.6f, 1.0f}; + const GLfloat model_shininess = 20.0f; + + glPushMatrix(); + + // Rotate the object + glRotatef((GLfloat) rot_x * 0.5f, 1.0f, 0.0f, 0.0f); + glRotatef((GLfloat) rot_y * 0.5f, 0.0f, 1.0f, 0.0f); + glRotatef((GLfloat) rot_z * 0.5f, 0.0f, 0.0f, 1.0f); + + // Set model color (used for orthogonal views, lighting disabled) + glColor4fv(model_diffuse); + + // Set model material (used for perspective view, lighting enabled) + glMaterialfv(GL_FRONT, GL_DIFFUSE, model_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, model_specular); + glMaterialf(GL_FRONT, GL_SHININESS, model_shininess); + + // Draw torus + drawTorus(); + + glPopMatrix(); +} + + +//======================================================================== +// Draw a 2D grid (used for orthogonal views) +//======================================================================== + +static void drawGrid(float scale, int steps) +{ + int i; + float x, y; + mat4x4 view; + + glPushMatrix(); + + // Set background to some dark bluish grey + glClearColor(0.05f, 0.05f, 0.2f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Setup modelview matrix (flat XY view) + { + vec3 eye = { 0.f, 0.f, 1.f }; + vec3 center = { 0.f, 0.f, 0.f }; + vec3 up = { 0.f, 1.f, 0.f }; + mat4x4_look_at(view, eye, center, up); + } + glLoadMatrixf((const GLfloat*) view); + + // We don't want to update the Z-buffer + glDepthMask(GL_FALSE); + + // Set grid color + glColor3f(0.0f, 0.5f, 0.5f); + + glBegin(GL_LINES); + + // Horizontal lines + x = scale * 0.5f * (float) (steps - 1); + y = -scale * 0.5f * (float) (steps - 1); + for (i = 0; i < steps; i++) + { + glVertex3f(-x, y, 0.0f); + glVertex3f(x, y, 0.0f); + y += scale; + } + + // Vertical lines + x = -scale * 0.5f * (float) (steps - 1); + y = scale * 0.5f * (float) (steps - 1); + for (i = 0; i < steps; i++) + { + glVertex3f(x, -y, 0.0f); + glVertex3f(x, y, 0.0f); + x += scale; + } + + glEnd(); + + // Enable Z-buffer writing again + glDepthMask(GL_TRUE); + + glPopMatrix(); +} + + +//======================================================================== +// Draw all views +//======================================================================== + +static void drawAllViews(void) +{ + const GLfloat light_position[4] = {0.0f, 8.0f, 8.0f, 1.0f}; + const GLfloat light_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const GLfloat light_specular[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const GLfloat light_ambient[4] = {0.2f, 0.2f, 0.3f, 1.0f}; + float aspect; + mat4x4 view, projection; + + // Calculate aspect of window + if (height > 0) + aspect = (float) width / (float) height; + else + aspect = 1.f; + + // Clear screen + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Enable scissor test + glEnable(GL_SCISSOR_TEST); + + // Enable depth test + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + // ** ORTHOGONAL VIEWS ** + + // For orthogonal views, use wireframe rendering + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + // Enable line anti-aliasing + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Setup orthogonal projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-3.0 * aspect, 3.0 * aspect, -3.0, 3.0, 1.0, 50.0); + + // Upper left view (TOP VIEW) + glViewport(0, height / 2, width / 2, height / 2); + glScissor(0, height / 2, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + { + vec3 eye = { 0.f, 10.f, 1e-3f }; + vec3 center = { 0.f, 0.f, 0.f }; + vec3 up = { 0.f, 1.f, 0.f }; + mat4x4_look_at( view, eye, center, up ); + } + glLoadMatrixf((const GLfloat*) view); + drawGrid(0.5, 12); + drawScene(); + + // Lower left view (FRONT VIEW) + glViewport(0, 0, width / 2, height / 2); + glScissor(0, 0, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + { + vec3 eye = { 0.f, 0.f, 10.f }; + vec3 center = { 0.f, 0.f, 0.f }; + vec3 up = { 0.f, 1.f, 0.f }; + mat4x4_look_at( view, eye, center, up ); + } + glLoadMatrixf((const GLfloat*) view); + drawGrid(0.5, 12); + drawScene(); + + // Lower right view (SIDE VIEW) + glViewport(width / 2, 0, width / 2, height / 2); + glScissor(width / 2, 0, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + { + vec3 eye = { 10.f, 0.f, 0.f }; + vec3 center = { 0.f, 0.f, 0.f }; + vec3 up = { 0.f, 1.f, 0.f }; + mat4x4_look_at( view, eye, center, up ); + } + glLoadMatrixf((const GLfloat*) view); + drawGrid(0.5, 12); + drawScene(); + + // Disable line anti-aliasing + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + + // ** PERSPECTIVE VIEW ** + + // For perspective view, use solid rendering + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // Enable face culling (faster rendering) + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CW); + + // Setup perspective projection matrix + glMatrixMode(GL_PROJECTION); + mat4x4_perspective(projection, + 65.f * (float) M_PI / 180.f, + aspect, + 1.f, 50.f); + glLoadMatrixf((const GLfloat*) projection); + + // Upper right view (PERSPECTIVE VIEW) + glViewport(width / 2, height / 2, width / 2, height / 2); + glScissor(width / 2, height / 2, width / 2, height / 2); + glMatrixMode(GL_MODELVIEW); + { + vec3 eye = { 3.f, 1.5f, 3.f }; + vec3 center = { 0.f, 0.f, 0.f }; + vec3 up = { 0.f, 1.f, 0.f }; + mat4x4_look_at( view, eye, center, up ); + } + glLoadMatrixf((const GLfloat*) view); + + // Configure and enable light source 1 + glLightfv(GL_LIGHT1, GL_POSITION, light_position); + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHTING); + + // Draw scene + drawScene(); + + // Disable lighting + glDisable(GL_LIGHTING); + + // Disable face culling + glDisable(GL_CULL_FACE); + + // Disable depth test + glDisable(GL_DEPTH_TEST); + + // Disable scissor test + glDisable(GL_SCISSOR_TEST); + + // Draw a border around the active view + if (active_view > 0 && active_view != 2) + { + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0, 2.0, 0.0, 2.0, 0.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef((GLfloat) ((active_view - 1) & 1), (GLfloat) (1 - (active_view - 1) / 2), 0.0f); + + glColor3f(1.0f, 1.0f, 0.6f); + + glBegin(GL_LINE_STRIP); + glVertex2i(0, 0); + glVertex2i(1, 0); + glVertex2i(1, 1); + glVertex2i(0, 1); + glVertex2i(0, 0); + glEnd(); + } +} + + +//======================================================================== +// Framebuffer size callback function +//======================================================================== + +static void framebufferSizeFun(GLFWwindow* window, int w, int h) +{ + width = w; + height = h > 0 ? h : 1; + do_redraw = 1; +} + + +//======================================================================== +// Window refresh callback function +//======================================================================== + +static void windowRefreshFun(GLFWwindow* window) +{ + drawAllViews(); + glfwSwapBuffers(window); + do_redraw = 0; +} + + +//======================================================================== +// Mouse position callback function +//======================================================================== + +static void cursorPosFun(GLFWwindow* window, double x, double y) +{ + int wnd_width, wnd_height, fb_width, fb_height; + double scale; + + glfwGetWindowSize(window, &wnd_width, &wnd_height); + glfwGetFramebufferSize(window, &fb_width, &fb_height); + + scale = (double) fb_width / (double) wnd_width; + + x *= scale; + y *= scale; + + // Depending on which view was selected, rotate around different axes + switch (active_view) + { + case 1: + rot_x += (int) (y - ypos); + rot_z += (int) (x - xpos); + do_redraw = 1; + break; + case 3: + rot_x += (int) (y - ypos); + rot_y += (int) (x - xpos); + do_redraw = 1; + break; + case 4: + rot_y += (int) (x - xpos); + rot_z += (int) (y - ypos); + do_redraw = 1; + break; + default: + // Do nothing for perspective view, or if no view is selected + break; + } + + // Remember cursor position + xpos = x; + ypos = y; +} + + +//======================================================================== +// Mouse button callback function +//======================================================================== + +static void mouseButtonFun(GLFWwindow* window, int button, int action, int mods) +{ + if ((button == GLFW_MOUSE_BUTTON_LEFT) && action == GLFW_PRESS) + { + // Detect which of the four views was clicked + active_view = 1; + if (xpos >= width / 2) + active_view += 1; + if (ypos >= height / 2) + active_view += 2; + } + else if (button == GLFW_MOUSE_BUTTON_LEFT) + { + // Deselect any previously selected view + active_view = 0; + } + + do_redraw = 1; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + + +//======================================================================== +// main +//======================================================================== + +int main(void) +{ + GLFWwindow* window; + + // Initialise GLFW + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + glfwWindowHint(GLFW_SAMPLES, 4); + + // Open OpenGL window + window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL); + if (!window) + { + fprintf(stderr, "Failed to open GLFW window\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + // Set callback functions + glfwSetFramebufferSizeCallback(window, framebufferSizeFun); + glfwSetWindowRefreshCallback(window, windowRefreshFun); + glfwSetCursorPosCallback(window, cursorPosFun); + glfwSetMouseButtonCallback(window, mouseButtonFun); + glfwSetKeyCallback(window, key_callback); + + // Enable vsync + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + if (GLAD_GL_ARB_multisample || GLAD_GL_VERSION_1_3) + glEnable(GL_MULTISAMPLE_ARB); + + glfwGetFramebufferSize(window, &width, &height); + framebufferSizeFun(window, width, height); + + // Main loop + for (;;) + { + // Only redraw if we need to + if (do_redraw) + windowRefreshFun(window); + + // Wait for new events + glfwWaitEvents(); + + // Check if the window should be closed + if (glfwWindowShouldClose(window)) + break; + } + + // Close OpenGL window and terminate GLFW + glfwTerminate(); + + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/examples/wave.c b/extern/glfw-3.2.1/examples/wave.c new file mode 100644 index 0000000..c4c4d91 --- /dev/null +++ b/extern/glfw-3.2.1/examples/wave.c @@ -0,0 +1,460 @@ +/***************************************************************************** + * Wave Simulation in OpenGL + * (C) 2002 Jakob Thomsen + * http://home.in.tum.de/~thomsen + * Modified for GLFW by Sylvain Hellegouarch - sh@programmationworld.com + * Modified for variable frame rate by Marcus Geelnard + * 2003-Jan-31: Minor cleanups and speedups / MG + * 2010-10-24: Formatting and cleanup - Camilla Berglund + *****************************************************************************/ + +#if defined(_MSC_VER) + // Make MS math.h define M_PI + #define _USE_MATH_DEFINES +#endif + +#include +#include +#include + +#include +#include + +#include + +// Maximum delta T to allow for differential calculations +#define MAX_DELTA_T 0.01 + +// Animation speed (10.0 looks good) +#define ANIMATION_SPEED 10.0 + +GLfloat alpha = 210.f, beta = -70.f; +GLfloat zoom = 2.f; + +double cursorX; +double cursorY; + +struct Vertex +{ + GLfloat x, y, z; + GLfloat r, g, b; +}; + +#define GRIDW 50 +#define GRIDH 50 +#define VERTEXNUM (GRIDW*GRIDH) + +#define QUADW (GRIDW - 1) +#define QUADH (GRIDH - 1) +#define QUADNUM (QUADW*QUADH) + +GLuint quad[4 * QUADNUM]; +struct Vertex vertex[VERTEXNUM]; + +/* The grid will look like this: + * + * 3 4 5 + * *---*---* + * | | | + * | 0 | 1 | + * | | | + * *---*---* + * 0 1 2 + */ + +//======================================================================== +// Initialize grid geometry +//======================================================================== + +void init_vertices(void) +{ + int x, y, p; + + // Place the vertices in a grid + for (y = 0; y < GRIDH; y++) + { + for (x = 0; x < GRIDW; x++) + { + p = y * GRIDW + x; + + vertex[p].x = (GLfloat) (x - GRIDW / 2) / (GLfloat) (GRIDW / 2); + vertex[p].y = (GLfloat) (y - GRIDH / 2) / (GLfloat) (GRIDH / 2); + vertex[p].z = 0; + + if ((x % 4 < 2) ^ (y % 4 < 2)) + vertex[p].r = 0.0; + else + vertex[p].r = 1.0; + + vertex[p].g = (GLfloat) y / (GLfloat) GRIDH; + vertex[p].b = 1.f - ((GLfloat) x / (GLfloat) GRIDW + (GLfloat) y / (GLfloat) GRIDH) / 2.f; + } + } + + for (y = 0; y < QUADH; y++) + { + for (x = 0; x < QUADW; x++) + { + p = 4 * (y * QUADW + x); + + quad[p + 0] = y * GRIDW + x; // Some point + quad[p + 1] = y * GRIDW + x + 1; // Neighbor at the right side + quad[p + 2] = (y + 1) * GRIDW + x + 1; // Upper right neighbor + quad[p + 3] = (y + 1) * GRIDW + x; // Upper neighbor + } + } +} + +double dt; +double p[GRIDW][GRIDH]; +double vx[GRIDW][GRIDH], vy[GRIDW][GRIDH]; +double ax[GRIDW][GRIDH], ay[GRIDW][GRIDH]; + +//======================================================================== +// Initialize grid +//======================================================================== + +void init_grid(void) +{ + int x, y; + double dx, dy, d; + + for (y = 0; y < GRIDH; y++) + { + for (x = 0; x < GRIDW; x++) + { + dx = (double) (x - GRIDW / 2); + dy = (double) (y - GRIDH / 2); + d = sqrt(dx * dx + dy * dy); + if (d < 0.1 * (double) (GRIDW / 2)) + { + d = d * 10.0; + p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0; + } + else + p[x][y] = 0.0; + + vx[x][y] = 0.0; + vy[x][y] = 0.0; + } + } +} + + +//======================================================================== +// Draw scene +//======================================================================== + +void draw_scene(GLFWwindow* window) +{ + // Clear the color and depth buffers + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // We don't want to modify the projection matrix + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Move back + glTranslatef(0.0, 0.0, -zoom); + // Rotate the view + glRotatef(beta, 1.0, 0.0, 0.0); + glRotatef(alpha, 0.0, 0.0, 1.0); + + glDrawElements(GL_QUADS, 4 * QUADNUM, GL_UNSIGNED_INT, quad); + + glfwSwapBuffers(window); +} + + +//======================================================================== +// Initialize Miscellaneous OpenGL state +//======================================================================== + +void init_opengl(void) +{ + // Use Gouraud (smooth) shading + glShadeModel(GL_SMOOTH); + + // Switch on the z-buffer + glEnable(GL_DEPTH_TEST); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), vertex); + glColorPointer(3, GL_FLOAT, sizeof(struct Vertex), &vertex[0].r); // Pointer to the first color + + glPointSize(2.0); + + // Background color is black + glClearColor(0, 0, 0, 0); +} + + +//======================================================================== +// Modify the height of each vertex according to the pressure +//======================================================================== + +void adjust_grid(void) +{ + int pos; + int x, y; + + for (y = 0; y < GRIDH; y++) + { + for (x = 0; x < GRIDW; x++) + { + pos = y * GRIDW + x; + vertex[pos].z = (float) (p[x][y] * (1.0 / 50.0)); + } + } +} + + +//======================================================================== +// Calculate wave propagation +//======================================================================== + +void calc_grid(void) +{ + int x, y, x2, y2; + double time_step = dt * ANIMATION_SPEED; + + // Compute accelerations + for (x = 0; x < GRIDW; x++) + { + x2 = (x + 1) % GRIDW; + for(y = 0; y < GRIDH; y++) + ax[x][y] = p[x][y] - p[x2][y]; + } + + for (y = 0; y < GRIDH; y++) + { + y2 = (y + 1) % GRIDH; + for(x = 0; x < GRIDW; x++) + ay[x][y] = p[x][y] - p[x][y2]; + } + + // Compute speeds + for (x = 0; x < GRIDW; x++) + { + for (y = 0; y < GRIDH; y++) + { + vx[x][y] = vx[x][y] + ax[x][y] * time_step; + vy[x][y] = vy[x][y] + ay[x][y] * time_step; + } + } + + // Compute pressure + for (x = 1; x < GRIDW; x++) + { + x2 = x - 1; + for (y = 1; y < GRIDH; y++) + { + y2 = y - 1; + p[x][y] = p[x][y] + (vx[x2][y] - vx[x][y] + vy[x][y2] - vy[x][y]) * time_step; + } + } +} + + +//======================================================================== +// Print errors +//======================================================================== + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + + +//======================================================================== +// Handle key strokes +//======================================================================== + +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + case GLFW_KEY_SPACE: + init_grid(); + break; + case GLFW_KEY_LEFT: + alpha += 5; + break; + case GLFW_KEY_RIGHT: + alpha -= 5; + break; + case GLFW_KEY_UP: + beta -= 5; + break; + case GLFW_KEY_DOWN: + beta += 5; + break; + case GLFW_KEY_PAGE_UP: + zoom -= 0.25f; + if (zoom < 0.f) + zoom = 0.f; + break; + case GLFW_KEY_PAGE_DOWN: + zoom += 0.25f; + break; + default: + break; + } +} + + +//======================================================================== +// Callback function for mouse button events +//======================================================================== + +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + if (button != GLFW_MOUSE_BUTTON_LEFT) + return; + + if (action == GLFW_PRESS) + { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwGetCursorPos(window, &cursorX, &cursorY); + } + else + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); +} + + +//======================================================================== +// Callback function for cursor motion events +//======================================================================== + +void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) + { + alpha += (GLfloat) (x - cursorX) / 10.f; + beta += (GLfloat) (y - cursorY) / 10.f; + + cursorX = x; + cursorY = y; + } +} + + +//======================================================================== +// Callback function for scroll events +//======================================================================== + +void scroll_callback(GLFWwindow* window, double x, double y) +{ + zoom += (float) y / 4.f; + if (zoom < 0) + zoom = 0; +} + + +//======================================================================== +// Callback function for framebuffer resize events +//======================================================================== + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + float ratio = 1.f; + mat4x4 projection; + + if (height > 0) + ratio = (float) width / (float) height; + + // Setup viewport + glViewport(0, 0, width, height); + + // Change to the projection matrix and set our viewing volume + glMatrixMode(GL_PROJECTION); + mat4x4_perspective(projection, + 60.f * (float) M_PI / 180.f, + ratio, + 1.f, 1024.f); + glLoadMatrixf((const GLfloat*) projection); +} + + +//======================================================================== +// main +//======================================================================== + +int main(int argc, char* argv[]) +{ + GLFWwindow* window; + double t, dt_total, t_old; + int width, height; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); + glfwSetCursorPosCallback(window, cursor_position_callback); + glfwSetScrollCallback(window, scroll_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwGetFramebufferSize(window, &width, &height); + framebuffer_size_callback(window, width, height); + + // Initialize OpenGL + init_opengl(); + + // Initialize simulation + init_vertices(); + init_grid(); + adjust_grid(); + + // Initialize timer + t_old = glfwGetTime() - 0.01; + + while (!glfwWindowShouldClose(window)) + { + t = glfwGetTime(); + dt_total = t - t_old; + t_old = t; + + // Safety - iterate if dt_total is too large + while (dt_total > 0.f) + { + // Select iteration time step + dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total; + dt_total -= dt; + + // Calculate wave propagation + calc_grid(); + } + + // Compute height of each vertex + adjust_grid(); + + // Draw wave grid to OpenGL display + draw_scene(window); + + glfwPollEvents(); + } + + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/include/GLFW/glfw3.h b/extern/glfw-3.2.1/include/GLFW/glfw3.h new file mode 100644 index 0000000..95caa95 --- /dev/null +++ b/extern/glfw-3.2.1/include/GLFW/glfw3.h @@ -0,0 +1,4248 @@ +/************************************************************************* + * 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 + * + * 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 */ + +/* Include because most Windows GLU headers need wchar_t and + * the OS X OpenGL header blocks the definition of ptrdiff_t by glext.h. + * Include it unconditionally to avoid surprising side-effects. + */ +#include + +/* Include because it is needed by Vulkan and related functions. + */ +#include + +/* Include the chosen client API headers. + */ +#if defined(__APPLE__) + #if defined(GLFW_INCLUDE_GLCOREARB) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif !defined(GLFW_INCLUDE_NONE) + #if !defined(GLFW_INCLUDE_GLEXT) + #define GL_GLEXT_LEGACY + #endif + #include + #endif + #if defined(GLFW_INCLUDE_GLU) + #include + #endif +#else + #if defined(GLFW_INCLUDE_GLCOREARB) + #include + #elif defined(GLFW_INCLUDE_ES1) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_ES2) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_ES3) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_ES31) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #elif defined(GLFW_INCLUDE_VULKAN) + #include + #elif !defined(GLFW_INCLUDE_NONE) + #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif + #endif + #if defined(GLFW_INCLUDE_GLU) + #include + #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 1 +/*! @} */ + +/*! @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 + * @sa @ref window_icon + * + * @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. + * + * Once you have created the window, you can switch it between windowed and + * full screen mode with @ref glfwSetWindowMonitor. If the window has an + * OpenGL or OpenGL ES context, it will be unaffected. + * + * 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](@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 + * + * @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 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 + * 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 + * @sa glfwWaitEventsTimeout + * + * @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](@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 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 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. + * + * @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 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. + * + * @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 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. + * + * @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((264 - 1) / 109) 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 / 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/extern/glfw-3.2.1/include/GLFW/glfw3native.h b/extern/glfw-3.2.1/include/GLFW/glfw3native.h new file mode 100644 index 0000000..30e1a57 --- /dev/null +++ b/extern/glfw-3.2.1/include/GLFW/glfw3native.h @@ -0,0 +1,456 @@ +/************************************************************************* + * 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 + * + * 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 +#elif defined(GLFW_EXPOSE_NATIVE_COCOA) + #include + #if defined(__OBJC__) + #import + #else + typedef void* id; + #endif +#elif defined(GLFW_EXPOSE_NATIVE_X11) + #include + #include +#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include +#elif defined(GLFW_EXPOSE_NATIVE_MIR) + #include +#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 +#endif +#if defined(GLFW_EXPOSE_NATIVE_EGL) + #include +#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/extern/glfw-3.2.1/src/CMakeLists.txt b/extern/glfw-3.2.1/src/CMakeLists.txt new file mode 100644 index 0000000..5042aba --- /dev/null +++ b/extern/glfw-3.2.1/src/CMakeLists.txt @@ -0,0 +1,120 @@ + +set(common_HEADERS internal.h + "${GLFW_BINARY_DIR}/src/glfw_config.h" + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" + "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") +set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c) + +if (_GLFW_COCOA) + set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h + posix_tls.h nsgl_context.h) + set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m + cocoa_monitor.m cocoa_window.m cocoa_time.c posix_tls.c + nsgl_context.m) +elseif (_GLFW_WIN32) + set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h + wgl_context.h egl_context.h) + set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c + win32_monitor.c win32_time.c win32_tls.c win32_window.c + wgl_context.c egl_context.c) +elseif (_GLFW_X11) + set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h + linux_joystick.h posix_time.h posix_tls.h glx_context.h + egl_context.h) + set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c + xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c + glx_context.c egl_context.c) +elseif (_GLFW_WAYLAND) + set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h + posix_time.h posix_tls.h xkb_unicode.h egl_context.h) + set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c + linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c + egl_context.c) + + ecm_add_wayland_client_protocol(glfw_SOURCES + PROTOCOL + ${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml + BASENAME relative-pointer-unstable-v1) + ecm_add_wayland_client_protocol(glfw_SOURCES + PROTOCOL + ${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml + BASENAME pointer-constraints-unstable-v1) +elseif (_GLFW_MIR) + set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h + posix_time.h posix_tls.h xkb_unicode.h egl_context.h) + set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c + linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c + egl_context.c) +endif() + +if (APPLE) + # For some reason, CMake doesn't know about .m + set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) +endif() + +add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) +set_target_properties(glfw PROPERTIES + OUTPUT_NAME ${GLFW_LIB_NAME} + VERSION ${GLFW_VERSION} + SOVERSION ${GLFW_VERSION_MAJOR} + POSITION_INDEPENDENT_CODE ON + FOLDER "GLFW3") + +target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H) +target_include_directories(glfw PUBLIC + $ + $/include>) +target_include_directories(glfw PRIVATE + "${GLFW_SOURCE_DIR}/src" + "${GLFW_BINARY_DIR}/src" + ${glfw_INCLUDE_DIRS}) + +# HACK: When building on MinGW, WINVER and UNICODE need to be defined before +# the inclusion of stddef.h (by glfw3.h), which is itself included before +# win32_platform.h. We define them here until a saner solution can be found +# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack. +target_compile_definitions(glfw PRIVATE + "$<$:UNICODE;WINVER=0x0501>") + +# Enable a reasonable set of warnings (no, -Wextra is not reasonable) +target_compile_options(glfw PRIVATE + "$<$:-Wall>" + "$<$:-Wall>") + +if (BUILD_SHARED_LIBS) + if (WIN32) + if (MINGW) + # Remove the lib prefix on the DLL (but not the import library + set_target_properties(glfw PROPERTIES PREFIX "") + + # Add a suffix to the import library to avoid naming conflicts + set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") + else() + # Add a suffix to the import library to avoid naming conflicts + set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") + endif() + elseif (APPLE) + # Add -fno-common to work around a bug in Apple's GCC + target_compile_options(glfw PRIVATE "-fno-common") + + set_target_properties(glfw PROPERTIES + INSTALL_NAME_DIR "lib${LIB_SUFFIX}") + elseif (UNIX) + # Hide symbols not explicitly tagged for export from the shared library + target_compile_options(glfw PRIVATE "-fvisibility=hidden") + endif() + + target_compile_definitions(glfw INTERFACE -DGLFW_DLL) + target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES}) +else() + target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES}) +endif() + +if (MSVC) + target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) +endif() + +if (GLFW_INSTALL) + install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) +endif() + diff --git a/extern/glfw-3.2.1/src/cocoa_init.m b/extern/glfw-3.2.1/src/cocoa_init.m new file mode 100644 index 0000000..f10d638 --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_init.m @@ -0,0 +1,398 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// +// 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 // For MAXPATHLEN + + +#if defined(_GLFW_USE_CHDIR) + +// 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); +} + +#endif /* _GLFW_USE_CHDIR */ + +// Create key code translation tables +// +static void createKeyTables(void) +{ + int scancode; + + memset(_glfw.ns.publicKeys, -1, sizeof(_glfw.ns.publicKeys)); + memset(_glfw.ns.nativeKeys, -1, sizeof(_glfw.ns.nativeKeys)); + + _glfw.ns.publicKeys[0x1D] = GLFW_KEY_0; + _glfw.ns.publicKeys[0x12] = GLFW_KEY_1; + _glfw.ns.publicKeys[0x13] = GLFW_KEY_2; + _glfw.ns.publicKeys[0x14] = GLFW_KEY_3; + _glfw.ns.publicKeys[0x15] = GLFW_KEY_4; + _glfw.ns.publicKeys[0x17] = GLFW_KEY_5; + _glfw.ns.publicKeys[0x16] = GLFW_KEY_6; + _glfw.ns.publicKeys[0x1A] = GLFW_KEY_7; + _glfw.ns.publicKeys[0x1C] = GLFW_KEY_8; + _glfw.ns.publicKeys[0x19] = GLFW_KEY_9; + _glfw.ns.publicKeys[0x00] = GLFW_KEY_A; + _glfw.ns.publicKeys[0x0B] = GLFW_KEY_B; + _glfw.ns.publicKeys[0x08] = GLFW_KEY_C; + _glfw.ns.publicKeys[0x02] = GLFW_KEY_D; + _glfw.ns.publicKeys[0x0E] = GLFW_KEY_E; + _glfw.ns.publicKeys[0x03] = GLFW_KEY_F; + _glfw.ns.publicKeys[0x05] = GLFW_KEY_G; + _glfw.ns.publicKeys[0x04] = GLFW_KEY_H; + _glfw.ns.publicKeys[0x22] = GLFW_KEY_I; + _glfw.ns.publicKeys[0x26] = GLFW_KEY_J; + _glfw.ns.publicKeys[0x28] = GLFW_KEY_K; + _glfw.ns.publicKeys[0x25] = GLFW_KEY_L; + _glfw.ns.publicKeys[0x2E] = GLFW_KEY_M; + _glfw.ns.publicKeys[0x2D] = GLFW_KEY_N; + _glfw.ns.publicKeys[0x1F] = GLFW_KEY_O; + _glfw.ns.publicKeys[0x23] = GLFW_KEY_P; + _glfw.ns.publicKeys[0x0C] = GLFW_KEY_Q; + _glfw.ns.publicKeys[0x0F] = GLFW_KEY_R; + _glfw.ns.publicKeys[0x01] = GLFW_KEY_S; + _glfw.ns.publicKeys[0x11] = GLFW_KEY_T; + _glfw.ns.publicKeys[0x20] = GLFW_KEY_U; + _glfw.ns.publicKeys[0x09] = GLFW_KEY_V; + _glfw.ns.publicKeys[0x0D] = GLFW_KEY_W; + _glfw.ns.publicKeys[0x07] = GLFW_KEY_X; + _glfw.ns.publicKeys[0x10] = GLFW_KEY_Y; + _glfw.ns.publicKeys[0x06] = GLFW_KEY_Z; + + _glfw.ns.publicKeys[0x27] = GLFW_KEY_APOSTROPHE; + _glfw.ns.publicKeys[0x2A] = GLFW_KEY_BACKSLASH; + _glfw.ns.publicKeys[0x2B] = GLFW_KEY_COMMA; + _glfw.ns.publicKeys[0x18] = GLFW_KEY_EQUAL; + _glfw.ns.publicKeys[0x32] = GLFW_KEY_GRAVE_ACCENT; + _glfw.ns.publicKeys[0x21] = GLFW_KEY_LEFT_BRACKET; + _glfw.ns.publicKeys[0x1B] = GLFW_KEY_MINUS; + _glfw.ns.publicKeys[0x2F] = GLFW_KEY_PERIOD; + _glfw.ns.publicKeys[0x1E] = GLFW_KEY_RIGHT_BRACKET; + _glfw.ns.publicKeys[0x29] = GLFW_KEY_SEMICOLON; + _glfw.ns.publicKeys[0x2C] = GLFW_KEY_SLASH; + _glfw.ns.publicKeys[0x0A] = GLFW_KEY_WORLD_1; + + _glfw.ns.publicKeys[0x33] = GLFW_KEY_BACKSPACE; + _glfw.ns.publicKeys[0x39] = GLFW_KEY_CAPS_LOCK; + _glfw.ns.publicKeys[0x75] = GLFW_KEY_DELETE; + _glfw.ns.publicKeys[0x7D] = GLFW_KEY_DOWN; + _glfw.ns.publicKeys[0x77] = GLFW_KEY_END; + _glfw.ns.publicKeys[0x24] = GLFW_KEY_ENTER; + _glfw.ns.publicKeys[0x35] = GLFW_KEY_ESCAPE; + _glfw.ns.publicKeys[0x7A] = GLFW_KEY_F1; + _glfw.ns.publicKeys[0x78] = GLFW_KEY_F2; + _glfw.ns.publicKeys[0x63] = GLFW_KEY_F3; + _glfw.ns.publicKeys[0x76] = GLFW_KEY_F4; + _glfw.ns.publicKeys[0x60] = GLFW_KEY_F5; + _glfw.ns.publicKeys[0x61] = GLFW_KEY_F6; + _glfw.ns.publicKeys[0x62] = GLFW_KEY_F7; + _glfw.ns.publicKeys[0x64] = GLFW_KEY_F8; + _glfw.ns.publicKeys[0x65] = GLFW_KEY_F9; + _glfw.ns.publicKeys[0x6D] = GLFW_KEY_F10; + _glfw.ns.publicKeys[0x67] = GLFW_KEY_F11; + _glfw.ns.publicKeys[0x6F] = GLFW_KEY_F12; + _glfw.ns.publicKeys[0x69] = GLFW_KEY_F13; + _glfw.ns.publicKeys[0x6B] = GLFW_KEY_F14; + _glfw.ns.publicKeys[0x71] = GLFW_KEY_F15; + _glfw.ns.publicKeys[0x6A] = GLFW_KEY_F16; + _glfw.ns.publicKeys[0x40] = GLFW_KEY_F17; + _glfw.ns.publicKeys[0x4F] = GLFW_KEY_F18; + _glfw.ns.publicKeys[0x50] = GLFW_KEY_F19; + _glfw.ns.publicKeys[0x5A] = GLFW_KEY_F20; + _glfw.ns.publicKeys[0x73] = GLFW_KEY_HOME; + _glfw.ns.publicKeys[0x72] = GLFW_KEY_INSERT; + _glfw.ns.publicKeys[0x7B] = GLFW_KEY_LEFT; + _glfw.ns.publicKeys[0x3A] = GLFW_KEY_LEFT_ALT; + _glfw.ns.publicKeys[0x3B] = GLFW_KEY_LEFT_CONTROL; + _glfw.ns.publicKeys[0x38] = GLFW_KEY_LEFT_SHIFT; + _glfw.ns.publicKeys[0x37] = GLFW_KEY_LEFT_SUPER; + _glfw.ns.publicKeys[0x6E] = GLFW_KEY_MENU; + _glfw.ns.publicKeys[0x47] = GLFW_KEY_NUM_LOCK; + _glfw.ns.publicKeys[0x79] = GLFW_KEY_PAGE_DOWN; + _glfw.ns.publicKeys[0x74] = GLFW_KEY_PAGE_UP; + _glfw.ns.publicKeys[0x7C] = GLFW_KEY_RIGHT; + _glfw.ns.publicKeys[0x3D] = GLFW_KEY_RIGHT_ALT; + _glfw.ns.publicKeys[0x3E] = GLFW_KEY_RIGHT_CONTROL; + _glfw.ns.publicKeys[0x3C] = GLFW_KEY_RIGHT_SHIFT; + _glfw.ns.publicKeys[0x36] = GLFW_KEY_RIGHT_SUPER; + _glfw.ns.publicKeys[0x31] = GLFW_KEY_SPACE; + _glfw.ns.publicKeys[0x30] = GLFW_KEY_TAB; + _glfw.ns.publicKeys[0x7E] = GLFW_KEY_UP; + + _glfw.ns.publicKeys[0x52] = GLFW_KEY_KP_0; + _glfw.ns.publicKeys[0x53] = GLFW_KEY_KP_1; + _glfw.ns.publicKeys[0x54] = GLFW_KEY_KP_2; + _glfw.ns.publicKeys[0x55] = GLFW_KEY_KP_3; + _glfw.ns.publicKeys[0x56] = GLFW_KEY_KP_4; + _glfw.ns.publicKeys[0x57] = GLFW_KEY_KP_5; + _glfw.ns.publicKeys[0x58] = GLFW_KEY_KP_6; + _glfw.ns.publicKeys[0x59] = GLFW_KEY_KP_7; + _glfw.ns.publicKeys[0x5B] = GLFW_KEY_KP_8; + _glfw.ns.publicKeys[0x5C] = GLFW_KEY_KP_9; + _glfw.ns.publicKeys[0x45] = GLFW_KEY_KP_ADD; + _glfw.ns.publicKeys[0x41] = GLFW_KEY_KP_DECIMAL; + _glfw.ns.publicKeys[0x4B] = GLFW_KEY_KP_DIVIDE; + _glfw.ns.publicKeys[0x4C] = GLFW_KEY_KP_ENTER; + _glfw.ns.publicKeys[0x51] = GLFW_KEY_KP_EQUAL; + _glfw.ns.publicKeys[0x43] = GLFW_KEY_KP_MULTIPLY; + _glfw.ns.publicKeys[0x4E] = GLFW_KEY_KP_SUBTRACT; + + for (scancode = 0; scancode < 256; scancode++) + { + // Store the reverse translation for faster key name lookup + if (_glfw.ns.publicKeys[scancode] >= 0) + _glfw.ns.nativeKeys[_glfw.ns.publicKeys[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")); + CFStringRef* kNotifySelectedKeyboardInputSourceChanged = + CFBundleGetDataPointerForName(_glfw.ns.tis.bundle, + CFSTR("kTISNotifySelectedKeyboardInputSourceChanged")); + _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 || + !kNotifySelectedKeyboardInputSourceChanged || + !TISCopyCurrentKeyboardLayoutInputSource || + !TISGetInputSourceProperty || + !LMGetKbdType) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to load TIS API symbols"); + return GLFW_FALSE; + } + + _glfw.ns.tis.kPropertyUnicodeKeyLayoutData = + *kPropertyUnicodeKeyLayoutData; + _glfw.ns.tis.kNotifySelectedKeyboardInputSourceChanged = + *kNotifySelectedKeyboardInputSourceChanged; + + 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]; + + _glfw.ns.listener = [[GLFWLayoutListener alloc] init]; + [[NSDistributedNotificationCenter defaultCenter] + addObserver:_glfw.ns.listener + selector:@selector(selectedKeyboardInputSourceChanged:) + name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged + object:nil]; + +#if defined(_GLFW_USE_CHDIR) + changeToResourcesDirectory(); +#endif + + createKeyTables(); + + _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + if (!_glfw.ns.eventSource) + return GLFW_FALSE; + + CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); + + if (!initializeTIS()) + return GLFW_FALSE; + + if (!_glfwInitThreadLocalStoragePOSIX()) + return GLFW_FALSE; + + _glfwInitTimerNS(); + _glfwInitJoysticksNS(); + + 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) + { + [[NSDistributedNotificationCenter defaultCenter] + removeObserver:_glfw.ns.listener + name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged + object:nil]; + [[NSDistributedNotificationCenter defaultCenter] + removeObserver:_glfw.ns.listener]; + [_glfw.ns.listener release]; + _glfw.ns.listener = nil; + } + + [_glfw.ns.cursor release]; + _glfw.ns.cursor = nil; + + free(_glfw.ns.clipboardString); + + _glfwTerminateNSGL(); + _glfwTerminateJoysticksNS(); + _glfwTerminateThreadLocalStoragePOSIX(); + + [_glfw.ns.autoreleasePool release]; + _glfw.ns.autoreleasePool = nil; +} + +const char* _glfwPlatformGetVersionString(void) +{ + return _GLFW_VERSION_NUMBER " Cocoa NSGL" +#if defined(_GLFW_USE_CHDIR) + " chdir" +#endif +#if defined(_GLFW_USE_MENUBAR) + " menubar" +#endif +#if defined(_GLFW_USE_RETINA) + " retina" +#endif +#if defined(_GLFW_BUILD_DLL) + " dynamic" +#endif + ; +} + diff --git a/extern/glfw-3.2.1/src/cocoa_joystick.h b/extern/glfw-3.2.1/src/cocoa_joystick.h new file mode 100644 index 0000000..3b80634 --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_joystick.h @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW 3.2 Cocoa - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_cocoa_joystick_h_ +#define _glfw3_cocoa_joystick_h_ + +#include +#include +#include +#include + +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ + _GLFWjoystickNS ns_js[GLFW_JOYSTICK_LAST + 1] + + +// Cocoa-specific per-joystick data +// +typedef struct _GLFWjoystickNS +{ + GLFWbool present; + char name[256]; + + IOHIDDeviceRef deviceRef; + + CFMutableArrayRef axisElements; + CFMutableArrayRef buttonElements; + CFMutableArrayRef hatElements; + + float* axes; + unsigned char* buttons; +} _GLFWjoystickNS; + + +void _glfwInitJoysticksNS(void); +void _glfwTerminateJoysticksNS(void); + +#endif // _glfw3_cocoa_joystick_h_ diff --git a/extern/glfw-3.2.1/src/cocoa_joystick.m b/extern/glfw-3.2.1/src/cocoa_joystick.m new file mode 100644 index 0000000..7423e3d --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_joystick.m @@ -0,0 +1,511 @@ +//======================================================================== +// GLFW 3.2 Cocoa - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// Copyright (c) 2012 Torsten Walluhn +// +// 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 +#include +#include + +#include +#include + +#include +#include + + +// Joystick element information +// +typedef struct _GLFWjoyelementNS +{ + IOHIDElementRef elementRef; + + long min; + long max; + + long minReport; + long maxReport; + +} _GLFWjoyelementNS; + + +static void getElementsCFArrayHandler(const void* value, void* parameter); + +// Adds an element to the specified joystick +// +static void addJoystickElement(_GLFWjoystickNS* js, + IOHIDElementRef elementRef) +{ + IOHIDElementType elementType; + long usagePage, usage; + CFMutableArrayRef elementsArray = NULL; + + elementType = IOHIDElementGetType(elementRef); + usagePage = IOHIDElementGetUsagePage(elementRef); + usage = IOHIDElementGetUsage(elementRef); + + if ((elementType != kIOHIDElementTypeInput_Axis) && + (elementType != kIOHIDElementTypeInput_Button) && + (elementType != kIOHIDElementTypeInput_Misc)) + { + return; + } + + switch (usagePage) + { + case 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: + elementsArray = js->axisElements; + break; + case kHIDUsage_GD_Hatswitch: + elementsArray = js->hatElements; + break; + } + + break; + } + + case kHIDPage_Button: + elementsArray = js->buttonElements; + break; + default: + break; + } + + if (elementsArray) + { + _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS)); + + CFArrayAppendValue(elementsArray, element); + + element->elementRef = elementRef; + + element->minReport = IOHIDElementGetLogicalMin(elementRef); + element->maxReport = IOHIDElementGetLogicalMax(elementRef); + } +} + +// Adds an element to the specified joystick +// +static void getElementsCFArrayHandler(const void* value, void* parameter) +{ + if (CFGetTypeID(value) == IOHIDElementGetTypeID()) + { + addJoystickElement((_GLFWjoystickNS*) parameter, + (IOHIDElementRef) value); + } +} + +// Returns the value of the specified element of the specified joystick +// +static long getElementValue(_GLFWjoystickNS* js, _GLFWjoyelementNS* element) +{ + IOReturn result = kIOReturnSuccess; + IOHIDValueRef valueRef; + long value = 0; + + if (js && element && js->deviceRef) + { + result = IOHIDDeviceGetValue(js->deviceRef, + element->elementRef, + &valueRef); + + if (kIOReturnSuccess == result) + { + value = IOHIDValueGetIntegerValue(valueRef); + + // Record min and max for auto calibration + if (value < element->minReport) + element->minReport = value; + if (value > element->maxReport) + element->maxReport = value; + } + } + + // Auto user scale + return value; +} + +// Removes the specified joystick +// +static void removeJoystick(_GLFWjoystickNS* js) +{ + int i; + + if (!js->present) + return; + + for (i = 0; i < CFArrayGetCount(js->axisElements); i++) + free((void*) CFArrayGetValueAtIndex(js->axisElements, i)); + CFArrayRemoveAllValues(js->axisElements); + CFRelease(js->axisElements); + + for (i = 0; i < CFArrayGetCount(js->buttonElements); i++) + free((void*) CFArrayGetValueAtIndex(js->buttonElements, i)); + CFArrayRemoveAllValues(js->buttonElements); + CFRelease(js->buttonElements); + + for (i = 0; i < CFArrayGetCount(js->hatElements); i++) + free((void*) CFArrayGetValueAtIndex(js->hatElements, i)); + CFArrayRemoveAllValues(js->hatElements); + CFRelease(js->hatElements); + + free(js->axes); + free(js->buttons); + + memset(js, 0, sizeof(_GLFWjoystickNS)); + + _glfwInputJoystickChange(js - _glfw.ns_js, GLFW_DISCONNECTED); +} + +// Polls for joystick axis events and updates GLFW state +// +static GLFWbool pollJoystickAxisEvents(_GLFWjoystickNS* js) +{ + CFIndex i; + + if (!js->present) + return GLFW_FALSE; + + for (i = 0; i < CFArrayGetCount(js->axisElements); i++) + { + _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*) + CFArrayGetValueAtIndex(js->axisElements, i); + + long value = getElementValue(js, axis); + long readScale = axis->maxReport - axis->minReport; + + if (readScale == 0) + js->axes[i] = value; + else + js->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f; + } + + return GLFW_TRUE; +} + +// Polls for joystick button events and updates GLFW state +// +static GLFWbool pollJoystickButtonEvents(_GLFWjoystickNS* js) +{ + CFIndex i; + int buttonIndex = 0; + + if (!js->present) + return GLFW_FALSE; + + for (i = 0; i < CFArrayGetCount(js->buttonElements); i++) + { + _GLFWjoyelementNS* button = (_GLFWjoyelementNS*) + CFArrayGetValueAtIndex(js->buttonElements, i); + + if (getElementValue(js, button)) + js->buttons[buttonIndex++] = GLFW_PRESS; + else + js->buttons[buttonIndex++] = GLFW_RELEASE; + } + + for (i = 0; i < CFArrayGetCount(js->hatElements); i++) + { + _GLFWjoyelementNS* hat = (_GLFWjoyelementNS*) + CFArrayGetValueAtIndex(js->hatElements, i); + + // Bit fields of button presses for each direction, including nil + const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; + + long j, value = getElementValue(js, hat); + if (value < 0 || value > 8) + value = 8; + + for (j = 0; j < 4; j++) + { + if (directions[value] & (1 << j)) + js->buttons[buttonIndex++] = GLFW_PRESS; + else + js->buttons[buttonIndex++] = GLFW_RELEASE; + } + } + + return GLFW_TRUE; +} + +// Callback for user-initiated joystick addition +// +static void matchCallback(void* context, + IOReturn result, + void* sender, + IOHIDDeviceRef deviceRef) +{ + _GLFWjoystickNS* js; + int joy; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (_glfw.ns_js[joy].present && _glfw.ns_js[joy].deviceRef == deviceRef) + return; + } + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.ns_js[joy].present) + break; + } + + if (joy > GLFW_JOYSTICK_LAST) + return; + + js = _glfw.ns_js + joy; + js->present = GLFW_TRUE; + js->deviceRef = deviceRef; + + CFStringRef name = IOHIDDeviceGetProperty(deviceRef, + CFSTR(kIOHIDProductKey)); + if (name) + { + CFStringGetCString(name, + js->name, + sizeof(js->name), + kCFStringEncodingUTF8); + } + else + strncpy(js->name, "Unknown", sizeof(js->name)); + + js->axisElements = CFArrayCreateMutable(NULL, 0, NULL); + js->buttonElements = CFArrayCreateMutable(NULL, 0, NULL); + js->hatElements = CFArrayCreateMutable(NULL, 0, NULL); + + CFArrayRef arrayRef = IOHIDDeviceCopyMatchingElements(deviceRef, + NULL, + kIOHIDOptionsTypeNone); + CFRange range = { 0, CFArrayGetCount(arrayRef) }; + CFArrayApplyFunction(arrayRef, + range, + getElementsCFArrayHandler, + (void*) js); + + CFRelease(arrayRef); + + js->axes = calloc(CFArrayGetCount(js->axisElements), sizeof(float)); + js->buttons = calloc(CFArrayGetCount(js->buttonElements) + + CFArrayGetCount(js->hatElements) * 4, 1); + + _glfwInputJoystickChange(joy, GLFW_CONNECTED); +} + +// Callback for user-initiated joystick removal +// +static void removeCallback(void* context, + IOReturn result, + void* sender, + IOHIDDeviceRef deviceRef) +{ + int joy; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (_glfw.ns_js[joy].deviceRef == deviceRef) + { + removeJoystick(_glfw.ns_js + joy); + break; + } + } +} + +// Creates a dictionary to match against devices with the specified usage page +// and usage +// +static CFMutableDictionaryRef createMatchingDictionary(long usagePage, + long usage) +{ + CFMutableDictionaryRef result = + CFDictionaryCreateMutable(kCFAllocatorDefault, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (result) + { + CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault, + kCFNumberLongType, + &usagePage); + if (pageRef) + { + CFDictionarySetValue(result, + CFSTR(kIOHIDDeviceUsagePageKey), + pageRef); + CFRelease(pageRef); + + CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault, + kCFNumberLongType, + &usage); + if (usageRef) + { + CFDictionarySetValue(result, + CFSTR(kIOHIDDeviceUsageKey), + usageRef); + CFRelease(usageRef); + } + } + } + + return result; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize joystick interface +// +void _glfwInitJoysticksNS(void) +{ + CFMutableArrayRef matchingCFArrayRef; + + _glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault, + kIOHIDOptionsTypeNone); + + matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, + 0, + &kCFTypeArrayCallBacks); + if (matchingCFArrayRef) + { + CFDictionaryRef matchingCFDictRef = + createMatchingDictionary(kHIDPage_GenericDesktop, + kHIDUsage_GD_Joystick); + if (matchingCFDictRef) + { + CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef); + CFRelease(matchingCFDictRef); + } + + matchingCFDictRef = createMatchingDictionary(kHIDPage_GenericDesktop, + kHIDUsage_GD_GamePad); + if (matchingCFDictRef) + { + CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef); + CFRelease(matchingCFDictRef); + } + + matchingCFDictRef = + createMatchingDictionary(kHIDPage_GenericDesktop, + kHIDUsage_GD_MultiAxisController); + if (matchingCFDictRef) + { + CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef); + CFRelease(matchingCFDictRef); + } + + IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, + matchingCFArrayRef); + CFRelease(matchingCFArrayRef); + } + + 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 joy; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + _GLFWjoystickNS* js = _glfw.ns_js + joy; + removeJoystick(js); + } + + CFRelease(_glfw.ns.hidManager); + _glfw.ns.hidManager = NULL; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformJoystickPresent(int joy) +{ + _GLFWjoystickNS* js = _glfw.ns_js + joy; + return js->present; +} + +const float* _glfwPlatformGetJoystickAxes(int joy, int* count) +{ + _GLFWjoystickNS* js = _glfw.ns_js + joy; + if (!pollJoystickAxisEvents(js)) + return NULL; + + *count = (int) CFArrayGetCount(js->axisElements); + return js->axes; +} + +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) +{ + _GLFWjoystickNS* js = _glfw.ns_js + joy; + if (!pollJoystickButtonEvents(js)) + return NULL; + + *count = (int) CFArrayGetCount(js->buttonElements) + + (int) CFArrayGetCount(js->hatElements) * 4; + return js->buttons; +} + +const char* _glfwPlatformGetJoystickName(int joy) +{ + _GLFWjoystickNS* js = _glfw.ns_js + joy; + if (!js->present) + return NULL; + + return js->name; +} + diff --git a/extern/glfw-3.2.1/src/cocoa_monitor.m b/extern/glfw-3.2.1/src/cocoa_monitor.m new file mode 100644 index 0000000..9ac0a83 --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_monitor.m @@ -0,0 +1,413 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include + +#include +#include +#include +#include + + +// Get the name of the specified display +// +static char* getDisplayName(CGDirectDisplayID displayID) +{ + char* name; + CFDictionaryRef info, names; + CFStringRef value; + CFIndex size; + + // NOTE: This uses a deprecated function because Apple has + // (as of January 2015) not provided any alternative + info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), + kIODisplayOnlyPreferredName); + names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); + + if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), + (const void**) &value)) + { + // This may happen if a desktop Mac is running headless + _glfwInputError(GLFW_PLATFORM_ERROR, + "Cocoa: Failed to retrieve display name"); + + CFRelease(info); + return strdup("Unknown"); + } + + size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), + kCFStringEncodingUTF8); + name = calloc(size + 1, 1); + CFStringGetCString(value, 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; + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && + CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) + { + CFRelease(format); + return GLFW_FALSE; + } + + CFRelease(format); + 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); + } + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) + { + result.redBits = 5; + result.greenBits = 5; + result.blueBits = 5; + } + else + { + result.redBits = 8; + result.greenBits = 8; + result.blueBits = 8; + } + + CFRelease(format); + 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 ////// +////////////////////////////////////////////////////////////////////////// + +// 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, ¤t); + if (_glfwCompareVideoModes(¤t, 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 ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + uint32_t i, found = 0, displayCount; + _GLFWmonitor** monitors; + CGDirectDisplayID* displays; + + *count = 0; + + CGGetOnlineDisplayList(0, NULL, &displayCount); + displays = calloc(displayCount, sizeof(CGDirectDisplayID)); + monitors = calloc(displayCount, sizeof(_GLFWmonitor*)); + + CGGetOnlineDisplayList(displayCount, displays, &displayCount); + + for (i = 0; i < displayCount; i++) + { + _GLFWmonitor* monitor; + + if (CGDisplayIsAsleep(displays[i])) + continue; + + const CGSize size = CGDisplayScreenSize(displays[i]); + char* name = getDisplayName(displays[i]); + + monitor = _glfwAllocMonitor(name, size.width, size.height); + monitor->ns.displayID = displays[i]; + monitor->ns.unitNumber = CGDisplayUnitNumber(displays[i]); + + free(name); + + found++; + monitors[found - 1] = monitor; + } + + free(displays); + + *count = found; + return monitors; +} + +GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + // HACK: Compare unit numbers instead of display IDs to work around display + // replacement on machines with automatic graphics switching + return first->ns.unitNumber == second->ns.unitNumber; +} + +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; +} + +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/extern/glfw-3.2.1/src/cocoa_platform.h b/extern/glfw-3.2.1/src/cocoa_platform.h new file mode 100644 index 0000000..9221427 --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_platform.h @@ -0,0 +1,150 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// +// 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_cocoa_platform_h_ +#define _glfw3_cocoa_platform_h_ + +#include +#include + +#if defined(__OBJC__) +#import +#import +#else +#include +#include +typedef void* id; +#endif + +#include "posix_tls.h" +#include "cocoa_joystick.h" +#include "nsgl_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_PLATFORM_WINDOW_STATE _GLFWwindowNS ns +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns +#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns + +#define _GLFW_EGL_CONTEXT_STATE +#define _GLFW_EGL_LIBRARY_CONTEXT_STATE + +// HIToolbox.framework pointer typedefs +#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData +#define kTISNotifySelectedKeyboardInputSourceChanged _glfw.ns.tis.kNotifySelectedKeyboardInputSourceChanged +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; + + // 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; + id cursor; + TISInputSourceRef inputSource; + IOHIDManagerRef hidManager; + id unicodeData; + id listener; + + char keyName[64]; + short int publicKeys[256]; + short int nativeKeys[GLFW_KEY_LAST + 1]; + char* clipboardString; + // 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; + CFStringRef kNotifySelectedKeyboardInputSourceChanged; + } tis; + +} _GLFWlibraryNS; + +// Cocoa-specific per-monitor data +// +typedef struct _GLFWmonitorNS +{ + CGDirectDisplayID displayID; + CGDisplayModeRef previousMode; + uint32_t unitNumber; + +} _GLFWmonitorNS; + +// Cocoa-specific per-cursor data +// +typedef struct _GLFWcursorNS +{ + id object; + +} _GLFWcursorNS; + +// Cocoa-specific global timer data +// +typedef struct _GLFWtimeNS +{ + uint64_t frequency; + +} _GLFWtimeNS; + + +void _glfwInitTimerNS(void); + +GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired); +void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor); + +#endif // _glfw3_cocoa_platform_h_ diff --git a/extern/glfw-3.2.1/src/cocoa_time.c b/extern/glfw-3.2.1/src/cocoa_time.c new file mode 100644 index 0000000..dacfed0 --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_time.c @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// +// 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 + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialise timer +// +void _glfwInitTimerNS(void) +{ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + + _glfw.ns_time.frequency = (info.denom * 1e9) / info.numer; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +uint64_t _glfwPlatformGetTimerValue(void) +{ + return mach_absolute_time(); +} + +uint64_t _glfwPlatformGetTimerFrequency(void) +{ + return _glfw.ns_time.frequency; +} + diff --git a/extern/glfw-3.2.1/src/cocoa_window.m b/extern/glfw-3.2.1/src/cocoa_window.m new file mode 100644 index 0000000..b002e99 --- /dev/null +++ b/extern/glfw-3.2.1/src/cocoa_window.m @@ -0,0 +1,1653 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// +// 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 +#include + +// Needed for _NSGetProgname +#include + + +// Returns the specified standard cursor +// +static NSCursor* getStandardCursor(int shape) +{ + switch (shape) + { + case GLFW_ARROW_CURSOR: + return [NSCursor arrowCursor]; + case GLFW_IBEAM_CURSOR: + return [NSCursor IBeamCursor]; + case GLFW_CROSSHAIR_CURSOR: + return [NSCursor crosshairCursor]; + case GLFW_HAND_CURSOR: + return [NSCursor pointingHandCursor]; + case GLFW_HRESIZE_CURSOR: + return [NSCursor resizeLeftRightCursor]; + case GLFW_VRESIZE_CURSOR: + return [NSCursor resizeUpDownCursor]; + } + + return nil; +} + +// Returns the style mask corresponding to the window settings +// +static NSUInteger getStyleMask(_GLFWwindow* window) +{ + NSUInteger styleMask = 0; + + if (window->monitor || !window->decorated) + styleMask |= NSBorderlessWindowMask; + else + { + styleMask |= NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask; + + if (window->resizable) + styleMask |= NSResizableWindowMask; + } + + 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]]; +} + +// Updates the cursor image according to its cursor mode +// +static void updateCursorImage(_GLFWwindow* window) +{ + if (window->cursorMode == GLFW_CURSOR_NORMAL) + { + if (window->cursor) + [(NSCursor*) window->cursor->ns.object set]; + else + [[NSCursor arrowCursor] set]; + } + else + [(NSCursor*) _glfw.ns.cursor set]; +} + +// 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]; + + _glfwInputMonitorWindowChange(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; + + _glfwInputMonitorWindowChange(window->monitor, NULL); + _glfwRestoreVideoModeNS(window->monitor); +} + +// Translates OS X key modifiers into GLFW ones +// +static int translateFlags(NSUInteger flags) +{ + int mods = 0; + + if (flags & NSShiftKeyMask) + mods |= GLFW_MOD_SHIFT; + if (flags & NSControlKeyMask) + mods |= GLFW_MOD_CONTROL; + if (flags & NSAlternateKeyMask) + mods |= GLFW_MOD_ALT; + if (flags & NSCommandKeyMask) + mods |= GLFW_MOD_SUPER; + + return mods; +} + +// Translates a OS X keycode to a GLFW keycode +// +static int translateKey(unsigned int key) +{ + if (key >= sizeof(_glfw.ns.publicKeys) / sizeof(_glfw.ns.publicKeys[0])) + return GLFW_KEY_UNKNOWN; + + return _glfw.ns.publicKeys[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 NSShiftKeyMask; + case GLFW_KEY_LEFT_CONTROL: + case GLFW_KEY_RIGHT_CONTROL: + return NSControlKeyMask; + case GLFW_KEY_LEFT_ALT: + case GLFW_KEY_RIGHT_ALT: + return NSAlternateKeyMask; + case GLFW_KEY_LEFT_SUPER: + case GLFW_KEY_RIGHT_SUPER: + return NSCommandKeyMask; + } + + 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; +} + +- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; + +@end + +@implementation GLFWWindowDelegate + +- (id)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 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 +{ + _glfwInputMonitorChange(); +} + +- (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 +{ + _GLFWwindow* window; + NSTrackingArea* trackingArea; + NSMutableAttributedString* markedText; +} + +- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; + +@end + +@implementation GLFWContentView + ++ (void)initialize +{ + if (self == [GLFWContentView class]) + { + if (_glfw.ns.cursor == nil) + { + NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)]; + _glfw.ns.cursor = [[NSCursor alloc] initWithImage:data + hotSpot:NSZeroPoint]; + [data release]; + } + } +} + +- (id)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 YES; +} + +- (BOOL)canBecomeKeyView +{ + return YES; +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (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 +{ + _glfwInputCursorEnter(window, GLFW_FALSE); +} + +- (void)mouseEntered:(NSEvent *)event +{ + _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] & NSDeviceIndependentModifierFlagsMask; + 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 )sender +{ + if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) + == NSDragOperationGeneric) + { + [self setNeedsDisplay:YES]; + return NSDragOperationGeneric; + } + + return NSDragOperationNone; +} + +- (BOOL)prepareForDragOperation:(id )sender +{ + [self setNeedsDisplay:YES]; + return YES; +} + +- (BOOL)performDragOperation:(id )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 )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 +{ + if ([string isKindOfClass:[NSAttributedString class]]) + [markedText initWithAttributedString:string]; + else + [markedText 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 NSBorderlessWindowMask windows + return YES; +} + +@end + + +//------------------------------------------------------------------------ +// GLFW application class +//------------------------------------------------------------------------ + +@interface GLFWApplication : NSApplication +@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] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + [[self keyWindow] sendEvent:event]; + else + [super sendEvent:event]; +} + + +// No-op thread entry point +// +- (void)doNothing:(id)object +{ +} +@end + +#if defined(_GLFW_USE_MENUBAR) + +// Try to figure out what the calling application is called +// +static NSString* findAppName(void) +{ + size_t i; + NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary]; + + // Keys to search for as potential application names + NSString* GLFWNameKeys[] = + { + @"CFBundleDisplayName", + @"CFBundleName", + @"CFBundleExecutable", + }; + + for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++) + { + id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; + if (name && + [name isKindOfClass:[NSString class]] && + ![name isEqualToString:@""]) + { + return name; + } + } + + char** progname = _NSGetProgname(); + if (progname && *progname) + return [NSString stringWithUTF8String:*progname]; + + // Really shouldn't get here + return @"GLFW Application"; +} + +// 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. Loading a nib would save us this horror, but that +// doesn't seem like a good thing to require of GLFW users. +// +static void createMenuBar(void) +{ + NSString* appName = findAppName(); + + 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:NSAlternateKeyMask | NSCommandKeyMask]; + [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:NSControlKeyMask | NSCommandKeyMask]; + + // 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]; +} + +#endif /* _GLFW_USE_MENUBAR */ + +// 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]; + + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + +#if defined(_GLFW_USE_MENUBAR) + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + createMenuBar(); +#endif + + // 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]; + + return GLFW_TRUE; +} + +// Create the Cocoa window +// +static GLFWbool createNativeWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + 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]; + + if (wndconfig->resizable) + [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + + if (wndconfig->floating) + [window->ns.object setLevel:NSFloatingWindowLevel]; + + if (wndconfig->maximized) + [window->ns.object zoom:nil]; + } + + window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window]; + +#if defined(_GLFW_USE_RETINA) + [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; +#endif /*_GLFW_USE_RETINA*/ + + [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 setContentView:window->ns.view]; + [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)) + 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 + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Cocoa: EGL not available"); + return GLFW_FALSE; + } + } + + if (window->monitor) + { + _glfwPlatformShowWindow(window); + _glfwPlatformFocusWindow(window); + if (!acquireMonitor(window)) + return GLFW_FALSE; + + 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) +{ + [window->ns.object setTitle:[NSString stringWithUTF8String:title]]; +} + +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 setContentAspectRatio:NSMakeSize(0, 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 _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 _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); + + _glfwInputWindowMonitorChange(window, monitor); + + 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]; + } +} + +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]; +} + +void _glfwPlatformPollEvents(void) +{ + for (;;) + { + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + 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:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + [NSApp sendEvent:event]; + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformWaitEventsTimeout(double timeout) +{ + NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:date + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event) + [NSApp sendEvent:event]; + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformPostEmptyEvent(void) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined + 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* _glfwPlatformGetKeyName(int key, int scancode) +{ + if (key != GLFW_KEY_UNKNOWN) + scancode = _glfw.ns.nativeKeys[key]; + + if (!_glfwIsPrintable(_glfw.ns.publicKeys[scancode])) + return NULL; + + 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 _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; + + cursor->ns.object = getStandardCursor(shape); + 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; +} + +char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count) +{ + *count = 0; + return NULL; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) +{ + return GLFW_FALSE; +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + return VK_ERROR_EXTENSION_NOT_PRESENT; +} + + +////////////////////////////////////////////////////////////////////////// +////// 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/extern/glfw-3.2.1/src/context.c b/extern/glfw-3.2.1/src/context.c new file mode 100644 index 0000000..85bce7f --- /dev/null +++ b/extern/glfw-3.2.1/src/context.c @@ -0,0 +1,720 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) +{ + if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API && + ctxconfig->source != GLFW_EGL_CONTEXT_API) + { + _glfwInputError(GLFW_INVALID_ENUM, + "Invalid context creation API %i", + 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 %i", + 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 %i", + 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 %i", + 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 %i", + 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++; + } + } + + // 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 = _glfwPlatformGetCurrentContext(); + + 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 = _glfwPlatformGetCurrentContext(); + + _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 (GLFWwindow*) _glfwPlatformGetCurrentContext(); +} + +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 = _glfwPlatformGetCurrentContext(); + 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 = _glfwPlatformGetCurrentContext(); + 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 = _glfwPlatformGetCurrentContext(); + if (!window) + { + _glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL); + return NULL; + } + + return window->context.getProcAddress(procname); +} + diff --git a/extern/glfw-3.2.1/src/egl_context.c b/extern/glfw-3.2.1/src/egl_context.c new file mode 100644 index 0000000..e3d6260 --- /dev/null +++ b/extern/glfw-3.2.1/src/egl_context.c @@ -0,0 +1,746 @@ +//======================================================================== +// GLFW 3.2 EGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include +#include + + +// 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) + // Only consider EGLConfigs with associated Visuals + if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) + continue; +#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; + } + } + + _glfwPlatformSetCurrentContext(window); +} + +static void swapBuffersEGL(_GLFWwindow* window) +{ + if (window != _glfwPlatformGetCurrentContext()) + { + _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 = _glfwPlatformGetCurrentContext(); + + 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_WIN32) + "libEGL.dll", + "EGL.dll", +#elif defined(_GLFW_COCOA) + "libEGL.dylib", +#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 = (PFNEGLGETCONFIGATTRIBPROC) + _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); + _glfw.egl.GetConfigs = (PFNEGLGETCONFIGSPROC) + _glfw_dlsym(_glfw.egl.handle, "eglGetConfigs"); + _glfw.egl.GetDisplay = (PFNEGLGETDISPLAYPROC) + _glfw_dlsym(_glfw.egl.handle, "eglGetDisplay"); + _glfw.egl.GetError = (PFNEGLGETERRORPROC) + _glfw_dlsym(_glfw.egl.handle, "eglGetError"); + _glfw.egl.Initialize = (PFNEGLINITIALIZEPROC) + _glfw_dlsym(_glfw.egl.handle, "eglInitialize"); + _glfw.egl.Terminate = (PFNEGLTERMINATEPROC) + _glfw_dlsym(_glfw.egl.handle, "eglTerminate"); + _glfw.egl.BindAPI = (PFNEGLBINDAPIPROC) + _glfw_dlsym(_glfw.egl.handle, "eglBindAPI"); + _glfw.egl.CreateContext = (PFNEGLCREATECONTEXTPROC) + _glfw_dlsym(_glfw.egl.handle, "eglCreateContext"); + _glfw.egl.DestroySurface = (PFNEGLDESTROYSURFACEPROC) + _glfw_dlsym(_glfw.egl.handle, "eglDestroySurface"); + _glfw.egl.DestroyContext = (PFNEGLDESTROYCONTEXTPROC) + _glfw_dlsym(_glfw.egl.handle, "eglDestroyContext"); + _glfw.egl.CreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) + _glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface"); + _glfw.egl.MakeCurrent = (PFNEGLMAKECURRENTPROC) + _glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent"); + _glfw.egl.SwapBuffers = (PFNEGLSWAPBUFFERSPROC) + _glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers"); + _glfw.egl.SwapInterval = (PFNEGLSWAPINTERVALPROC) + _glfw_dlsym(_glfw.egl.handle, "eglSwapInterval"); + _glfw.egl.QueryString = (PFNEGLQUERYSTRINGPROC) + _glfw_dlsym(_glfw.egl.handle, "eglQueryString"); + _glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC) + _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"); + + 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 setEGLattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ +} + +// 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; + + 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 index = 0, 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 (_glfw.egl.KHR_create_context_no_error) + { + if (ctxconfig->noerror) + flags |= EGL_CONTEXT_OPENGL_NO_ERROR_KHR; + } + } + + if (ctxconfig->debug) + flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + + if (ctxconfig->robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + { + setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, + EGL_NO_RESET_NOTIFICATION_KHR); + } + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + { + setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, + EGL_LOSE_CONTEXT_ON_RESET_KHR); + } + + flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + } + + if (ctxconfig->major != 1 || ctxconfig->minor != 0) + { + setEGLattrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); + setEGLattrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); + } + + if (mask) + setEGLattrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); + + if (flags) + setEGLattrib(EGL_CONTEXT_FLAGS_KHR, flags); + + setEGLattrib(EGL_NONE, EGL_NONE); + } + else + { + int index = 0; + + if (ctxconfig->client == GLFW_OPENGL_ES_API) + setEGLattrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); + + setEGLattrib(EGL_NONE, EGL_NONE); + } + + // Context release behaviors (GL_KHR_context_flush_control) are not yet + // supported on EGL but are not a hard constraint, so ignore and continue + + 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) + { + setEGLattrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR); + } + } + + setEGLattrib(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 + { + int i; + const char** sonames; + const char* es1sonames[] = + { +#if 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_WIN32) + "GLESv2.dll", + "libGLESv2.dll", +#elif defined(_GLFW_COCOA) + "libGLESv2.dylib", +#else + "libGLESv2.so.2", +#endif + NULL + }; + const char* glsonames[] = + { +#if 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 setEGLattrib + +// Returns the Visual and depth of the chosen EGLConfig +// +#if defined(_GLFW_X11) +GLFWbool _glfwChooseVisualEGL(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/extern/glfw-3.2.1/src/egl_context.h b/extern/glfw-3.2.1/src/egl_context.h new file mode 100644 index 0000000..9bd8bb4 --- /dev/null +++ b/extern/glfw-3.2.1/src/egl_context.h @@ -0,0 +1,213 @@ +//======================================================================== +// GLFW 3.2 EGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_egl_context_h_ +#define _glfw3_egl_context_h_ + +#if defined(_GLFW_USE_EGLPLATFORM_H) + #include +#elif defined(_GLFW_WIN32) + #define EGLAPIENTRY __stdcall +typedef HDC EGLNativeDisplayType; +typedef HWND 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 + +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 * PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay,EGLConfig,EGLint,EGLint*); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETCONFIGSPROC)(EGLDisplay,EGLConfig*,EGLint,EGLint*); +typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType); +typedef EGLint (EGLAPIENTRY * PFNEGLGETERRORPROC)(void); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLINITIALIZEPROC)(EGLDisplay,EGLint*,EGLint*); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLTERMINATEPROC)(EGLDisplay); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLBINDAPIPROC)(EGLenum); +typedef EGLContext (EGLAPIENTRY * PFNEGLCREATECONTEXTPROC)(EGLDisplay,EGLConfig,EGLContext,const EGLint*); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSURFACEPROC)(EGLDisplay,EGLSurface); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYCONTEXTPROC)(EGLDisplay,EGLContext); +typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLMAKECURRENTPROC)(EGLDisplay,EGLSurface,EGLSurface,EGLContext); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPBUFFERSPROC)(EGLDisplay,EGLSurface); +typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPINTERVALPROC)(EGLDisplay,EGLint); +typedef const char* (EGLAPIENTRY * PFNEGLQUERYSTRINGPROC)(EGLDisplay,EGLint); +typedef GLFWglproc (EGLAPIENTRY * PFNEGLGETPROCADDRESSPROC)(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; + + void* handle; + + PFNEGLGETCONFIGATTRIBPROC GetConfigAttrib; + PFNEGLGETCONFIGSPROC GetConfigs; + PFNEGLGETDISPLAYPROC GetDisplay; + PFNEGLGETERRORPROC GetError; + PFNEGLINITIALIZEPROC Initialize; + PFNEGLTERMINATEPROC Terminate; + PFNEGLBINDAPIPROC BindAPI; + PFNEGLCREATECONTEXTPROC CreateContext; + PFNEGLDESTROYSURFACEPROC DestroySurface; + PFNEGLDESTROYCONTEXTPROC DestroyContext; + PFNEGLCREATEWINDOWSURFACEPROC CreateWindowSurface; + PFNEGLMAKECURRENTPROC MakeCurrent; + PFNEGLSWAPBUFFERSPROC SwapBuffers; + PFNEGLSWAPINTERVALPROC SwapInterval; + PFNEGLQUERYSTRINGPROC QueryString; + PFNEGLGETPROCADDRESSPROC 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 _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig, + Visual** visual, int* depth); +#endif /*_GLFW_X11*/ + +#endif // _glfw3_egl_context_h_ diff --git a/extern/glfw-3.2.1/src/glfw3.pc.in b/extern/glfw-3.2.1/src/glfw3.pc.in new file mode 100644 index 0000000..f2e4d97 --- /dev/null +++ b/extern/glfw-3.2.1/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/extern/glfw-3.2.1/src/glfw3Config.cmake.in b/extern/glfw-3.2.1/src/glfw3Config.cmake.in new file mode 100644 index 0000000..1fa200e --- /dev/null +++ b/extern/glfw-3.2.1/src/glfw3Config.cmake.in @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake") diff --git a/extern/glfw-3.2.1/src/glfw_config.h.in b/extern/glfw-3.2.1/src/glfw_config.h.in new file mode 100644 index 0000000..cf253d3 --- /dev/null +++ b/extern/glfw-3.2.1/src/glfw_config.h.in @@ -0,0 +1,65 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2010-2016 Camilla Berglund +// +// 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 as a shared library / dynamic library / DLL +#cmakedefine _GLFW_BUILD_DLL +// Define this to 1 to use Vulkan loader linked statically into application +#cmakedefine _GLFW_VULKAN_STATIC + +// Define this to 1 to force use of high-performance GPU on hybrid systems +#cmakedefine _GLFW_USE_HYBRID_HPG + +// Define this to 1 if the Xxf86vm X11 extension is available +#cmakedefine _GLFW_HAS_XF86VM + +// Define this to 1 if glfwInit should change the current directory +#cmakedefine _GLFW_USE_CHDIR +// Define this to 1 if glfwCreateWindow should populate the menu bar +#cmakedefine _GLFW_USE_MENUBAR +// Define this to 1 if windows should use full resolution on Retina displays +#cmakedefine _GLFW_USE_RETINA + diff --git a/extern/glfw-3.2.1/src/glx_context.c b/extern/glfw-3.2.1/src/glx_context.c new file mode 100644 index 0000000..251b7fc --- /dev/null +++ b/extern/glfw-3.2.1/src/glx_context.c @@ -0,0 +1,677 @@ +//======================================================================== +// GLFW 3.2 GLX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include + +#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 (strcmp(vendor, "Chromium") == 0) + trustWindowBit = GLFW_FALSE; + + nativeConfigs = + glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount); + if (!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; + } + + 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; + } + } + + _glfwPlatformSetCurrentContext(window); +} + +static void swapBuffersGLX(_GLFWwindow* window) +{ + glXSwapBuffers(_glfw.x11.display, window->context.glx.window); +} + +static void swapIntervalGLX(int interval) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + 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(__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_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 setGLXattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ +} + +// 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->noerror) + flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; + + if (ctxconfig->robustness) + { + if (_glfw.glx.ARB_create_context_robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + { + setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + GLX_NO_RESET_NOTIFICATION_ARB); + } + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + { + setGLXattrib(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) + { + setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + } + else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) + { + setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + } + } + } + + // 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) + { + setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + } + + if (mask) + setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); + + if (flags) + setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); + + setGLXattrib(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 setGLXattrib + +// Returns the Visual and depth of the chosen GLXFBConfig +// +GLFWbool _glfwChooseVisualGLX(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/extern/glfw-3.2.1/src/glx_context.h b/extern/glfw-3.2.1/src/glx_context.h new file mode 100644 index 0000000..3abed0e --- /dev/null +++ b/extern/glfw-3.2.1/src/glx_context.h @@ -0,0 +1,182 @@ +//======================================================================== +// GLFW 3.2 GLX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_glx_context_h_ +#define _glfw3_glx_context_h_ + +#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 + +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 int (*PFNGLXSWAPINTERVALMESAPROC)(int); +typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int); +typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int); +typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*); +typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig); +typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*); +typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); + +// 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_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 _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig, + Visual** visual, int* depth); + +#endif // _glfw3_glx_context_h_ diff --git a/extern/glfw-3.2.1/src/init.c b/extern/glfw-3.2.1/src/init.c new file mode 100644 index 0000000..9d4a2b2 --- /dev/null +++ b/extern/glfw-3.2.1/src/init.c @@ -0,0 +1,200 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include +#include + + +// The three global variables below comprise all global data in GLFW. +// Any other global variable is a bug. + +// Global state shared between compilation units of GLFW +// These are documented in internal.h +// +GLFWbool _glfwInitialized = GLFW_FALSE; +_GLFWlibrary _glfw; + +// This is outside of _glfw so it can be initialized and usable before +// glfwInit is called, which lets that function report errors +// +static GLFWerrorfun _glfwErrorCallback = NULL; + + +// Returns a generic string representation of the specified error +// +static const char* getErrorString(int error) +{ + switch (error) + { + 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 "A 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"; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW event API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInputError(int error, const char* format, ...) +{ + if (_glfwErrorCallback) + { + char buffer[8192]; + const char* description; + + if (format) + { + int count; + va_list vl; + + va_start(vl, format); + count = vsnprintf(buffer, sizeof(buffer), format, vl); + va_end(vl); + + if (count < 0) + buffer[sizeof(buffer) - 1] = '\0'; + + description = buffer; + } + else + description = getErrorString(error); + + _glfwErrorCallback(error, description); + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI int glfwInit(void) +{ + if (_glfwInitialized) + return GLFW_TRUE; + + memset(&_glfw, 0, sizeof(_glfw)); + + if (!_glfwPlatformInit()) + { + _glfwPlatformTerminate(); + return GLFW_FALSE; + } + + _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); + _glfwInitialized = GLFW_TRUE; + + _glfw.timerOffset = _glfwPlatformGetTimerValue(); + + // Not all window hints have zero as their default value + glfwDefaultWindowHints(); + + return GLFW_TRUE; +} + +GLFWAPI void glfwTerminate(void) +{ + int i; + + if (!_glfwInitialized) + return; + + 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); + } + + _glfwTerminateVulkan(); + + _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount); + _glfw.monitors = NULL; + _glfw.monitorCount = 0; + + _glfwPlatformTerminate(); + + memset(&_glfw, 0, sizeof(_glfw)); + _glfwInitialized = GLFW_FALSE; +} + +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 GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) +{ + _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); + return cbfun; +} + diff --git a/extern/glfw-3.2.1/src/input.c b/extern/glfw-3.2.1/src/input.c new file mode 100644 index 0000000..614c6ef --- /dev/null +++ b/extern/glfw-3.2.1/src/input.c @@ -0,0 +1,659 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include + +// Internal key state used for sticky keys +#define _GLFW_STICK 3 + + +////////////////////////////////////////////////////////////////////////// +////// 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; + + // Register mouse button action + 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 _glfwInputJoystickChange(int joy, int event) +{ + if (_glfw.callbacks.joystick) + _glfw.callbacks.joystick(joy, event); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWbool _glfwIsPrintable(int key) +{ + return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) || + (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) || + key == GLFW_KEY_KP_EQUAL; +} + + +////////////////////////////////////////////////////////////////////////// +////// 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; + default: + _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode); + return 0; + } +} + +GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT(); + + switch (mode) + { + case GLFW_CURSOR: + { + if (value != GLFW_CURSOR_NORMAL && + value != GLFW_CURSOR_HIDDEN && + value != GLFW_CURSOR_DISABLED) + { + _glfwInputError(GLFW_INVALID_ENUM, + "Invalid cursor mode %i", + value); + return; + } + + if (window->cursorMode == value) + return; + + window->cursorMode = value; + + _glfwPlatformGetCursorPos(window, + &window->virtualCursorPosX, + &window->virtualCursorPosY); + + if (_glfwPlatformWindowFocused(window)) + _glfwPlatformSetCursorMode(window, value); + + return; + } + + case GLFW_STICKY_KEYS: + { + 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; + return; + } + + case GLFW_STICKY_MOUSE_BUTTONS: + { + 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; + return; + } + } + + _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode); +} + +GLFWAPI const char* glfwGetKeyName(int key, int scancode) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return _glfwPlatformGetKeyName(key, scancode); +} + +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 %i", 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 joy) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(0); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy); + return 0; + } + + return _glfwPlatformJoystickPresent(joy); +} + +GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count) +{ + assert(count != NULL); + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy); + return NULL; + } + + return _glfwPlatformGetJoystickAxes(joy, count); +} + +GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count) +{ + assert(count != NULL); + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy); + return NULL; + } + + return _glfwPlatformGetJoystickButtons(joy, count); +} + +GLFWAPI const char* glfwGetJoystickName(int joy) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (joy < 0 || joy > GLFW_JOYSTICK_LAST) + { + _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy); + return NULL; + } + + return _glfwPlatformGetJoystickName(joy); +} + +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun); + return cbfun; +} + +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.timerOffset) / + _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.timerOffset = _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/extern/glfw-3.2.1/src/internal.h b/extern/glfw-3.2.1/src/internal.h new file mode 100644 index 0000000..8e84efd --- /dev/null +++ b/extern/glfw-3.2.1/src/internal.h @@ -0,0 +1,1055 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_internal_h_ +#define _glfw3_internal_h_ + + +#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_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" + +typedef int GLFWbool; + +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 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_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_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" +#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 (!_glfwInitialized) \ + { \ + _glfwInputError(GLFW_NOT_INITIALIZED, NULL); \ + return; \ + } +#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \ + if (!_glfwInitialized) \ + { \ + _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 +//======================================================================== + +/*! @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; +}; + +/*! @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; +}; + +/*! @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; + 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; +}; + +/*! @brief Window and context structure. + */ +struct _GLFWwindow +{ + struct _GLFWwindow* next; + + // Window settings and state + GLFWbool resizable; + GLFWbool decorated; + GLFWbool autoIconify; + GLFWbool floating; + GLFWbool closed; + 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; + 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 Library global data. + */ +struct _GLFWlibrary +{ + struct { + _GLFWfbconfig framebuffer; + _GLFWwndconfig window; + _GLFWctxconfig context; + int refreshRate; + } hints; + + _GLFWcursor* cursorListHead; + + _GLFWwindow* windowListHead; + + _GLFWmonitor** monitors; + int monitorCount; + + uint64_t timerOffset; + + struct { + GLFWbool available; + void* handle; + char** extensions; + uint32_t extensionCount; +#if !defined(_GLFW_VULKAN_STATIC) + PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; +#endif + GLFWbool KHR_surface; + GLFWbool KHR_win32_surface; + GLFWbool KHR_xlib_surface; + GLFWbool KHR_xcb_surface; + GLFWbool KHR_wayland_surface; + GLFWbool KHR_mir_surface; + } 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 time.h + _GLFW_PLATFORM_LIBRARY_TIME_STATE; + // This is defined in the platform's joystick.h + _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE; + // This is defined in the platform's tls.h + _GLFW_PLATFORM_LIBRARY_TLS_STATE; + // This is defined in egl_context.h + _GLFW_EGL_LIBRARY_CONTEXT_STATE; +}; + + +//======================================================================== +// Global state shared between compilation units of GLFW +//======================================================================== + +/*! @brief Flag indicating whether GLFW has been successfully initialized. + */ +extern GLFWbool _glfwInitialized; + +/*! @brief All global data protected by @ref _glfwInitialized. + * This should only be touched after a call to @ref glfwInit that has not been + * followed by a call to @ref glfwTerminate. + */ +extern _GLFWlibrary _glfw; + + +//======================================================================== +// Platform API functions +//======================================================================== + +/*! @brief Initializes the platform-specific part of the library. + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an error occurred. + * @ingroup platform + */ +int _glfwPlatformInit(void); + +/*! @brief Terminates the platform-specific part of the library. + * @ingroup platform + */ +void _glfwPlatformTerminate(void); + +/*! @copydoc glfwGetVersionString + * @ingroup platform + * + * @note The returned string must be available for the duration of the program. + * + * @note The returned string must not change for the duration of the program. + */ +const char* _glfwPlatformGetVersionString(void); + +/*! @copydoc glfwGetCursorPos + * @ingroup platform + */ +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos); + +/*! @copydoc glfwSetCursorPos + * @ingroup platform + */ +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); + +/*! @brief Sets the specified cursor mode of the specified window. + * @param[in] window The window whose cursor mode to set. + * @ingroup platform + */ +void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); + +/*! @copydoc glfwGetKeyName + * @ingroup platform + */ +const char* _glfwPlatformGetKeyName(int key, int scancode); + +/*! @copydoc glfwGetMonitors + * @ingroup platform + */ +_GLFWmonitor** _glfwPlatformGetMonitors(int* count); + +/*! @brief Checks whether two monitor objects represent the same monitor. + * + * @param[in] first The first monitor. + * @param[in] second The second monitor. + * @return @c GLFW_TRUE if the monitor objects represent the same monitor, or + * @c GLFW_FALSE otherwise. + * @ingroup platform + */ +GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second); + +/*! @copydoc glfwGetMonitorPos + * @ingroup platform + */ +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); + +/*! @copydoc glfwGetVideoModes + * @ingroup platform + */ +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); + +/*! @ingroup platform + */ +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); + +/*! @copydoc glfwGetGammaRamp + * @ingroup platform + */ +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); + +/*! @copydoc glfwSetGammaRamp + * @ingroup platform + */ +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); + +/*! @copydoc glfwSetClipboardString + * @ingroup platform + */ +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string); + +/*! @copydoc glfwGetClipboardString + * @ingroup platform + * + * @note The returned string must be valid until the next call to @ref + * _glfwPlatformGetClipboardString or @ref _glfwPlatformSetClipboardString. + */ +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window); + +/*! @copydoc glfwJoystickPresent + * @ingroup platform + */ +int _glfwPlatformJoystickPresent(int joy); + +/*! @copydoc glfwGetJoystickAxes + * @ingroup platform + */ +const float* _glfwPlatformGetJoystickAxes(int joy, int* count); + +/*! @copydoc glfwGetJoystickButtons + * @ingroup platform + */ +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count); + +/*! @copydoc glfwGetJoystickName + * @ingroup platform + */ +const char* _glfwPlatformGetJoystickName(int joy); + +/*! @copydoc glfwGetTimerValue + * @ingroup platform + */ +uint64_t _glfwPlatformGetTimerValue(void); + +/*! @copydoc glfwGetTimerFrequency + * @ingroup platform + */ +uint64_t _glfwPlatformGetTimerFrequency(void); + +/*! @ingroup platform + */ +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); + +/*! @ingroup platform + */ +void _glfwPlatformDestroyWindow(_GLFWwindow* window); + +/*! @copydoc glfwSetWindowTitle + * @ingroup platform + */ +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); + +/*! @copydoc glfwSetWindowIcon + * @ingroup platform + */ +void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, const GLFWimage* images); + +/*! @copydoc glfwGetWindowPos + * @ingroup platform + */ +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos); + +/*! @copydoc glfwSetWindowPos + * @ingroup platform + */ +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos); + +/*! @copydoc glfwGetWindowSize + * @ingroup platform + */ +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height); + +/*! @copydoc glfwSetWindowSize + * @ingroup platform + */ +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); + +/*! @copydoc glfwSetWindowSizeLimits + * @ingroup platform + */ +void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); + +/*! @copydoc glfwSetWindowAspectRatio + * @ingroup platform + */ +void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom); + +/*! @copydoc glfwGetFramebufferSize + * @ingroup platform + */ +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height); + +/*! @copydoc glfwGetWindowFrameSize + * @ingroup platform + */ +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom); + +/*! @copydoc glfwIconifyWindow + * @ingroup platform + */ +void _glfwPlatformIconifyWindow(_GLFWwindow* window); + +/*! @copydoc glfwRestoreWindow + * @ingroup platform + */ +void _glfwPlatformRestoreWindow(_GLFWwindow* window); + +/*! @copydoc glfwMaximizeWindow + * @ingroup platform + */ +void _glfwPlatformMaximizeWindow(_GLFWwindow* window); + +/*! @copydoc glfwShowWindow + * @ingroup platform + */ +void _glfwPlatformShowWindow(_GLFWwindow* window); + +/*! @copydoc glfwHideWindow + * @ingroup platform + */ +void _glfwPlatformHideWindow(_GLFWwindow* window); + +/*! @copydoc glfwFocusWindow + * @ingroup platform + */ +void _glfwPlatformFocusWindow(_GLFWwindow* window); + +/*! @copydoc glfwSetWindowMonitor + * @ingroup platform + */ +void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); + +/*! @brief Returns whether the window is focused. + * @ingroup platform + */ +int _glfwPlatformWindowFocused(_GLFWwindow* window); + +/*! @brief Returns whether the window is iconified. + * @ingroup platform + */ +int _glfwPlatformWindowIconified(_GLFWwindow* window); + +/*! @brief Returns whether the window is visible. + * @ingroup platform + */ +int _glfwPlatformWindowVisible(_GLFWwindow* window); + +/*! @brief Returns whether the window is maximized. + * @ingroup platform + */ +int _glfwPlatformWindowMaximized(_GLFWwindow* window); + +/*! @copydoc glfwPollEvents + * @ingroup platform + */ +void _glfwPlatformPollEvents(void); + +/*! @copydoc glfwWaitEvents + * @ingroup platform + */ +void _glfwPlatformWaitEvents(void); + +/*! @copydoc glfwWaitEventsTimeout + * @ingroup platform + */ +void _glfwPlatformWaitEventsTimeout(double timeout); + +/*! @copydoc glfwPostEmptyEvent + * @ingroup platform + */ +void _glfwPlatformPostEmptyEvent(void); + +/*! @ingroup platform + */ +void _glfwPlatformSetCurrentContext(_GLFWwindow* context); + +/*! @copydoc glfwGetCurrentContext + * @ingroup platform + */ +_GLFWwindow* _glfwPlatformGetCurrentContext(void); + +/*! @copydoc glfwCreateCursor + * @ingroup platform + */ +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); + +/*! @copydoc glfwCreateStandardCursor + * @ingroup platform + */ +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); + +/*! @copydoc glfwDestroyCursor + * @ingroup platform + */ +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor); + +/*! @copydoc glfwSetCursor + * @ingroup platform + */ +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor); + +/*! @ingroup platform + */ +char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count); + +/*! @ingroup platform + */ +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); + +/*! @ingroup platform + */ +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + + +//======================================================================== +// Event API functions +//======================================================================== + +/*! @brief Notifies shared code of a window focus event. + * @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 of a window movement event. + * @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 of a window resize event. + * @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 of a framebuffer resize event. + * @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 of a window iconification event. + * @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 of a window damage event. + * @param[in] window The window that received the event. + */ +void _glfwInputWindowDamage(_GLFWwindow* window); + +/*! @brief Notifies shared code of a window close request event + * @param[in] window The window that received the event. + * @ingroup event + */ +void _glfwInputWindowCloseRequest(_GLFWwindow* window); + +void _glfwInputWindowMonitorChange(_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. + * @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); + +/*! @ingroup event + */ +void _glfwInputMonitorChange(void); + +/*! @ingroup event + */ +void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window); + +/*! @brief Notifies shared code of an error. + * @param[in] error 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 error, const char* format, ...) __attribute__((format(printf, 2, 3))); +#else +void _glfwInputError(int error, const char* format, ...); +#endif + +/*! @brief Notifies dropped object over 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/disconnection event. + * @param[in] joy The joystick that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. + * @ingroup event + */ +void _glfwInputJoystickChange(int joy, int event); + + +//======================================================================== +// Utility functions +//======================================================================== + +/*! @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); + +/*! @ingroup utility + */ +void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size); + +/*! @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); + +/*! @ingroup utility + */ +void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); + +/*! @ingroup utility + */ +GLFWbool _glfwIsPrintable(int key); + +/*! @ingroup utility + */ +GLFWbool _glfwInitVulkan(void); + +/*! @ingroup utility + */ +void _glfwTerminateVulkan(void); + +/*! @ingroup utility + */ +const char* _glfwGetVulkanResultString(VkResult result); + +#endif // _glfw3_internal_h_ diff --git a/extern/glfw-3.2.1/src/linux_joystick.c b/extern/glfw-3.2.1/src/linux_joystick.c new file mode 100644 index 0000000..561b1eb --- /dev/null +++ b/extern/glfw-3.2.1/src/linux_joystick.c @@ -0,0 +1,341 @@ +//======================================================================== +// GLFW 3.2 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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" + +#if defined(__linux__) +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // __linux__ + + +// Attempt to open the specified joystick device +// +#if defined(__linux__) +static GLFWbool openJoystickDevice(const char* path) +{ + char axisCount, buttonCount; + char name[256] = ""; + int joy, fd, version; + _GLFWjoystickLinux* js; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.linux_js.js[joy].present) + continue; + + if (strcmp(_glfw.linux_js.js[joy].path, path) == 0) + return GLFW_FALSE; + } + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.linux_js.js[joy].present) + break; + } + + if (joy > GLFW_JOYSTICK_LAST) + return GLFW_FALSE; + + fd = open(path, O_RDONLY | O_NONBLOCK); + if (fd == -1) + return GLFW_FALSE; + + // Verify that the joystick driver version is at least 1.0 + ioctl(fd, JSIOCGVERSION, &version); + if (version < 0x010000) + { + // It's an old 0.x interface (we don't support it) + close(fd); + return GLFW_FALSE; + } + + if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) + strncpy(name, "Unknown", sizeof(name)); + + js = _glfw.linux_js.js + joy; + js->present = GLFW_TRUE; + js->name = strdup(name); + js->path = strdup(path); + js->fd = fd; + + ioctl(fd, JSIOCGAXES, &axisCount); + js->axisCount = (int) axisCount; + js->axes = calloc(axisCount, sizeof(float)); + + ioctl(fd, JSIOCGBUTTONS, &buttonCount); + js->buttonCount = (int) buttonCount; + js->buttons = calloc(buttonCount, 1); + + _glfwInputJoystickChange(joy, GLFW_CONNECTED); + return GLFW_TRUE; +} +#endif // __linux__ + +// Polls for and processes events the specified joystick +// +static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js) +{ +#if defined(__linux__) + _glfwPollJoystickEvents(); + + if (!js->present) + return GLFW_FALSE; + + // Read all queued events (non-blocking) + for (;;) + { + struct js_event e; + + errno = 0; + if (read(js->fd, &e, sizeof(e)) < 0) + { + // Reset the joystick slot if the device was disconnected + if (errno == ENODEV) + { + free(js->axes); + free(js->buttons); + free(js->name); + free(js->path); + + memset(js, 0, sizeof(_GLFWjoystickLinux)); + + _glfwInputJoystickChange(js - _glfw.linux_js.js, + GLFW_DISCONNECTED); + } + + break; + } + + // Clear the initial-state bit + e.type &= ~JS_EVENT_INIT; + + if (e.type == JS_EVENT_AXIS) + js->axes[e.number] = (float) e.value / 32767.0f; + else if (e.type == JS_EVENT_BUTTON) + js->buttons[e.number] = e.value ? GLFW_PRESS : GLFW_RELEASE; + } +#endif // __linux__ + return js->present; +} + +// Lexically compare joysticks by name; used by qsort +// +#if defined(__linux__) +static int compareJoysticks(const void* fp, const void* sp) +{ + const _GLFWjoystickLinux* fj = fp; + const _GLFWjoystickLinux* sj = sp; + return strcmp(fj->path, sj->path); +} +#endif // __linux__ + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize joystick interface +// +GLFWbool _glfwInitJoysticksLinux(void) +{ +#if defined(__linux__) + DIR* dir; + int count = 0; + const char* dirname = "/dev/input"; + + _glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + if (_glfw.linux_js.inotify == -1) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Linux: Failed to initialize inotify: %s", + strerror(errno)); + return GLFW_FALSE; + } + + // HACK: Register for IN_ATTRIB as well to get notified when udev is done + // This works well in practice but the true way is libudev + + _glfw.linux_js.watch = inotify_add_watch(_glfw.linux_js.inotify, + dirname, + IN_CREATE | IN_ATTRIB); + if (_glfw.linux_js.watch == -1) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Linux: Failed to watch for joystick connections in %s: %s", + dirname, + strerror(errno)); + // Continue without device connection notifications + } + + if (regcomp(&_glfw.linux_js.regex, "^js[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))) + { + char path[20]; + regmatch_t match; + + if (regexec(&_glfw.linux_js.regex, entry->d_name, 1, &match, 0) != 0) + continue; + + snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); + if (openJoystickDevice(path)) + count++; + } + + closedir(dir); + } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Linux: Failed to open joystick device directory %s: %s", + dirname, + strerror(errno)); + // Continue with no joysticks detected + } + + qsort(_glfw.linux_js.js, count, sizeof(_GLFWjoystickLinux), compareJoysticks); +#endif // __linux__ + + return GLFW_TRUE; +} + +// Close all opened joystick handles +// +void _glfwTerminateJoysticksLinux(void) +{ +#if defined(__linux__) + int i; + + for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) + { + if (_glfw.linux_js.js[i].present) + { + close(_glfw.linux_js.js[i].fd); + free(_glfw.linux_js.js[i].axes); + free(_glfw.linux_js.js[i].buttons); + free(_glfw.linux_js.js[i].name); + free(_glfw.linux_js.js[i].path); + } + } + + regfree(&_glfw.linux_js.regex); + + if (_glfw.linux_js.inotify > 0) + { + if (_glfw.linux_js.watch > 0) + inotify_rm_watch(_glfw.linux_js.inotify, _glfw.linux_js.watch); + + close(_glfw.linux_js.inotify); + } +#endif // __linux__ +} + +void _glfwPollJoystickEvents(void) +{ +#if defined(__linux__) + ssize_t offset = 0; + char buffer[16384]; + + const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer)); + + while (size > offset) + { + regmatch_t match; + const struct inotify_event* e = (struct inotify_event*) (buffer + offset); + + if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0) + { + char path[20]; + snprintf(path, sizeof(path), "/dev/input/%s", e->name); + openJoystickDevice(path); + } + + offset += sizeof(struct inotify_event) + e->len; + } +#endif +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformJoystickPresent(int joy) +{ + _GLFWjoystickLinux* js = _glfw.linux_js.js + joy; + return pollJoystickEvents(js); +} + +const float* _glfwPlatformGetJoystickAxes(int joy, int* count) +{ + _GLFWjoystickLinux* js = _glfw.linux_js.js + joy; + if (!pollJoystickEvents(js)) + return NULL; + + *count = js->axisCount; + return js->axes; +} + +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) +{ + _GLFWjoystickLinux* js = _glfw.linux_js.js + joy; + if (!pollJoystickEvents(js)) + return NULL; + + *count = js->buttonCount; + return js->buttons; +} + +const char* _glfwPlatformGetJoystickName(int joy) +{ + _GLFWjoystickLinux* js = _glfw.linux_js.js + joy; + if (!pollJoystickEvents(js)) + return NULL; + + return js->name; +} + diff --git a/extern/glfw-3.2.1/src/linux_joystick.h b/extern/glfw-3.2.1/src/linux_joystick.h new file mode 100644 index 0000000..e9d1f2b --- /dev/null +++ b/extern/glfw-3.2.1/src/linux_joystick.h @@ -0,0 +1,68 @@ +//======================================================================== +// GLFW 3.2 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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_linux_joystick_h_ +#define _glfw3_linux_joystick_h_ + +#include + +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoylistLinux linux_js + + +// Linux-specific joystick data +// +typedef struct _GLFWjoystickLinux +{ + GLFWbool present; + int fd; + float* axes; + int axisCount; + unsigned char* buttons; + int buttonCount; + char* name; + char* path; +} _GLFWjoystickLinux; + +// Linux-specific joystick API data +// +typedef struct _GLFWjoylistLinux +{ + _GLFWjoystickLinux js[GLFW_JOYSTICK_LAST + 1]; + +#if defined(__linux__) + int inotify; + int watch; + regex_t regex; +#endif /*__linux__*/ +} _GLFWjoylistLinux; + + +GLFWbool _glfwInitJoysticksLinux(void); +void _glfwTerminateJoysticksLinux(void); + +void _glfwPollJoystickEvents(void); + +#endif // _glfw3_linux_joystick_h_ diff --git a/extern/glfw-3.2.1/src/mir_init.c b/extern/glfw-3.2.1/src/mir_init.c new file mode 100644 index 0000000..3076f5f --- /dev/null +++ b/extern/glfw-3.2.1/src/mir_init.c @@ -0,0 +1,238 @@ +//======================================================================== +// GLFW 3.2 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014-2015 Brandon Schaefer +// +// 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 +#include +#include + + +// Create key code translation tables +// +static void createKeyTables(void) +{ + memset(_glfw.mir.publicKeys, -1, sizeof(_glfw.mir.publicKeys)); + + _glfw.mir.publicKeys[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT; + _glfw.mir.publicKeys[KEY_1] = GLFW_KEY_1; + _glfw.mir.publicKeys[KEY_2] = GLFW_KEY_2; + _glfw.mir.publicKeys[KEY_3] = GLFW_KEY_3; + _glfw.mir.publicKeys[KEY_4] = GLFW_KEY_4; + _glfw.mir.publicKeys[KEY_5] = GLFW_KEY_5; + _glfw.mir.publicKeys[KEY_6] = GLFW_KEY_6; + _glfw.mir.publicKeys[KEY_7] = GLFW_KEY_7; + _glfw.mir.publicKeys[KEY_8] = GLFW_KEY_8; + _glfw.mir.publicKeys[KEY_9] = GLFW_KEY_9; + _glfw.mir.publicKeys[KEY_0] = GLFW_KEY_0; + _glfw.mir.publicKeys[KEY_MINUS] = GLFW_KEY_MINUS; + _glfw.mir.publicKeys[KEY_EQUAL] = GLFW_KEY_EQUAL; + _glfw.mir.publicKeys[KEY_Q] = GLFW_KEY_Q; + _glfw.mir.publicKeys[KEY_W] = GLFW_KEY_W; + _glfw.mir.publicKeys[KEY_E] = GLFW_KEY_E; + _glfw.mir.publicKeys[KEY_R] = GLFW_KEY_R; + _glfw.mir.publicKeys[KEY_T] = GLFW_KEY_T; + _glfw.mir.publicKeys[KEY_Y] = GLFW_KEY_Y; + _glfw.mir.publicKeys[KEY_U] = GLFW_KEY_U; + _glfw.mir.publicKeys[KEY_I] = GLFW_KEY_I; + _glfw.mir.publicKeys[KEY_O] = GLFW_KEY_O; + _glfw.mir.publicKeys[KEY_P] = GLFW_KEY_P; + _glfw.mir.publicKeys[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET; + _glfw.mir.publicKeys[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET; + _glfw.mir.publicKeys[KEY_A] = GLFW_KEY_A; + _glfw.mir.publicKeys[KEY_S] = GLFW_KEY_S; + _glfw.mir.publicKeys[KEY_D] = GLFW_KEY_D; + _glfw.mir.publicKeys[KEY_F] = GLFW_KEY_F; + _glfw.mir.publicKeys[KEY_G] = GLFW_KEY_G; + _glfw.mir.publicKeys[KEY_H] = GLFW_KEY_H; + _glfw.mir.publicKeys[KEY_J] = GLFW_KEY_J; + _glfw.mir.publicKeys[KEY_K] = GLFW_KEY_K; + _glfw.mir.publicKeys[KEY_L] = GLFW_KEY_L; + _glfw.mir.publicKeys[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON; + _glfw.mir.publicKeys[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE; + _glfw.mir.publicKeys[KEY_Z] = GLFW_KEY_Z; + _glfw.mir.publicKeys[KEY_X] = GLFW_KEY_X; + _glfw.mir.publicKeys[KEY_C] = GLFW_KEY_C; + _glfw.mir.publicKeys[KEY_V] = GLFW_KEY_V; + _glfw.mir.publicKeys[KEY_B] = GLFW_KEY_B; + _glfw.mir.publicKeys[KEY_N] = GLFW_KEY_N; + _glfw.mir.publicKeys[KEY_M] = GLFW_KEY_M; + _glfw.mir.publicKeys[KEY_COMMA] = GLFW_KEY_COMMA; + _glfw.mir.publicKeys[KEY_DOT] = GLFW_KEY_PERIOD; + _glfw.mir.publicKeys[KEY_SLASH] = GLFW_KEY_SLASH; + _glfw.mir.publicKeys[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH; + _glfw.mir.publicKeys[KEY_ESC] = GLFW_KEY_ESCAPE; + _glfw.mir.publicKeys[KEY_TAB] = GLFW_KEY_TAB; + _glfw.mir.publicKeys[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT; + _glfw.mir.publicKeys[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT; + _glfw.mir.publicKeys[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL; + _glfw.mir.publicKeys[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL; + _glfw.mir.publicKeys[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT; + _glfw.mir.publicKeys[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT; + _glfw.mir.publicKeys[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER; + _glfw.mir.publicKeys[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER; + _glfw.mir.publicKeys[KEY_MENU] = GLFW_KEY_MENU; + _glfw.mir.publicKeys[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK; + _glfw.mir.publicKeys[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK; + _glfw.mir.publicKeys[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN; + _glfw.mir.publicKeys[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK; + _glfw.mir.publicKeys[KEY_PAUSE] = GLFW_KEY_PAUSE; + _glfw.mir.publicKeys[KEY_DELETE] = GLFW_KEY_DELETE; + _glfw.mir.publicKeys[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE; + _glfw.mir.publicKeys[KEY_ENTER] = GLFW_KEY_ENTER; + _glfw.mir.publicKeys[KEY_HOME] = GLFW_KEY_HOME; + _glfw.mir.publicKeys[KEY_END] = GLFW_KEY_END; + _glfw.mir.publicKeys[KEY_PAGEUP] = GLFW_KEY_PAGE_UP; + _glfw.mir.publicKeys[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN; + _glfw.mir.publicKeys[KEY_INSERT] = GLFW_KEY_INSERT; + _glfw.mir.publicKeys[KEY_LEFT] = GLFW_KEY_LEFT; + _glfw.mir.publicKeys[KEY_RIGHT] = GLFW_KEY_RIGHT; + _glfw.mir.publicKeys[KEY_DOWN] = GLFW_KEY_DOWN; + _glfw.mir.publicKeys[KEY_UP] = GLFW_KEY_UP; + _glfw.mir.publicKeys[KEY_F1] = GLFW_KEY_F1; + _glfw.mir.publicKeys[KEY_F2] = GLFW_KEY_F2; + _glfw.mir.publicKeys[KEY_F3] = GLFW_KEY_F3; + _glfw.mir.publicKeys[KEY_F4] = GLFW_KEY_F4; + _glfw.mir.publicKeys[KEY_F5] = GLFW_KEY_F5; + _glfw.mir.publicKeys[KEY_F6] = GLFW_KEY_F6; + _glfw.mir.publicKeys[KEY_F7] = GLFW_KEY_F7; + _glfw.mir.publicKeys[KEY_F8] = GLFW_KEY_F8; + _glfw.mir.publicKeys[KEY_F9] = GLFW_KEY_F9; + _glfw.mir.publicKeys[KEY_F10] = GLFW_KEY_F10; + _glfw.mir.publicKeys[KEY_F11] = GLFW_KEY_F11; + _glfw.mir.publicKeys[KEY_F12] = GLFW_KEY_F12; + _glfw.mir.publicKeys[KEY_F13] = GLFW_KEY_F13; + _glfw.mir.publicKeys[KEY_F14] = GLFW_KEY_F14; + _glfw.mir.publicKeys[KEY_F15] = GLFW_KEY_F15; + _glfw.mir.publicKeys[KEY_F16] = GLFW_KEY_F16; + _glfw.mir.publicKeys[KEY_F17] = GLFW_KEY_F17; + _glfw.mir.publicKeys[KEY_F18] = GLFW_KEY_F18; + _glfw.mir.publicKeys[KEY_F19] = GLFW_KEY_F19; + _glfw.mir.publicKeys[KEY_F20] = GLFW_KEY_F20; + _glfw.mir.publicKeys[KEY_F21] = GLFW_KEY_F21; + _glfw.mir.publicKeys[KEY_F22] = GLFW_KEY_F22; + _glfw.mir.publicKeys[KEY_F23] = GLFW_KEY_F23; + _glfw.mir.publicKeys[KEY_F24] = GLFW_KEY_F24; + _glfw.mir.publicKeys[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE; + _glfw.mir.publicKeys[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY; + _glfw.mir.publicKeys[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT; + _glfw.mir.publicKeys[KEY_KPPLUS] = GLFW_KEY_KP_ADD; + _glfw.mir.publicKeys[KEY_KP0] = GLFW_KEY_KP_0; + _glfw.mir.publicKeys[KEY_KP1] = GLFW_KEY_KP_1; + _glfw.mir.publicKeys[KEY_KP2] = GLFW_KEY_KP_2; + _glfw.mir.publicKeys[KEY_KP3] = GLFW_KEY_KP_3; + _glfw.mir.publicKeys[KEY_KP4] = GLFW_KEY_KP_4; + _glfw.mir.publicKeys[KEY_KP5] = GLFW_KEY_KP_5; + _glfw.mir.publicKeys[KEY_KP6] = GLFW_KEY_KP_6; + _glfw.mir.publicKeys[KEY_KP7] = GLFW_KEY_KP_7; + _glfw.mir.publicKeys[KEY_KP8] = GLFW_KEY_KP_8; + _glfw.mir.publicKeys[KEY_KP9] = GLFW_KEY_KP_9; + _glfw.mir.publicKeys[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL; + _glfw.mir.publicKeys[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL; + _glfw.mir.publicKeys[KEY_KPENTER] = GLFW_KEY_KP_ENTER; +} + + +////////////////////////////////////////////////////////////////////////// +////// 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 (!_glfwInitThreadLocalStoragePOSIX()) + return GLFW_FALSE; + + if (!_glfwInitJoysticksLinux()) + return GLFW_FALSE; + + _glfwInitTimerPOSIX(); + + // Need the default conf for when we set a NULL cursor + _glfw.mir.default_conf = mir_cursor_configuration_from_name(mir_arrow_cursor_name); + + _glfw.mir.event_queue = calloc(1, sizeof(EventQueue)); + _glfwInitEventQueueMir(_glfw.mir.event_queue); + + error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL); + if (error) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Failed to create event mutex: %s", + strerror(error)); + return GLFW_FALSE; + } + + return GLFW_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + _glfwTerminateEGL(); + _glfwTerminateJoysticksLinux(); + _glfwTerminateThreadLocalStoragePOSIX(); + + _glfwDeleteEventQueueMir(_glfw.mir.event_queue); + + pthread_mutex_destroy(&_glfw.mir.event_mutex); + + 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 +#if defined(__linux__) + " /dev/js" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; +} + diff --git a/extern/glfw-3.2.1/src/mir_monitor.c b/extern/glfw-3.2.1/src/mir_monitor.c new file mode 100644 index 0000000..90aa6c9 --- /dev/null +++ b/extern/glfw-3.2.1/src/mir_monitor.c @@ -0,0 +1,182 @@ +//======================================================================== +// GLFW 3.2 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014-2015 Brandon Schaefer +// +// 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 + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int i, found = 0; + _GLFWmonitor** monitors = NULL; + MirDisplayConfiguration* displayConfig = + mir_connection_create_display_config(_glfw.mir.connection); + + *count = 0; + + for (i = 0; i < displayConfig->num_outputs; i++) + { + const MirDisplayOutput* out = displayConfig->outputs + i; + + if (out->used && + out->connected && + out->num_modes && + out->current_mode < out->num_modes) + { + found++; + monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found); + monitors[i] = _glfwAllocMonitor("Unknown", + out->physical_width_mm, + out->physical_height_mm); + + monitors[i]->mir.x = out->position_x; + monitors[i]->mir.y = out->position_y; + monitors[i]->mir.output_id = out->output_id; + monitors[i]->mir.cur_mode = out->current_mode; + + monitors[i]->modes = _glfwPlatformGetVideoModes(monitors[i], + &monitors[i]->modeCount); + } + } + + mir_display_config_destroy(displayConfig); + + *count = found; + return monitors; +} + +GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->mir.output_id == second->mir.output_id; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + if (xpos) + *xpos = monitor->mir.x; + if (ypos) + *ypos = monitor->mir.y; +} + +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; + MirDisplayConfiguration* displayConfig = + mir_connection_create_display_config(_glfw.mir.connection); + + for (i = 0; i < displayConfig->num_outputs; i++) + { + const MirDisplayOutput* out = displayConfig->outputs + i; + if (out->output_id != monitor->mir.output_id) + continue; + + modes = calloc(out->num_modes, sizeof(GLFWvidmode)); + + for (*found = 0; *found < out->num_modes; (*found)++) + { + modes[*found].width = out->modes[*found].horizontal_resolution; + modes[*found].height = out->modes[*found].vertical_resolution; + modes[*found].refreshRate = out->modes[*found].refresh_rate; + + FillInRGBBitsFromPixelFormat(&modes[*found], out->output_formats[*found]); + } + + break; + } + + mir_display_config_destroy(displayConfig); + + return modes; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + *mode = monitor->modes[monitor->mir.cur_mode]; +} + +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.output_id; +} + diff --git a/extern/glfw-3.2.1/src/mir_platform.h b/extern/glfw-3.2.1/src/mir_platform.h new file mode 100644 index 0000000..8f1cf4e --- /dev/null +++ b/extern/glfw-3.2.1/src/mir_platform.h @@ -0,0 +1,130 @@ +//======================================================================== +// GLFW 3.2 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014-2015 Brandon Schaefer +// +// 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_mir_platform_h_ +#define _glfw3_mir_platform_h_ + +#include +#include +#include + +#include + +typedef VkFlags VkMirSurfaceCreateFlagsKHR; + +typedef struct VkMirSurfaceCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkMirSurfaceCreateFlagsKHR flags; + MirConnection* connection; + MirSurface* mirSurface; +} VkMirSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateMirSurfaceKHR)(VkInstance,const VkMirSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); +typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*); + +#include "posix_tls.h" +#include "posix_time.h" +#include "linux_joystick.h" +#include "xkb_unicode.h" +#include "egl_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.window) +#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 +{ + MirSurface* surface; + int width; + int height; + MirEGLNativeWindowType window; + +} _GLFWwindowMir; + +// Mir-specific per-monitor data +// +typedef struct _GLFWmonitorMir +{ + int cur_mode; + int output_id; + int x; + int y; + +} _GLFWmonitorMir; + +// Mir-specific global data +// +typedef struct _GLFWlibraryMir +{ + MirConnection* connection; + MirEGLNativeDisplayType display; + MirCursorConfiguration* default_conf; + EventQueue* event_queue; + + short int publicKeys[256]; + + pthread_mutex_t event_mutex; + pthread_cond_t event_cond; + +} _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* custom_cursor; +} _GLFWcursorMir; + + +extern void _glfwInitEventQueueMir(EventQueue* queue); +extern void _glfwDeleteEventQueueMir(EventQueue* queue); + +#endif // _glfw3_mir_platform_h_ diff --git a/extern/glfw-3.2.1/src/mir_window.c b/extern/glfw-3.2.1/src/mir_window.c new file mode 100644 index 0000000..411f906 --- /dev/null +++ b/extern/glfw-3.2.1/src/mir_window.c @@ -0,0 +1,848 @@ +//======================================================================== +// GLFW 3.2 Mir - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014-2015 Brandon Schaefer +// +// 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 +#include +#include + + +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* new_node = calloc(1, sizeof(EventNode)); + new_node->event = mir_event_ref(event); + new_node->window = context; + + return new_node; +} + +static void enqueueEvent(const MirEvent* event, _GLFWwindow* context) +{ + pthread_mutex_lock(&_glfw.mir.event_mutex); + + EventNode* new_node = newEventNode(event, context); + TAILQ_INSERT_TAIL(&_glfw.mir.event_queue->head, new_node, entries); + + pthread_cond_signal(&_glfw.mir.event_cond); + + pthread_mutex_unlock(&_glfw.mir.event_mutex); +} + +static EventNode* dequeueEvent(EventQueue* queue) +{ + EventNode* node = NULL; + + pthread_mutex_lock(&_glfw.mir.event_mutex); + + node = queue->head.tqh_first; + + if (node) + TAILQ_REMOVE(&queue->head, node, entries); + + pthread_mutex_unlock(&_glfw.mir.event_mutex); + + return node; +} + +/* FIXME Soon to be changed upstream mir! So we can use an egl config to figure out + the best pixel format! +*/ +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.publicKeys) / sizeof(_glfw.mir.publicKeys[0])) + return _glfw.mir.publicKeys[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) +{ + int current_x = window->virtualCursorPosX; + int current_y = window->virtualCursorPosY; + int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x); + int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y); + int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll); + int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll); + + _glfwInputCursorPos(window, x, y); + if (dx != 0 || dy != 0) + _glfwInputScroll(window, dx, dy); +} + +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(MirSurface* surface, const MirEvent* event, void* context) +{ + enqueueEvent(event, context); +} + +static GLFWbool createSurface(_GLFWwindow* window) +{ + MirSurfaceSpec* 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_connection_create_spec_for_normal_surface(_glfw.mir.connection, + window->mir.width, + window->mir.height, + pixel_format); + + mir_surface_spec_set_buffer_usage(spec, buffer_usage); + mir_surface_spec_set_name(spec, "MirSurface"); + + window->mir.surface = mir_surface_create_sync(spec); + mir_surface_spec_release(spec); + + if (!mir_surface_is_valid(window->mir.surface)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unable to create surface: %s", + mir_surface_get_error_message(window->mir.surface)); + + return GLFW_FALSE; + } + + mir_surface_set_event_handler(window->mir.surface, addNewEvent, window); + + return GLFW_TRUE; +} + +////////////////////////////////////////////////////////////////////////// +////// 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_surface_set_state(window->mir.surface, mir_surface_state_fullscreen); + + if (wndconfig->width > mode.width || wndconfig->height > mode.height) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Requested surface size too large: %ix%i", + wndconfig->width, wndconfig->height); + + return GLFW_FALSE; + } + } + + window->mir.width = wndconfig->width; + window->mir.height = wndconfig->height; + + if (!createSurface(window)) + return GLFW_FALSE; + + window->mir.window = mir_buffer_stream_get_egl_native_window( + mir_surface_get_buffer_stream(window->mir.surface)); + + if (ctxconfig->client != GLFW_NO_API) + { + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + + return GLFW_TRUE; +} + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (mir_surface_is_valid(window->mir.surface)) + { + mir_surface_release_sync(window->mir.surface); + window->mir.surface = NULL; + } + + if (window->context.destroy) + window->context.destroy(window); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ + MirSurfaceSpec* spec; + const char* e_title = title ? title : ""; + + spec = mir_connection_create_spec_for_changes(_glfw.mir.connection); + mir_surface_spec_set_name(spec, e_title); + + mir_surface_apply_spec(window->mir.surface, spec); + mir_surface_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) +{ + MirSurfaceSpec* spec; + + spec = mir_connection_create_spec_for_changes(_glfw.mir.connection); + mir_surface_spec_set_width (spec, width); + mir_surface_spec_set_height(spec, height); + + mir_surface_apply_spec(window->mir.surface, spec); + mir_surface_spec_release(spec); +} + +void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, + int minwidth, int minheight, + int maxwidth, int maxheight) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); +} + +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 _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ + mir_surface_set_state(window->mir.surface, mir_surface_state_minimized); +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ + mir_surface_set_state(window->mir.surface, mir_surface_state_restored); +} + +void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + MirSurfaceSpec* spec; + + spec = mir_connection_create_spec_for_changes(_glfw.mir.connection); + mir_surface_spec_set_state(spec, mir_surface_state_hidden); + + mir_surface_apply_spec(window->mir.surface, spec); + mir_surface_spec_release(spec); +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + MirSurfaceSpec* spec; + + spec = mir_connection_create_spec_for_changes(_glfw.mir.connection); + mir_surface_spec_set_state(spec, mir_surface_state_restored); + + mir_surface_apply_spec(window->mir.surface, spec); + mir_surface_spec_release(spec); +} + +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) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); + return GLFW_FALSE; +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); + return GLFW_FALSE; +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + return mir_surface_get_visibility(window->mir.surface) == mir_surface_visibility_exposed; +} + +int _glfwPlatformWindowMaximized(_GLFWwindow* window) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); + return GLFW_FALSE; +} + +void _glfwPlatformPollEvents(void) +{ + EventNode* node = NULL; + + while ((node = dequeueEvent(_glfw.mir.event_queue))) + { + handleEvent(node->event, node->window); + deleteNode(_glfw.mir.event_queue, node); + } +} + +void _glfwPlatformWaitEvents(void) +{ + pthread_mutex_lock(&_glfw.mir.event_mutex); + + if (emptyEventQueue(_glfw.mir.event_queue)) + pthread_cond_wait(&_glfw.mir.event_cond, &_glfw.mir.event_mutex); + + pthread_mutex_unlock(&_glfw.mir.event_mutex); + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformWaitEventsTimeout(double timeout) +{ + pthread_mutex_lock(&_glfw.mir.event_mutex); + + if (emptyEventQueue(_glfw.mir.event_queue)) + { + 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.event_cond, &_glfw.mir.event_mutex, &time); + } + + pthread_mutex_unlock(&_glfw.mir.event_mutex); + + _glfwPlatformPollEvents(); +} + +void _glfwPlatformPostEmptyEvent(void) +{ +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + if (width) + *width = window->mir.width; + if (height) + *height = window->mir.height; +} + +// FIXME implement +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + MirBufferStream* stream; + MirPixelFormat pixel_format = findValidPixelFormat(); + + int i_w = image->width; + int i_h = image->height; + + if (pixel_format == mir_pixel_format_invalid) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unable to find a correct pixel format"); + return GLFW_FALSE; + } + + stream = mir_connection_create_buffer_stream_sync(_glfw.mir.connection, + i_w, i_h, + pixel_format, + mir_buffer_usage_software); + + cursor->mir.conf = mir_cursor_configuration_from_buffer_stream(stream, xhot, yhot); + + char* dest; + unsigned char *pixels; + int i, r_stride, bytes_per_pixel, bytes_per_row; + + MirGraphicsRegion region; + mir_buffer_stream_get_graphics_region(stream, ®ion); + + // FIXME Figure this out based on the current_pf + bytes_per_pixel = 4; + bytes_per_row = bytes_per_pixel * i_w; + + dest = region.vaddr; + pixels = image->pixels; + + r_stride = region.stride; + + for (i = 0; i < i_h; i++) + { + memcpy(dest, pixels, bytes_per_row); + dest += r_stride; + pixels += r_stride; + } + + cursor->mir.custom_cursor = stream; + + return GLFW_TRUE; +} + +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) +{ + const char* cursor_name = getSystemCursorName(shape); + + if (cursor_name) + { + cursor->mir.conf = mir_cursor_configuration_from_name(cursor_name); + cursor->mir.custom_cursor = NULL; + + return GLFW_TRUE; + } + + return GLFW_FALSE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ + if (cursor->mir.conf) + mir_cursor_configuration_destroy(cursor->mir.conf); + if (cursor->mir.custom_cursor) + mir_buffer_stream_release_sync(cursor->mir.custom_cursor); +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ + if (cursor && cursor->mir.conf) + { + mir_wait_for(mir_surface_configure_cursor(window->mir.surface, cursor->mir.conf)); + if (cursor->mir.custom_cursor) + { + mir_buffer_stream_swap_buffers_sync(cursor->mir.custom_cursor); + } + } + else + { + mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.default_conf)); + } +} + +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) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); +} + +const char* _glfwPlatformGetKeyName(int key, int scancode) +{ + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); + return NULL; +} + +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; +} + +char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_mir_surface) + return NULL; + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + extensions[1] = strdup("VK_KHR_mir_surface"); + + *count = 2; + return extensions; +} + +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; + VkMirSurfaceCreateInfoKHR sci; + PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR; + + vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR"); + if (!vkCreateMirSurfaceKHR) + { + _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.mirSurface = window->mir.surface; + + err = vkCreateMirSurfaceKHR(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 MirSurface* glfwGetMirWindow(GLFWwindow* handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return window->mir.surface; +} + diff --git a/extern/glfw-3.2.1/src/monitor.c b/extern/glfw-3.2.1/src/monitor.c new file mode 100644 index 0000000..b6c312d --- /dev/null +++ b/extern/glfw-3.2.1/src/monitor.c @@ -0,0 +1,477 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include +#include +#include +#include + + +// 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 _glfwInputMonitorChange(void) +{ + int i, j, monitorCount = _glfw.monitorCount; + _GLFWmonitor** monitors = _glfw.monitors; + + _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); + + // Re-use still connected monitor objects + + for (i = 0; i < _glfw.monitorCount; i++) + { + for (j = 0; j < monitorCount; j++) + { + if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j])) + { + _glfwFreeMonitor(_glfw.monitors[i]); + _glfw.monitors[i] = monitors[j]; + break; + } + } + } + + // Find and report disconnected monitors (not in the new list) + + for (i = 0; i < monitorCount; i++) + { + _GLFWwindow* window; + + for (j = 0; j < _glfw.monitorCount; j++) + { + if (monitors[i] == _glfw.monitors[j]) + break; + } + + if (j < _glfw.monitorCount) + continue; + + for (window = _glfw.windowListHead; window; window = window->next) + { + if (window->monitor == monitors[i]) + { + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0); + } + } + + if (_glfw.callbacks.monitor) + _glfw.callbacks.monitor((GLFWmonitor*) monitors[i], GLFW_DISCONNECTED); + } + + // Find and report newly connected monitors (not in the old list) + // Re-used monitor objects are then removed from the old list to avoid + // having them destroyed at the end of this function + + for (i = 0; i < _glfw.monitorCount; i++) + { + for (j = 0; j < monitorCount; j++) + { + if (_glfw.monitors[i] == monitors[j]) + { + monitors[j] = NULL; + break; + } + } + + if (j < monitorCount) + continue; + + if (_glfw.callbacks.monitor) + _glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED); + } + + _glfwFreeMonitors(monitors, monitorCount); +} + +void _glfwInputMonitorWindowChange(_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->name = strdup(name); + monitor->widthMM = widthMM; + monitor->heightMM = heightMM; + + 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)); +} + +void _glfwFreeMonitors(_GLFWmonitor** monitors, int count) +{ + int i; + + for (i = 0; i < count; i++) + _glfwFreeMonitor(monitors[i]); + + free(monitors); +} + +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 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; + + _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->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/extern/glfw-3.2.1/src/nsgl_context.h b/extern/glfw-3.2.1/src/nsgl_context.h new file mode 100644 index 0000000..1304f2e --- /dev/null +++ b/extern/glfw-3.2.1/src/nsgl_context.h @@ -0,0 +1,60 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// +// 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_nsgl_context_h_ +#define _glfw3_nsgl_context_h_ + +#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); + +#endif // _glfw3_nsgl_context_h_ diff --git a/extern/glfw-3.2.1/src/nsgl_context.m b/extern/glfw-3.2.1/src/nsgl_context.m new file mode 100644 index 0000000..22ebdba --- /dev/null +++ b/extern/glfw-3.2.1/src/nsgl_context.m @@ -0,0 +1,308 @@ +//======================================================================== +// GLFW 3.2 OS X - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2009-2016 Camilla Berglund +// +// 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]; + + _glfwPlatformSetCurrentContext(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 = _glfwPlatformGetCurrentContext(); + + 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) +{ + unsigned int attributeCount = 0; + + if (ctxconfig->client == GLFW_OPENGL_ES_API) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "NSGL: OpenGL ES is not available on OS X"); + return GLFW_FALSE; + } + + if (ctxconfig->major == 3 && ctxconfig->minor < 2) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X does not support OpenGL 3.0 or 3.1"); + return GLFW_FALSE; + } + + if (ctxconfig->major > 2) + { + if (!ctxconfig->forward) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X only supports forward-compatible contexts for OpenGL 3.2 and above"); + return GLFW_FALSE; + } + + if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "NSGL: The targeted version of OS X only supports core profile contexts for OpenGL 3.2 and above"); + return GLFW_FALSE; + } + } + + // Context robustness modes (GL_KHR_robustness) are not yet supported on + // OS X but are not a hard constraint, so ignore and continue + + // Context release behaviors (GL_KHR_context_flush_control) are not yet + // supported on OS X but are not a hard constraint, so ignore and continue + +#define ADD_ATTR(x) { attributes[attributeCount++] = x; } +#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } + + // Arbitrary array size here + NSOpenGLPixelFormatAttribute attributes[40]; + + ADD_ATTR(NSOpenGLPFAAccelerated); + ADD_ATTR(NSOpenGLPFAClosestPolicy); + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 + if (ctxconfig->major >= 4) + { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); + } + else +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + if (ctxconfig->major >= 3) + { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + } + + if (ctxconfig->major <= 2) + { + if (fbconfig->auxBuffers != GLFW_DONT_CARE) + ADD_ATTR2(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; + + ADD_ATTR2(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; + + // OS X needs non-zero color size, so set reasonable values + if (colorBits == 0) + colorBits = 24; + else if (colorBits < 15) + colorBits = 15; + + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + } + + if (fbconfig->alphaBits != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); + + if (fbconfig->depthBits != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); + + if (fbconfig->stencilBits != GLFW_DONT_CARE) + ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); + + if (fbconfig->stereo) + ADD_ATTR(NSOpenGLPFAStereo); + + if (fbconfig->doublebuffer) + ADD_ATTR(NSOpenGLPFADoubleBuffer); + + if (fbconfig->samples != GLFW_DONT_CARE) + { + if (fbconfig->samples == 0) + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 0); + } + else + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } + } + + // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB + // framebuffer, so there's no need (and no way) to request it + + ADD_ATTR(0); + +#undef ADD_ATTR +#undef ADD_ATTR2 + + window->context.nsgl.pixelFormat = + [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + 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; + } + + [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/extern/glfw-3.2.1/src/posix_time.c b/extern/glfw-3.2.1/src/posix_time.c new file mode 100644 index 0000000..8d0d4cd --- /dev/null +++ b/extern/glfw-3.2.1/src/posix_time.c @@ -0,0 +1,85 @@ +//======================================================================== +// GLFW 3.2 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialise timer +// +void _glfwInitTimerPOSIX(void) +{ +#if defined(CLOCK_MONOTONIC) + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + _glfw.posix_time.monotonic = GLFW_TRUE; + _glfw.posix_time.frequency = 1000000000; + } + else +#endif + { + _glfw.posix_time.monotonic = GLFW_FALSE; + _glfw.posix_time.frequency = 1000000; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +uint64_t _glfwPlatformGetTimerValue(void) +{ +#if defined(CLOCK_MONOTONIC) + if (_glfw.posix_time.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.posix_time.frequency; +} + diff --git a/extern/glfw-3.2.1/src/posix_time.h b/extern/glfw-3.2.1/src/posix_time.h new file mode 100644 index 0000000..4730ca7 --- /dev/null +++ b/extern/glfw-3.2.1/src/posix_time.h @@ -0,0 +1,48 @@ +//======================================================================== +// GLFW 3.2 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_posix_time_h_ +#define _glfw3_posix_time_h_ + +#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimePOSIX posix_time + +#include + + +// POSIX-specific global timer data +// +typedef struct _GLFWtimePOSIX +{ + GLFWbool monotonic; + uint64_t frequency; + +} _GLFWtimePOSIX; + + +void _glfwInitTimerPOSIX(void); + +#endif // _glfw3_posix_time_h_ diff --git a/extern/glfw-3.2.1/src/posix_tls.c b/extern/glfw-3.2.1/src/posix_tls.c new file mode 100644 index 0000000..c9517c6 --- /dev/null +++ b/extern/glfw-3.2.1/src/posix_tls.c @@ -0,0 +1,68 @@ +//======================================================================== +// GLFW 3.2 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 ////// +////////////////////////////////////////////////////////////////////////// + +GLFWbool _glfwInitThreadLocalStoragePOSIX(void) +{ + if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "POSIX: Failed to create context TLS"); + return GLFW_FALSE; + } + + _glfw.posix_tls.allocated = GLFW_TRUE; + return GLFW_TRUE; +} + +void _glfwTerminateThreadLocalStoragePOSIX(void) +{ + if (_glfw.posix_tls.allocated) + pthread_key_delete(_glfw.posix_tls.context); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformSetCurrentContext(_GLFWwindow* context) +{ + pthread_setspecific(_glfw.posix_tls.context, context); +} + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return pthread_getspecific(_glfw.posix_tls.context); +} + diff --git a/extern/glfw-3.2.1/src/posix_tls.h b/extern/glfw-3.2.1/src/posix_tls.h new file mode 100644 index 0000000..0d408ae --- /dev/null +++ b/extern/glfw-3.2.1/src/posix_tls.h @@ -0,0 +1,49 @@ +//======================================================================== +// GLFW 3.2 POSIX - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_posix_tls_h_ +#define _glfw3_posix_tls_h_ + +#include + +#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsPOSIX posix_tls + + +// POSIX-specific global TLS data +// +typedef struct _GLFWtlsPOSIX +{ + GLFWbool allocated; + pthread_key_t context; + +} _GLFWtlsPOSIX; + + +GLFWbool _glfwInitThreadLocalStoragePOSIX(void); +void _glfwTerminateThreadLocalStoragePOSIX(void); + +#endif // _glfw3_posix_tls_h_ diff --git a/extern/glfw-3.2.1/src/vulkan.c b/extern/glfw-3.2.1/src/vulkan.c new file mode 100644 index 0000000..20011de --- /dev/null +++ b/extern/glfw-3.2.1/src/vulkan.c @@ -0,0 +1,302 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWbool _glfwInitVulkan(void) +{ + VkResult err; + VkExtensionProperties* ep; + uint32_t i, count; + +#if !defined(_GLFW_VULKAN_STATIC) +#if defined(_GLFW_WIN32) + const char* name = "vulkan-1.dll"; +#else + const char* name = "libvulkan.so.1"; +#endif + + if (_glfw.vk.available) + return GLFW_TRUE; + + _glfw.vk.handle = _glfw_dlopen(name); + if (!_glfw.vk.handle) + 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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "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_PLATFORM_ERROR, + "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 (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) + _glfw.vk.KHR_win32_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) + _glfw.vk.KHR_xlib_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) + _glfw.vk.KHR_xcb_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) + _glfw.vk.KHR_wayland_surface = GLFW_TRUE; + if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0) + _glfw.vk.KHR_mir_surface = GLFW_TRUE; + } + + free(ep); + + _glfw.vk.available = GLFW_TRUE; + + if (_glfw.vk.KHR_surface) + { + _glfw.vk.extensions = + _glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount); + } + + return GLFW_TRUE; +} + +void _glfwTerminateVulkan(void) +{ + uint32_t i; + + for (i = 0; i < _glfw.vk.extensionCount; i++) + free(_glfw.vk.extensions[i]); + free(_glfw.vk.extensions); + + if (_glfw.vk.handle) + _glfw_dlclose(_glfw.vk.handle); +} + +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(); +} + +GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count) +{ + *count = 0; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (!_glfwInitVulkan()) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available"); + return NULL; + } + + *count = _glfw.vk.extensionCount; + return (const char**) _glfw.vk.extensions; +} + +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, + const char* procname) +{ + GLFWvkproc proc; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + if (!_glfwInitVulkan()) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available"); + return NULL; + } + + proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname); + if (!proc) + proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname); + + return proc; +} + +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + + if (!_glfwInitVulkan()) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available"); + return GLFW_FALSE; + } + + if (!_glfw.vk.extensions) + { + _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(window != NULL); + assert(surface != NULL); + + *surface = VK_NULL_HANDLE; + + _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED); + + if (!_glfwInitVulkan()) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available"); + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (!_glfw.vk.extensions) + { + _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/extern/glfw-3.2.1/src/wgl_context.c b/extern/glfw-3.2.1/src/wgl_context.c new file mode 100644 index 0000000..696c4cb --- /dev/null +++ b/extern/glfw-3.2.1/src/wgl_context.c @@ -0,0 +1,718 @@ +//======================================================================== +// GLFW 3.2 WGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include + + +// 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)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve pixel format attribute %i", + attrib); + return 0; + } + + return value; +} + +// Return a list of available and usable framebuffer configs +// +static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired) +{ + _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 (_glfw.wgl.ARB_framebuffer_sRGB || + _glfw.wgl.EXT_framebuffer_sRGB) + { + if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) + u->sRGB = GLFW_TRUE; + } + } + else + { + PIXELFORMATDESCRIPTOR pfd; + + // Get pixel format attributes through legacy PFDs + + 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(desired, 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; +} + +// Returns whether desktop compositing is enabled +// +static GLFWbool isCompositionEnabled(void) +{ + BOOL enabled; + + if (!_glfw_DwmIsCompositionEnabled) + return FALSE; + + if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK) + return FALSE; + + return enabled; +} + +static void makeContextCurrentWGL(_GLFWwindow* window) +{ + if (window) + { + if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle)) + _glfwPlatformSetCurrentContext(window); + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to make context current"); + _glfwPlatformSetCurrentContext(NULL); + } + } + else + { + if (!wglMakeCurrent(NULL, NULL)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to clear current context"); + } + + _glfwPlatformSetCurrentContext(NULL); + } +} + +static void swapBuffersWGL(_GLFWwindow* window) +{ + // HACK: Use DwmFlush when desktop composition is enabled + if (isCompositionEnabled() && !window->monitor) + { + int count = abs(window->context.wgl.interval); + while (count--) + _glfw_DwmFlush(); + } + + SwapBuffers(window->context.wgl.dc); +} + +static void swapIntervalWGL(int interval) +{ + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + window->context.wgl.interval = interval; + + // HACK: Disable WGL swap interval when desktop composition is enabled to + // avoid interfering with DWM vsync + if (isCompositionEnabled() && !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)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to set pixel format for dummy context"); + return; + } + + rc = wglCreateContext(dc); + if (!rc) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to create dummy context"); + return; + } + + if (!wglMakeCurrent(dc, rc)) + { + wglDeleteContext(rc); + + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to make dummy context current"); + 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.EXT_swap_control = + extensionSupportedWGL("WGL_EXT_swap_control"); + _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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to load opengl32.dll"); + return GLFW_FALSE; + } + + _glfw.wgl.CreateContext = (WGLCREATECONTEXT_T) + GetProcAddress(_glfw.wgl.instance, "wglCreateContext"); + _glfw.wgl.DeleteContext = (WGLDELETECONTEXT_T) + GetProcAddress(_glfw.wgl.instance, "wglDeleteContext"); + _glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T) + GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress"); + _glfw.wgl.GetCurrentDC = (WGLGETCURRENTDC_T) + GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC"); + _glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T) + GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent"); + _glfw.wgl.ShareLists = (WGLSHARELISTS_T) + GetProcAddress(_glfw.wgl.instance, "wglShareLists"); + + return GLFW_TRUE; +} + +// Terminate WGL +// +void _glfwTerminateWGL(void) +{ + if (_glfw.wgl.instance) + FreeLibrary(_glfw.wgl.instance); +} + +#define setWGLattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ +} + +// 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, fbconfig); + if (!pixelFormat) + return GLFW_FALSE; + + if (!DescribePixelFormat(window->context.wgl.dc, + pixelFormat, sizeof(pfd), &pfd)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve PFD for selected pixel format"); + return GLFW_FALSE; + } + + if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd)) + { + _glfwInputError(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->noerror) + flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; + + if (ctxconfig->robustness) + { + if (_glfw.wgl.ARB_create_context_robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + { + setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + WGL_NO_RESET_NOTIFICATION_ARB); + } + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + { + setWGLattrib(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) + { + setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, + WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + } + else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) + { + setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, + WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + } + } + } + + // 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) + { + setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + } + + if (flags) + setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags); + + if (mask) + setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); + + setWGLattrib(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 (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) + { + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "WGL: Failed to create OpenGL context"); + return GLFW_FALSE; + } + + if (share) + { + if (!wglShareLists(share, window->context.wgl.handle)) + { + _glfwInputError(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 setWGLattrib + + +////////////////////////////////////////////////////////////////////////// +////// 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/extern/glfw-3.2.1/src/wgl_context.h b/extern/glfw-3.2.1/src/wgl_context.h new file mode 100644 index 0000000..b837d43 --- /dev/null +++ b/extern/glfw-3.2.1/src/wgl_context.h @@ -0,0 +1,157 @@ +//======================================================================== +// GLFW 3.2 WGL - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_wgl_context_h_ +#define _glfw3_wgl_context_h_ + + +#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 ERROR_INVALID_VERSION_ARB 0x2095 +#define ERROR_INVALID_PROFILE_ARB 0x2096 + +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 * WGLCREATECONTEXT_T)(HDC); +typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC); +typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR); +typedef HDC (WINAPI * WGLGETCURRENTDC_T)(void); +typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC); +typedef BOOL (WINAPI * WGLSHARELISTS_T)(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; + WGLCREATECONTEXT_T CreateContext; + WGLDELETECONTEXT_T DeleteContext; + WGLGETPROCADDRESS_T GetProcAddress; + WGLGETCURRENTDC_T GetCurrentDC; + WGLMAKECURRENT_T MakeCurrent; + WGLSHARELISTS_T ShareLists; + + GLFWbool extensionsLoaded; + + PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT; + PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB; + PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT; + PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB; + PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; + GLFWbool EXT_swap_control; + 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_context_flush_control; + +} _GLFWlibraryWGL; + + +GLFWbool _glfwInitWGL(void); +void _glfwTerminateWGL(void); +GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig); + +#endif // _glfw3_wgl_context_h_ diff --git a/extern/glfw-3.2.1/src/win32_init.c b/extern/glfw-3.2.1/src/win32_init.c new file mode 100644 index 0000000..b2a0a67 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_init.c @@ -0,0 +1,473 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include + +#include +DEFINE_GUID(GUID_DEVINTERFACE_HID,0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30); + +#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) + +// Applications 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; + +// Applications 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 + +// Load necessary libraries (DLLs) +// +static GLFWbool loadLibraries(void) +{ + _glfw.win32.winmm.instance = LoadLibraryA("winmm.dll"); + if (!_glfw.win32.winmm.instance) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load winmm.dll"); + return GLFW_FALSE; + } + + _glfw.win32.winmm.timeGetTime = (TIMEGETTIME_T) + GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime"); + + _glfw.win32.user32.instance = LoadLibraryA("user32.dll"); + if (!_glfw.win32.user32.instance) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load user32.dll"); + return GLFW_FALSE; + } + + _glfw.win32.user32.SetProcessDPIAware = (SETPROCESSDPIAWARE_T) + GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); + _glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T) + GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); + + _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll"); + if (_glfw.win32.dinput8.instance) + { + _glfw.win32.dinput8.DirectInput8Create = (DIRECTINPUT8CREATE_T) + 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.XInputGetCapabilities = (XINPUTGETCAPABILITIES_T) + GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities"); + _glfw.win32.xinput.XInputGetState = (XINPUTGETSTATE_T) + GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState"); + + break; + } + } + } + + _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll"); + if (_glfw.win32.dwmapi.instance) + { + _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) + GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); + _glfw.win32.dwmapi.DwmFlush = (DWMFLUSH_T) + GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush"); + } + + _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); + if (_glfw.win32.shcore.instance) + { + _glfw.win32.shcore.SetProcessDpiAwareness = (SETPROCESSDPIAWARENESS_T) + GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); + } + + 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.publicKeys, -1, sizeof(_glfw.win32.publicKeys)); + memset(_glfw.win32.nativeKeys, -1, sizeof(_glfw.win32.nativeKeys)); + + _glfw.win32.publicKeys[0x00B] = GLFW_KEY_0; + _glfw.win32.publicKeys[0x002] = GLFW_KEY_1; + _glfw.win32.publicKeys[0x003] = GLFW_KEY_2; + _glfw.win32.publicKeys[0x004] = GLFW_KEY_3; + _glfw.win32.publicKeys[0x005] = GLFW_KEY_4; + _glfw.win32.publicKeys[0x006] = GLFW_KEY_5; + _glfw.win32.publicKeys[0x007] = GLFW_KEY_6; + _glfw.win32.publicKeys[0x008] = GLFW_KEY_7; + _glfw.win32.publicKeys[0x009] = GLFW_KEY_8; + _glfw.win32.publicKeys[0x00A] = GLFW_KEY_9; + _glfw.win32.publicKeys[0x01E] = GLFW_KEY_A; + _glfw.win32.publicKeys[0x030] = GLFW_KEY_B; + _glfw.win32.publicKeys[0x02E] = GLFW_KEY_C; + _glfw.win32.publicKeys[0x020] = GLFW_KEY_D; + _glfw.win32.publicKeys[0x012] = GLFW_KEY_E; + _glfw.win32.publicKeys[0x021] = GLFW_KEY_F; + _glfw.win32.publicKeys[0x022] = GLFW_KEY_G; + _glfw.win32.publicKeys[0x023] = GLFW_KEY_H; + _glfw.win32.publicKeys[0x017] = GLFW_KEY_I; + _glfw.win32.publicKeys[0x024] = GLFW_KEY_J; + _glfw.win32.publicKeys[0x025] = GLFW_KEY_K; + _glfw.win32.publicKeys[0x026] = GLFW_KEY_L; + _glfw.win32.publicKeys[0x032] = GLFW_KEY_M; + _glfw.win32.publicKeys[0x031] = GLFW_KEY_N; + _glfw.win32.publicKeys[0x018] = GLFW_KEY_O; + _glfw.win32.publicKeys[0x019] = GLFW_KEY_P; + _glfw.win32.publicKeys[0x010] = GLFW_KEY_Q; + _glfw.win32.publicKeys[0x013] = GLFW_KEY_R; + _glfw.win32.publicKeys[0x01F] = GLFW_KEY_S; + _glfw.win32.publicKeys[0x014] = GLFW_KEY_T; + _glfw.win32.publicKeys[0x016] = GLFW_KEY_U; + _glfw.win32.publicKeys[0x02F] = GLFW_KEY_V; + _glfw.win32.publicKeys[0x011] = GLFW_KEY_W; + _glfw.win32.publicKeys[0x02D] = GLFW_KEY_X; + _glfw.win32.publicKeys[0x015] = GLFW_KEY_Y; + _glfw.win32.publicKeys[0x02C] = GLFW_KEY_Z; + + _glfw.win32.publicKeys[0x028] = GLFW_KEY_APOSTROPHE; + _glfw.win32.publicKeys[0x02B] = GLFW_KEY_BACKSLASH; + _glfw.win32.publicKeys[0x033] = GLFW_KEY_COMMA; + _glfw.win32.publicKeys[0x00D] = GLFW_KEY_EQUAL; + _glfw.win32.publicKeys[0x029] = GLFW_KEY_GRAVE_ACCENT; + _glfw.win32.publicKeys[0x01A] = GLFW_KEY_LEFT_BRACKET; + _glfw.win32.publicKeys[0x00C] = GLFW_KEY_MINUS; + _glfw.win32.publicKeys[0x034] = GLFW_KEY_PERIOD; + _glfw.win32.publicKeys[0x01B] = GLFW_KEY_RIGHT_BRACKET; + _glfw.win32.publicKeys[0x027] = GLFW_KEY_SEMICOLON; + _glfw.win32.publicKeys[0x035] = GLFW_KEY_SLASH; + _glfw.win32.publicKeys[0x056] = GLFW_KEY_WORLD_2; + + _glfw.win32.publicKeys[0x00E] = GLFW_KEY_BACKSPACE; + _glfw.win32.publicKeys[0x153] = GLFW_KEY_DELETE; + _glfw.win32.publicKeys[0x14F] = GLFW_KEY_END; + _glfw.win32.publicKeys[0x01C] = GLFW_KEY_ENTER; + _glfw.win32.publicKeys[0x001] = GLFW_KEY_ESCAPE; + _glfw.win32.publicKeys[0x147] = GLFW_KEY_HOME; + _glfw.win32.publicKeys[0x152] = GLFW_KEY_INSERT; + _glfw.win32.publicKeys[0x15D] = GLFW_KEY_MENU; + _glfw.win32.publicKeys[0x151] = GLFW_KEY_PAGE_DOWN; + _glfw.win32.publicKeys[0x149] = GLFW_KEY_PAGE_UP; + _glfw.win32.publicKeys[0x045] = GLFW_KEY_PAUSE; + _glfw.win32.publicKeys[0x146] = GLFW_KEY_PAUSE; + _glfw.win32.publicKeys[0x039] = GLFW_KEY_SPACE; + _glfw.win32.publicKeys[0x00F] = GLFW_KEY_TAB; + _glfw.win32.publicKeys[0x03A] = GLFW_KEY_CAPS_LOCK; + _glfw.win32.publicKeys[0x145] = GLFW_KEY_NUM_LOCK; + _glfw.win32.publicKeys[0x046] = GLFW_KEY_SCROLL_LOCK; + _glfw.win32.publicKeys[0x03B] = GLFW_KEY_F1; + _glfw.win32.publicKeys[0x03C] = GLFW_KEY_F2; + _glfw.win32.publicKeys[0x03D] = GLFW_KEY_F3; + _glfw.win32.publicKeys[0x03E] = GLFW_KEY_F4; + _glfw.win32.publicKeys[0x03F] = GLFW_KEY_F5; + _glfw.win32.publicKeys[0x040] = GLFW_KEY_F6; + _glfw.win32.publicKeys[0x041] = GLFW_KEY_F7; + _glfw.win32.publicKeys[0x042] = GLFW_KEY_F8; + _glfw.win32.publicKeys[0x043] = GLFW_KEY_F9; + _glfw.win32.publicKeys[0x044] = GLFW_KEY_F10; + _glfw.win32.publicKeys[0x057] = GLFW_KEY_F11; + _glfw.win32.publicKeys[0x058] = GLFW_KEY_F12; + _glfw.win32.publicKeys[0x064] = GLFW_KEY_F13; + _glfw.win32.publicKeys[0x065] = GLFW_KEY_F14; + _glfw.win32.publicKeys[0x066] = GLFW_KEY_F15; + _glfw.win32.publicKeys[0x067] = GLFW_KEY_F16; + _glfw.win32.publicKeys[0x068] = GLFW_KEY_F17; + _glfw.win32.publicKeys[0x069] = GLFW_KEY_F18; + _glfw.win32.publicKeys[0x06A] = GLFW_KEY_F19; + _glfw.win32.publicKeys[0x06B] = GLFW_KEY_F20; + _glfw.win32.publicKeys[0x06C] = GLFW_KEY_F21; + _glfw.win32.publicKeys[0x06D] = GLFW_KEY_F22; + _glfw.win32.publicKeys[0x06E] = GLFW_KEY_F23; + _glfw.win32.publicKeys[0x076] = GLFW_KEY_F24; + _glfw.win32.publicKeys[0x038] = GLFW_KEY_LEFT_ALT; + _glfw.win32.publicKeys[0x01D] = GLFW_KEY_LEFT_CONTROL; + _glfw.win32.publicKeys[0x02A] = GLFW_KEY_LEFT_SHIFT; + _glfw.win32.publicKeys[0x15B] = GLFW_KEY_LEFT_SUPER; + _glfw.win32.publicKeys[0x137] = GLFW_KEY_PRINT_SCREEN; + _glfw.win32.publicKeys[0x138] = GLFW_KEY_RIGHT_ALT; + _glfw.win32.publicKeys[0x11D] = GLFW_KEY_RIGHT_CONTROL; + _glfw.win32.publicKeys[0x036] = GLFW_KEY_RIGHT_SHIFT; + _glfw.win32.publicKeys[0x15C] = GLFW_KEY_RIGHT_SUPER; + _glfw.win32.publicKeys[0x150] = GLFW_KEY_DOWN; + _glfw.win32.publicKeys[0x14B] = GLFW_KEY_LEFT; + _glfw.win32.publicKeys[0x14D] = GLFW_KEY_RIGHT; + _glfw.win32.publicKeys[0x148] = GLFW_KEY_UP; + + _glfw.win32.publicKeys[0x052] = GLFW_KEY_KP_0; + _glfw.win32.publicKeys[0x04F] = GLFW_KEY_KP_1; + _glfw.win32.publicKeys[0x050] = GLFW_KEY_KP_2; + _glfw.win32.publicKeys[0x051] = GLFW_KEY_KP_3; + _glfw.win32.publicKeys[0x04B] = GLFW_KEY_KP_4; + _glfw.win32.publicKeys[0x04C] = GLFW_KEY_KP_5; + _glfw.win32.publicKeys[0x04D] = GLFW_KEY_KP_6; + _glfw.win32.publicKeys[0x047] = GLFW_KEY_KP_7; + _glfw.win32.publicKeys[0x048] = GLFW_KEY_KP_8; + _glfw.win32.publicKeys[0x049] = GLFW_KEY_KP_9; + _glfw.win32.publicKeys[0x04E] = GLFW_KEY_KP_ADD; + _glfw.win32.publicKeys[0x053] = GLFW_KEY_KP_DECIMAL; + _glfw.win32.publicKeys[0x135] = GLFW_KEY_KP_DIVIDE; + _glfw.win32.publicKeys[0x11C] = GLFW_KEY_KP_ENTER; + _glfw.win32.publicKeys[0x037] = GLFW_KEY_KP_MULTIPLY; + _glfw.win32.publicKeys[0x04A] = GLFW_KEY_KP_SUBTRACT; + + for (scancode = 0; scancode < 512; scancode++) + { + if (_glfw.win32.publicKeys[scancode] > 0) + _glfw.win32.nativeKeys[_glfw.win32.publicKeys[scancode]] = scancode; + } +} + +// Creates a dummy window for behind-the-scenes work +// +static HWND createHelperWindow(void) +{ + HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, + _GLFW_WNDCLASSNAME, + L"GLFW helper window", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + 0, 0, 1, 1, + HWND_MESSAGE, NULL, + GetModuleHandleW(NULL), + NULL); + if (!window) + { + _glfwInputError(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); + } + + return window; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Returns a wide string version of the specified UTF-8 string +// +WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source) +{ + WCHAR* target; + int length; + + length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0); + if (!length) + return NULL; + + target = calloc(length, sizeof(WCHAR)); + + if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length)) + { + 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 length; + + length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); + if (!length) + return NULL; + + target = calloc(length, 1); + + if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL)) + { + free(target); + return NULL; + } + + return target; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + if (!_glfwInitThreadLocalStorageWin32()) + return GLFW_FALSE; + + // 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(); + + if (_glfw_SetProcessDpiAwareness) + _glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); + else if (_glfw_SetProcessDPIAware) + _glfw_SetProcessDPIAware(); + + if (!_glfwRegisterWindowClassWin32()) + return GLFW_FALSE; + + _glfw.win32.helperWindowHandle = createHelperWindow(); + if (!_glfw.win32.helperWindowHandle) + return GLFW_FALSE; + + _glfwPlatformPollEvents(); + + _glfwInitTimerWin32(); + _glfwInitJoysticksWin32(); + + 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); + + _glfwTerminateWGL(); + _glfwTerminateEGL(); + + _glfwTerminateJoysticksWin32(); + _glfwTerminateThreadLocalStorageWin32(); + + 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/extern/glfw-3.2.1/src/win32_joystick.c b/extern/glfw-3.2.1/src/win32_joystick.c new file mode 100644 index 0000000..49f3b87 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_joystick.c @@ -0,0 +1,763 @@ +//======================================================================== +// GLFW 3.1 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 + +#include + +#define _GLFW_PRESENCE_ONLY 1 +#define _GLFW_UPDATE_STATE 2 + +#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 only the necessary GUIDs (it's bad enough that we're exporting these) +// +DEFINE_GUID(IID_IDirectInput8W,0xbf798031,0x483a,0x4da2,0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00); +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_POV,0xa36d02f2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); + +// 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 360 Controller"; + else + return "Xbox 360 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(_GLFWjoystickWin32* js) +{ + if (js->device) + { + IDirectInputDevice8_Unacquire(js->device); + IDirectInputDevice8_Release(js->device); + } + + free(js->name); + free(js->axes); + free(js->buttons); + free(js->objects); + memset(js, 0, sizeof(_GLFWjoystickWin32)); + + _glfwInputJoystickChange((int) (js - _glfw.win32_js), GLFW_DISCONNECTED); +} + +// DirectInput device object enumeration callback +// Insights gleaned from SDL2 +// +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 joy = 0; + DIDEVCAPS dc; + DIPROPDWORD dipd; + IDirectInputDevice8* device; + _GLFWobjenumWin32 data; + _GLFWjoystickWin32* js; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (memcmp(&_glfw.win32_js[joy].guid, &di->guidInstance, sizeof(GUID)) == 0) + return DIENUM_CONTINUE; + } + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.win32_js[joy].present) + break; + } + + if (joy > GLFW_JOYSTICK_LAST) + return DIENUM_STOP; + + if (supportsXInput(&di->guidProduct)) + return DIENUM_CONTINUE; + + if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api, + &di->guidInstance, + &device, + NULL))) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "DI: Failed to create device"); + return DIENUM_CONTINUE; + } + + if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat))) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "DI: 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, + "DI: 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, + "DI: 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, + "DI: Failed to enumerate device objects"); + + IDirectInputDevice8_Release(device); + free(data.objects); + return DIENUM_CONTINUE; + } + + qsort(data.objects, data.objectCount, + sizeof(_GLFWjoyobjectWin32), + compareJoystickObjects); + + js = _glfw.win32_js + joy; + js->device = device; + js->guid = di->guidInstance; + js->axisCount = data.axisCount + data.sliderCount; + js->axes = calloc(js->axisCount, sizeof(float)); + js->buttonCount += data.buttonCount + data.povCount * 4; + js->buttons = calloc(js->buttonCount, 1); + js->objects = data.objects; + js->objectCount = data.objectCount; + js->name = _glfwCreateUTF8FromWideStringWin32(di->tszInstanceName); + js->present = GLFW_TRUE; + + _glfwInputJoystickChange(joy, GLFW_CONNECTED); + return DIENUM_CONTINUE; +} + +// Attempt to open the specified joystick device +// TODO: Pack state arrays for non-gamepad devices +// +static GLFWbool openXinputDevice(DWORD index) +{ + int joy; + XINPUT_CAPABILITIES xic; + _GLFWjoystickWin32* js; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (_glfw.win32_js[joy].present && + _glfw.win32_js[joy].device == NULL && + _glfw.win32_js[joy].index == index) + { + return GLFW_FALSE; + } + } + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (!_glfw.win32_js[joy].present) + break; + } + + if (joy > GLFW_JOYSTICK_LAST) + return GLFW_FALSE; + + if (_glfw_XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS) + return GLFW_FALSE; + + js = _glfw.win32_js + joy; + js->axisCount = 6; + js->axes = calloc(js->axisCount, sizeof(float)); + js->buttonCount = 14; + js->buttons = calloc(js->buttonCount, 1); + js->present = GLFW_TRUE; + js->name = strdup(getDeviceDescription(&xic)); + js->index = index; + + _glfwInputJoystickChange(joy, GLFW_CONNECTED); + + return GLFW_TRUE; +} + +// Polls for and processes events the specified joystick +// +static GLFWbool pollJoystickState(_GLFWjoystickWin32* js, int mode) +{ + if (!js->present) + return GLFW_FALSE; + + if (js->device) + { + int i, j, ai = 0, bi = 0; + HRESULT result; + DIJOYSTATE state; + + IDirectInputDevice8_Poll(js->device); + result = IDirectInputDevice8_GetDeviceState(js->device, + sizeof(state), + &state); + if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST) + { + IDirectInputDevice8_Acquire(js->device); + IDirectInputDevice8_Poll(js->device); + result = IDirectInputDevice8_GetDeviceState(js->device, + sizeof(state), + &state); + } + + if (FAILED(result)) + { + closeJoystick(js); + return GLFW_FALSE; + } + + if (mode == _GLFW_PRESENCE_ONLY) + return GLFW_TRUE; + + for (i = 0; i < js->objectCount; i++) + { + const void* data = (char*) &state + js->objects[i].offset; + + switch (js->objects[i].type) + { + case _GLFW_TYPE_AXIS: + case _GLFW_TYPE_SLIDER: + { + js->axes[ai++] = (*((LONG*) data) + 0.5f) / 32767.5f; + break; + } + + case _GLFW_TYPE_BUTTON: + { + if (*((BYTE*) data) & 0x80) + js->buttons[bi++] = GLFW_PRESS; + else + js->buttons[bi++] = GLFW_RELEASE; + + break; + } + + case _GLFW_TYPE_POV: + { + const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; + // Screams of horror are appropriate at this point + int value = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES); + if (value < 0 || value > 8) + value = 8; + + for (j = 0; j < 4; j++) + { + if (directions[value] & (1 << j)) + js->buttons[bi++] = GLFW_PRESS; + else + js->buttons[bi++] = GLFW_RELEASE; + } + + break; + } + } + } + + return GLFW_TRUE; + } + else + { + int i; + DWORD result; + XINPUT_STATE xis; + const WORD buttons[14] = + { + 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, + XINPUT_GAMEPAD_DPAD_UP, + XINPUT_GAMEPAD_DPAD_RIGHT, + XINPUT_GAMEPAD_DPAD_DOWN, + XINPUT_GAMEPAD_DPAD_LEFT + }; + + result = _glfw_XInputGetState(js->index, &xis); + if (result != ERROR_SUCCESS) + { + if (result == ERROR_DEVICE_NOT_CONNECTED) + closeJoystick(js); + + return GLFW_FALSE; + } + + if (mode == _GLFW_PRESENCE_ONLY) + return GLFW_TRUE; + + if (sqrt((double) (xis.Gamepad.sThumbLX * xis.Gamepad.sThumbLX + + xis.Gamepad.sThumbLY * xis.Gamepad.sThumbLY)) > + (double) XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) + { + js->axes[0] = (xis.Gamepad.sThumbLX + 0.5f) / 32767.f; + js->axes[1] = (xis.Gamepad.sThumbLY + 0.5f) / 32767.f; + } + else + { + js->axes[0] = 0.f; + js->axes[1] = 0.f; + } + + if (sqrt((double) (xis.Gamepad.sThumbRX * xis.Gamepad.sThumbRX + + xis.Gamepad.sThumbRY * xis.Gamepad.sThumbRY)) > + (double) XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) + { + js->axes[2] = (xis.Gamepad.sThumbRX + 0.5f) / 32767.f; + js->axes[3] = (xis.Gamepad.sThumbRY + 0.5f) / 32767.f; + } + else + { + js->axes[2] = 0.f; + js->axes[3] = 0.f; + } + + if (xis.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + js->axes[4] = xis.Gamepad.bLeftTrigger / 127.5f - 1.f; + else + js->axes[4] = -1.f; + + if (xis.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + js->axes[5] = xis.Gamepad.bRightTrigger / 127.5f - 1.f; + else + js->axes[5] = -1.f; + + for (i = 0; i < 14; i++) + js->buttons[i] = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0; + + return GLFW_TRUE; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Initialize joystick interface +// +void _glfwInitJoysticksWin32(void) +{ + if (_glfw.win32.dinput8.instance) + { + if (FAILED(_glfw_DirectInput8Create(GetModuleHandle(NULL), + DIRECTINPUT_VERSION, + &IID_IDirectInput8W, + (void**) &_glfw.win32.dinput8.api, + NULL))) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "DI: Failed to create interface"); + } + } + + _glfwDetectJoystickConnectionWin32(); +} + +// Close all opened joystick handles +// +void _glfwTerminateJoysticksWin32(void) +{ + int joy; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + closeJoystick(_glfw.win32_js + joy); + + 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 i; + + for (i = 0; i < XUSER_MAX_COUNT; i++) + openXinputDevice(i); + } + + 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 joy; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + pollJoystickState(_glfw.win32_js + joy, _GLFW_PRESENCE_ONLY); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformJoystickPresent(int joy) +{ + _GLFWjoystickWin32* js = _glfw.win32_js + joy; + return pollJoystickState(js, _GLFW_PRESENCE_ONLY); +} + +const float* _glfwPlatformGetJoystickAxes(int joy, int* count) +{ + _GLFWjoystickWin32* js = _glfw.win32_js + joy; + if (!pollJoystickState(js, _GLFW_UPDATE_STATE)) + return NULL; + + *count = js->axisCount; + return js->axes; +} + +const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) +{ + _GLFWjoystickWin32* js = _glfw.win32_js + joy; + if (!pollJoystickState(js, _GLFW_UPDATE_STATE)) + return NULL; + + *count = js->buttonCount; + return js->buttons; +} + +const char* _glfwPlatformGetJoystickName(int joy) +{ + _GLFWjoystickWin32* js = _glfw.win32_js + joy; + if (!pollJoystickState(js, _GLFW_PRESENCE_ONLY)) + return NULL; + + return js->name; +} + diff --git a/extern/glfw-3.2.1/src/win32_joystick.h b/extern/glfw-3.2.1/src/win32_joystick.h new file mode 100644 index 0000000..6a75b41 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_joystick.h @@ -0,0 +1,64 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_win32_joystick_h_ +#define _glfw3_win32_joystick_h_ + +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ + _GLFWjoystickWin32 win32_js[GLFW_JOYSTICK_LAST + 1] + +// Joystick element (axis, button or slider) +// +typedef struct _GLFWjoyobjectWin32 +{ + int offset; + int type; +} _GLFWjoyobjectWin32; + +// Win32-specific per-joystick data +// +typedef struct _GLFWjoystickWin32 +{ + GLFWbool present; + float* axes; + int axisCount; + unsigned char* buttons; + int buttonCount; + _GLFWjoyobjectWin32* objects; + int objectCount; + char* name; + IDirectInputDevice8W* device; + DWORD index; + GUID guid; +} _GLFWjoystickWin32; + + +void _glfwInitJoysticksWin32(void); +void _glfwTerminateJoysticksWin32(void); +void _glfwDetectJoystickConnectionWin32(void); +void _glfwDetectJoystickDisconnectionWin32(void); + +#endif // _glfw3_win32_joystick_h_ diff --git a/extern/glfw-3.2.1/src/win32_monitor.c b/extern/glfw-3.2.1/src/win32_monitor.c new file mode 100644 index 0000000..e55c9a7 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_monitor.c @@ -0,0 +1,401 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include +#include + + +// Create monitor from an adapter and (optionally) a display +// +static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter, + DISPLAY_DEVICEW* display) +{ + _GLFWmonitor* monitor; + char* name; + HDC dc; + + if (display) + name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString); + else + name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString); + if (!name) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert string to UTF-8"); + return NULL; + } + + dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL); + + monitor = _glfwAllocMonitor(name, + GetDeviceCaps(dc, HORZSIZE), + GetDeviceCaps(dc, VERTSIZE)); + + DeleteDC(dc); + 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); + } + + return monitor; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +// Change the current video mode +// +GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired) +{ + GLFWvidmode current; + const GLFWvidmode* best; + DEVMODEW dm; + + best = _glfwChooseVideoMode(monitor, desired); + _glfwPlatformGetVideoMode(monitor, ¤t); + if (_glfwCompareVideoModes(¤t, best) == 0) + return GLFW_TRUE; + + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(DEVMODEW); + 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; + + if (ChangeDisplaySettingsExW(monitor->win32.adapterName, + &dm, + NULL, + CDS_FULLSCREEN, + NULL) != DISP_CHANGE_SUCCESSFUL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode"); + 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; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int found = 0; + DWORD adapterIndex, displayIndex, primaryIndex = 0; + DISPLAY_DEVICEW adapter, display; + GLFWbool hasDisplays = GLFW_FALSE; + _GLFWmonitor** monitors = NULL; + + *count = 0; + + // HACK: Check if any active adapters have connected displays + // If not, this is a headless system or a VMware guest + + for (adapterIndex = 0; ; adapterIndex++) + { + ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW)); + adapter.cb = sizeof(DISPLAY_DEVICEW); + + if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0)) + break; + + if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) + continue; + + ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); + display.cb = sizeof(DISPLAY_DEVICEW); + + if (EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0)) + { + hasDisplays = GLFW_TRUE; + break; + } + } + + for (adapterIndex = 0; ; adapterIndex++) + { + ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW)); + adapter.cb = sizeof(DISPLAY_DEVICEW); + + if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0)) + break; + + if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) + continue; + + if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) + primaryIndex = found; + + if (hasDisplays) + { + for (displayIndex = 0; ; displayIndex++) + { + ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); + display.cb = sizeof(DISPLAY_DEVICEW); + + if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0)) + break; + + found++; + monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found); + monitors[found - 1] = createMonitor(&adapter, &display); + } + } + else + { + found++; + monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found); + monitors[found - 1] = createMonitor(&adapter, NULL); + } + } + + _GLFW_SWAP_POINTERS(monitors[0], monitors[primaryIndex]); + + *count = found; + return monitors; +} + +GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + if (wcslen(first->win32.displayName)) + return wcscmp(first->win32.displayName, second->win32.displayName) == 0; + else + return wcscmp(first->win32.adapterName, second->win32.adapterName) == 0; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + DEVMODEW settings; + ZeroMemory(&settings, sizeof(DEVMODEW)); + settings.dmSize = sizeof(DEVMODEW); + + EnumDisplaySettingsExW(monitor->win32.adapterName, + ENUM_CURRENT_SETTINGS, + &settings, + EDS_ROTATEDMODE); + + if (xpos) + *xpos = settings.dmPosition.x; + if (ypos) + *ypos = settings.dmPosition.y; +} + +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(DEVMODEW)); + dm.dmSize = sizeof(DEVMODEW); + + 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(DEVMODEW)); + dm.dmSize = sizeof(DEVMODEW); + + 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/extern/glfw-3.2.1/src/win32_platform.h b/extern/glfw-3.2.1/src/win32_platform.h new file mode 100644 index 0000000..c0dcff1 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_platform.h @@ -0,0 +1,350 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_win32_platform_h_ +#define _glfw3_win32_platform_h_ + +// 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 +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) + #include + #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 + +#if WINVER < 0x0601 +typedef struct tagCHANGEFILTERSTRUCT +{ + DWORD cbSize; + DWORD ExtStatus; + +} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT; +#ifndef MSGFLT_ALLOW + #define MSGFLT_ALLOW 1 +#endif +#endif /*Windows 7*/ + +#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; +#endif /*DPI_ENUMS_DECLARED*/ + +// 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 * TIMEGETTIME_T)(void); +#define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime + +// xinput.dll function pointer typedefs +typedef DWORD (WINAPI * XINPUTGETCAPABILITIES_T)(DWORD,DWORD,XINPUT_CAPABILITIES*); +typedef DWORD (WINAPI * XINPUTGETSTATE_T)(DWORD,XINPUT_STATE*); +#define _glfw_XInputGetCapabilities _glfw.win32.xinput.XInputGetCapabilities +#define _glfw_XInputGetState _glfw.win32.xinput.XInputGetState + +// dinput8.dll function pointer typedefs +typedef HRESULT (WINAPI * DIRECTINPUT8CREATE_T)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN); +#define _glfw_DirectInput8Create _glfw.win32.dinput8.DirectInput8Create + +// user32.dll function pointer typedefs +typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); +typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); +#define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware +#define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx + +// dwmapi.dll function pointer typedefs +typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); +typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID); +#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled +#define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush + +// shcore.dll function pointer typedefs +typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); +#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness + +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" + +#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_TIME_STATE _GLFWtimeWin32 win32_time +#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32 +#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32 + + +// Win32-specific per-window data +// +typedef struct _GLFWwindowWin32 +{ + HWND handle; + HICON bigIcon; + HICON smallIcon; + + GLFWbool cursorTracked; + GLFWbool iconified; + + // The last received cursor position, regardless of source + int lastCursorPosX, lastCursorPosY; + +} _GLFWwindowWin32; + +// Win32-specific global data +// +typedef struct _GLFWlibraryWin32 +{ + HWND helperWindowHandle; + DWORD foregroundLockTimeout; + char* clipboardString; + char keyName[64]; + short int publicKeys[512]; + short int nativeKeys[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; + + struct { + HINSTANCE instance; + TIMEGETTIME_T timeGetTime; + } winmm; + + struct { + HINSTANCE instance; + DIRECTINPUT8CREATE_T DirectInput8Create; + IDirectInput8W* api; + } dinput8; + + struct { + HINSTANCE instance; + XINPUTGETCAPABILITIES_T XInputGetCapabilities; + XINPUTGETSTATE_T XInputGetState; + } xinput; + + struct { + HINSTANCE instance; + SETPROCESSDPIAWARE_T SetProcessDPIAware; + CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx; + } user32; + + struct { + HINSTANCE instance; + DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled; + DWMFLUSH_T DwmFlush; + } dwmapi; + + struct { + HINSTANCE instance; + SETPROCESSDPIAWARENESS_T SetProcessDpiAwareness; + } shcore; + +} _GLFWlibraryWin32; + +// Win32-specific per-monitor data +// +typedef struct _GLFWmonitorWin32 +{ + // 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 _GLFWtimeWin32 +{ + GLFWbool hasPC; + uint64_t frequency; + +} _GLFWtimeWin32; + +// Win32-specific global TLS data +// +typedef struct _GLFWtlsWin32 +{ + GLFWbool allocated; + DWORD context; + +} _GLFWtlsWin32; + + +GLFWbool _glfwRegisterWindowClassWin32(void); +void _glfwUnregisterWindowClassWin32(void); + +GLFWbool _glfwInitThreadLocalStorageWin32(void); +void _glfwTerminateThreadLocalStorageWin32(void); + +WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source); +char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source); + +void _glfwInitTimerWin32(void); + +GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired); +void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor); + +#endif // _glfw3_win32_platform_h_ diff --git a/extern/glfw-3.2.1/src/win32_time.c b/extern/glfw-3.2.1/src/win32_time.c new file mode 100644 index 0000000..d972f56 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_time.c @@ -0,0 +1,74 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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.win32_time.hasPC = GLFW_TRUE; + _glfw.win32_time.frequency = frequency; + } + else + { + _glfw.win32_time.hasPC = GLFW_FALSE; + _glfw.win32_time.frequency = 1000; + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +uint64_t _glfwPlatformGetTimerValue(void) +{ + if (_glfw.win32_time.hasPC) + { + uint64_t value; + QueryPerformanceCounter((LARGE_INTEGER*) &value); + return value; + } + else + return (uint64_t) _glfw_timeGetTime(); +} + +uint64_t _glfwPlatformGetTimerFrequency(void) +{ + return _glfw.win32_time.frequency; +} + diff --git a/extern/glfw-3.2.1/src/win32_tls.c b/extern/glfw-3.2.1/src/win32_tls.c new file mode 100644 index 0000000..ab79fcc --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_tls.c @@ -0,0 +1,69 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 ////// +////////////////////////////////////////////////////////////////////////// + +GLFWbool _glfwInitThreadLocalStorageWin32(void) +{ + _glfw.win32_tls.context = TlsAlloc(); + if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to allocate TLS index"); + return GLFW_FALSE; + } + + _glfw.win32_tls.allocated = GLFW_TRUE; + return GLFW_TRUE; +} + +void _glfwTerminateThreadLocalStorageWin32(void) +{ + if (_glfw.win32_tls.allocated) + TlsFree(_glfw.win32_tls.context); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformSetCurrentContext(_GLFWwindow* context) +{ + TlsSetValue(_glfw.win32_tls.context, context); +} + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return TlsGetValue(_glfw.win32_tls.context); +} + diff --git a/extern/glfw-3.2.1/src/win32_window.c b/extern/glfw-3.2.1/src/win32_window.c new file mode 100644 index 0000000..8e30eb6 --- /dev/null +++ b/extern/glfw-3.2.1/src/win32_window.c @@ -0,0 +1,1724 @@ +//======================================================================== +// GLFW 3.2 Win32 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include +#include +#include +#include + +#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 + { + if (window->decorated) + { + style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + 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(BITMAPV5HEADER); + 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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to create RGBA bitmap"); + return NULL; + } + + mask = CreateBitmap(image->width, image->height, 1, 1, NULL); + if (!mask) + { + _glfwInputError(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) + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create icon"); + else + _glfwInputError(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); +} + +// 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) +{ + if (wParam == VK_CONTROL) + { + // The CTRL keys require special handling + + MSG next; + DWORD time; + + // Is this an extended key (i.e. right key)? + if (lParam & 0x01000000) + return GLFW_KEY_RIGHT_CONTROL; + + // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only + // want the RALT message, so we try to see if the next message + // is a RALT message. In that case, this is a false LCTRL! + 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 a RALT down message, which + // means that this is not a proper LCTRL message + 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.publicKeys[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; + + 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); + + _glfwInputMonitorWindowChange(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; + + _glfwInputMonitorWindowChange(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_DEVICECHANGE: + { + if (wParam == DBT_DEVNODES_CHANGED) + { + _glfwInputMonitorChange(); + return TRUE; + } + else if (wParam == DBT_DEVICEARRIVAL) + { + DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam; + if (dbh) + { + if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) + _glfwDetectJoystickConnectionWin32(); + } + } + else if (wParam == DBT_DEVICEREMOVECOMPLETE) + { + DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam; + if (dbh) + { + if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) + _glfwDetectJoystickDisconnectionWin32(); + } + } + + break; + } + } + + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } + + switch (uMsg) + { + case WM_SETFOCUS: + { + _glfwInputWindowFocus(window, GLFW_TRUE); + + 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_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) + { + // Release both Shift keys on Shift up event, as only one event + // is sent even if both keys are released + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods); + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods); + } + else if (wParam == VK_SNAPSHOT) + { + // 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 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; + SetCapture(hWnd); + } + else + { + action = GLFW_RELEASE; + ReleaseCapture(); + } + + _glfwInputMouseClick(window, button, action, getKeyMods()); + + 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); + + if (window->cursorMode == GLFW_CURSOR_DISABLED) + { + const int dx = x - window->win32.lastCursorPosX; + const int dy = y - window->win32.lastCursorPosY; + + if (_glfw.win32.disabledCursorWindow != window) + break; + + _glfwInputCursorPos(window, + window->virtualCursorPosX + dx, + window->virtualCursorPosY + dy); + } + else + _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_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 OS X and X11. + _glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0); + return 0; + } + + case WM_ENTERSIZEMOVE: + case WM_ENTERMENULOOP: + { + if (window->cursorMode == GLFW_CURSOR_DISABLED) + _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); + + break; + } + + case WM_EXITSIZEMOVE: + case WM_EXITMENULOOP: + { + if (window->cursorMode == GLFW_CURSOR_DISABLED) + _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); + + break; + } + + case WM_SIZE: + { + const GLFWbool iconified = + !window->win32.iconified && wParam == SIZE_MINIMIZED; + const GLFWbool restored = + window->win32.iconified && + (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED); + + if (_glfw.win32.disabledCursorWindow == window) + updateClipRect(window); + + if (iconified) + _glfwInputWindowIconify(window, GLFW_TRUE); + else if (restored) + _glfwInputWindowIconify(window, GLFW_FALSE); + + _glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam)); + _glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam)); + + if (iconified) + { + window->win32.iconified = GLFW_TRUE; + if (window->monitor) + releaseMonitor(window); + } + else if (restored) + { + window->win32.iconified = GLFW_FALSE; + if (window->monitor) + acquireMonitor(window); + } + + 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; + } + + return 0; + } + + case WM_PAINT: + { + _glfwInputWindowDamage(window); + break; + } + + case WM_ERASEBKGND: + { + return TRUE; + } + + case WM_SETCURSOR: + { + if (LOWORD(lParam) == HTCLIENT) + { + updateCursorImage(window); + return TRUE; + } + + break; + } + + case WM_DPICHANGED: + { + RECT* rect = (RECT*) lParam; + SetWindowPos(window->win32.handle, + HWND_TOP, + rect->left, + rect->top, + rect->right - rect->left, + rect->bottom - rect->top, + SWP_NOACTIVATE | SWP_NOZORDER); + 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) +{ + 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 set + _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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert window title to UTF-16"); + 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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window"); + return GLFW_FALSE; + } + + SetPropW(window->win32.handle, L"GLFW", window); + + if (_glfw_ChangeWindowMessageFilterEx) + { + _glfw_ChangeWindowMessageFilterEx(window->win32.handle, + WM_DROPFILES, MSGFLT_ALLOW, NULL); + _glfw_ChangeWindowMessageFilterEx(window->win32.handle, + WM_COPYDATA, MSGFLT_ALLOW, NULL); + _glfw_ChangeWindowMessageFilterEx(window->win32.handle, + WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); + } + + DragAcceptFiles(window->win32.handle, 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)) + { + _glfwInputError(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)); +} + + +////////////////////////////////////////////////////////////////////////// +////// 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) + { + if (!_glfwInitWGL()) + return GLFW_FALSE; + if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + else + { + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + } + + if (window->monitor) + { + _glfwPlatformShowWindow(window); + _glfwPlatformFocusWindow(window); + if (!acquireMonitor(window)) + return GLFW_FALSE; + + 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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert window title to UTF-16"); + 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 _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 _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); + + _glfwInputWindowMonitorChange(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); +} + +void _glfwPlatformPollEvents(void) +{ + MSG msg; + HWND handle; + _GLFWwindow* window; + + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + // Treat WM_QUIT as a close on all windows + // While GLFW does not itself post WM_QUIT, other processes may post + // it to this one, for example Task Manager + + window = _glfw.windowListHead; + while (window) + { + _glfwInputWindowCloseRequest(window); + window = window->next; + } + } + else + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + handle = GetActiveWindow(); + if (handle) + { + // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix) + // This is the only async event handling in GLFW, but it solves some + // nasty problems + window = GetPropW(handle, L"GLFW"); + if (window) + { + const int mods = getAsyncKeyMods(); + + // Get current state of left and right shift keys + const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1; + const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1; + + // See if this differs from our belief of what has happened + // (we only have to check for lost key up events) + if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1) + _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods); + + if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1) + _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, 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) +{ + _GLFWwindow* window = _glfw.windowListHead; + PostMessage(window->win32.handle, 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) + { + _glfw.win32.disabledCursorWindow = window; + _glfwPlatformGetCursorPos(window, + &_glfw.win32.restoreCursorPosX, + &_glfw.win32.restoreCursorPosY); + centerCursor(window); + updateClipRect(window); + } + else if (_glfw.win32.disabledCursorWindow == window) + { + _glfw.win32.disabledCursorWindow = NULL; + updateClipRect(NULL); + _glfwPlatformSetCursorPos(window, + _glfw.win32.restoreCursorPosX, + _glfw.win32.restoreCursorPosY); + } + + if (cursorInClientArea(window)) + updateCursorImage(window); +} + +const char* _glfwPlatformGetKeyName(int key, int scancode) +{ + WCHAR name[16]; + + if (key != GLFW_KEY_UNKNOWN) + scancode = _glfw.win32.nativeKeys[key]; + + if (!_glfwIsPrintable(_glfw.win32.publicKeys[scancode])) + return NULL; + + if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR))) + return NULL; + + if (!WideCharToMultiByte(CP_UTF8, 0, name, -1, + _glfw.win32.keyName, + sizeof(_glfw.win32.keyName), + NULL, NULL)) + { + return NULL; + } + + return _glfw.win32.keyName; +} + +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) + { + _glfwInputError(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) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert clipboard string to UTF-16"); + return; + } + + object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR)); + if (!object) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to allocate global handle for clipboard"); + return; + } + + buffer = GlobalLock(object); + if (!buffer) + { + GlobalFree(object); + + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle"); + return; + } + + MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount); + GlobalUnlock(object); + + if (!OpenClipboard(_glfw.win32.helperWindowHandle)) + { + GlobalFree(object); + + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); + return; + } + + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, object); + CloseClipboard(); +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + HANDLE object; + WCHAR* buffer; + + if (!OpenClipboard(_glfw.win32.helperWindowHandle)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); + return NULL; + } + + object = GetClipboardData(CF_UNICODETEXT); + if (!object) + { + CloseClipboard(); + + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "Win32: Failed to convert clipboard to string"); + return NULL; + } + + buffer = GlobalLock(object); + if (!buffer) + { + CloseClipboard(); + + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle"); + return NULL; + } + + free(_glfw.win32.clipboardString); + _glfw.win32.clipboardString = + _glfwCreateUTF8FromWideStringWin32(buffer); + + GlobalUnlock(object); + CloseClipboard(); + + if (!_glfw.win32.clipboardString) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to convert wide string to UTF-8"); + return NULL; + } + + return _glfw.win32.clipboardString; +} + +char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_win32_surface) + return NULL; + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + extensions[1] = strdup("VK_KHR_win32_surface"); + + *count = 2; + return extensions; +} + +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/extern/glfw-3.2.1/src/window.c b/extern/glfw-3.2.1/src/window.c new file mode 100644 index 0000000..5e74e6e --- /dev/null +++ b/extern/glfw-3.2.1/src/window.c @@ -0,0 +1,904 @@ +//======================================================================== +// GLFW 3.2 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// Copyright (c) 2012 Torsten Walluhn +// +// 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 +#include +#include +#include + + +////////////////////////////////////////////////////////////////////////// +////// GLFW event API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) +{ + if (focused) + { + if (window->callbacks.focus) + window->callbacks.focus((GLFWwindow*) window, focused); + } + else + { + int i; + + if (window->callbacks.focus) + window->callbacks.focus((GLFWwindow*) window, focused); + + // Release all pressed keyboard keys + for (i = 0; i <= GLFW_KEY_LAST; i++) + { + if (window->keys[i] == GLFW_PRESS) + _glfwInputKey(window, i, 0, GLFW_RELEASE, 0); + } + + // Release all pressed mouse buttons + for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + { + if (window->mouseButtons[i] == GLFW_PRESS) + _glfwInputMouseClick(window, i, 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 _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->closed = GLFW_TRUE; + + if (window->callbacks.close) + window->callbacks.close((GLFWwindow*) window); +} + +void _glfwInputWindowMonitorChange(_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); + + _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 = _glfwPlatformGetCurrentContext(); + 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(); + + memset(&_glfw.hints, 0, sizeof(_glfw.hints)); + + // The default is OpenGL with minimum version 1.0 + _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 + _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; + + // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, + // double buffered + _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; +} + +GLFWAPI void glfwWindowHint(int hint, int value) +{ + _GLFW_REQUIRE_INIT(); + + switch (hint) + { + case GLFW_RED_BITS: + _glfw.hints.framebuffer.redBits = value; + break; + case GLFW_GREEN_BITS: + _glfw.hints.framebuffer.greenBits = value; + break; + case GLFW_BLUE_BITS: + _glfw.hints.framebuffer.blueBits = value; + break; + case GLFW_ALPHA_BITS: + _glfw.hints.framebuffer.alphaBits = value; + break; + case GLFW_DEPTH_BITS: + _glfw.hints.framebuffer.depthBits = value; + break; + case GLFW_STENCIL_BITS: + _glfw.hints.framebuffer.stencilBits = value; + break; + case GLFW_ACCUM_RED_BITS: + _glfw.hints.framebuffer.accumRedBits = value; + break; + case GLFW_ACCUM_GREEN_BITS: + _glfw.hints.framebuffer.accumGreenBits = value; + break; + case GLFW_ACCUM_BLUE_BITS: + _glfw.hints.framebuffer.accumBlueBits = value; + break; + case GLFW_ACCUM_ALPHA_BITS: + _glfw.hints.framebuffer.accumAlphaBits = value; + break; + case GLFW_AUX_BUFFERS: + _glfw.hints.framebuffer.auxBuffers = value; + break; + case GLFW_STEREO: + _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_DOUBLEBUFFER: + _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_SAMPLES: + _glfw.hints.framebuffer.samples = value; + break; + case GLFW_SRGB_CAPABLE: + _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_RESIZABLE: + _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_DECORATED: + _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_FOCUSED: + _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_AUTO_ICONIFY: + _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_FLOATING: + _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_MAXIMIZED: + _glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_VISIBLE: + _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_CLIENT_API: + _glfw.hints.context.client = value; + break; + case GLFW_CONTEXT_CREATION_API: + _glfw.hints.context.source = value; + break; + case GLFW_CONTEXT_VERSION_MAJOR: + _glfw.hints.context.major = value; + break; + case GLFW_CONTEXT_VERSION_MINOR: + _glfw.hints.context.minor = value; + break; + case GLFW_CONTEXT_ROBUSTNESS: + _glfw.hints.context.robustness = value; + break; + case GLFW_OPENGL_FORWARD_COMPAT: + _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_OPENGL_DEBUG_CONTEXT: + _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_CONTEXT_NO_ERROR: + _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE; + break; + case GLFW_OPENGL_PROFILE: + _glfw.hints.context.profile = value; + break; + case GLFW_CONTEXT_RELEASE_BEHAVIOR: + _glfw.hints.context.release = value; + break; + case GLFW_REFRESH_RATE: + _glfw.hints.refreshRate = value; + break; + default: + _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint %i", hint); + break; + } +} + +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 == _glfwPlatformGetCurrentContext()) + 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->closed; +} + +GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT(); + window->closed = 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); + + _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); + + _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 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(); + _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 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_RESIZABLE: + return window->resizable; + case GLFW_DECORATED: + return window->decorated; + case GLFW_FLOATING: + return window->floating; + 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 %i", attrib); + return 0; +} + +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); + + _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 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(); + + 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/extern/glfw-3.2.1/src/wl_init.c b/extern/glfw-3.2.1/src/wl_init.c new file mode 100644 index 0000000..44f7d0c --- /dev/null +++ b/extern/glfw-3.2.1/src/wl_init.c @@ -0,0 +1,658 @@ +//======================================================================== +// GLFW 3.2 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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 +#include +#include +#include +#include +#include +#include +#include + + +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; + + /* 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 scroll_factor; + 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. */ + scroll_factor = 1.0/10.0; + + switch (axis) + { + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + x = wl_fixed_to_double(value) * scroll_factor; + y = 0.0; + break; + case WL_POINTER_AXIS_VERTICAL_SCROLL: + x = 0.0; + y = wl_fixed_to_double(value) * scroll_factor; + 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; + char* mapStr; + + 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_map_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_map_unref(keymap); + return; + } + + 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.control_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Control"); + _glfw.wl.xkb.alt_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod1"); + _glfw.wl.xkb.shift_mask = + 1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Shift"); + _glfw.wl.xkb.super_mask = + 1 << xkb_map_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.publicKeys) / sizeof(_glfw.wl.publicKeys[0])) + return _glfw.wl.publicKeys[key]; + + return GLFW_KEY_UNKNOWN; +} + +static void keyboardHandleKey(void* data, + struct wl_keyboard* keyboard, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state) +{ + uint32_t code, num_syms; + long cp; + int keyCode; + int action; + const xkb_keysym_t *syms; + _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); + + code = key + 8; + num_syms = xkb_key_get_syms(_glfw.wl.xkb.state, code, &syms); + + if (num_syms == 1) + { + cp = _glfwKeySym2Unicode(syms[0]); + 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 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_DEPRESSED | + XKB_STATE_LATCHED); + if (mask & _glfw.wl.xkb.control_mask) + modifiers |= GLFW_MOD_CONTROL; + if (mask & _glfw.wl.xkb.alt_mask) + modifiers |= GLFW_MOD_ALT; + if (mask & _glfw.wl.xkb.shift_mask) + modifiers |= GLFW_MOD_SHIFT; + if (mask & _glfw.wl.xkb.super_mask) + 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.wl_compositor_version = min(3, version); + _glfw.wl.compositor = + wl_registry_bind(registry, name, &wl_compositor_interface, + _glfw.wl.wl_compositor_version); + } + 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) +{ + memset(_glfw.wl.publicKeys, -1, sizeof(_glfw.wl.publicKeys)); + + _glfw.wl.publicKeys[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT; + _glfw.wl.publicKeys[KEY_1] = GLFW_KEY_1; + _glfw.wl.publicKeys[KEY_2] = GLFW_KEY_2; + _glfw.wl.publicKeys[KEY_3] = GLFW_KEY_3; + _glfw.wl.publicKeys[KEY_4] = GLFW_KEY_4; + _glfw.wl.publicKeys[KEY_5] = GLFW_KEY_5; + _glfw.wl.publicKeys[KEY_6] = GLFW_KEY_6; + _glfw.wl.publicKeys[KEY_7] = GLFW_KEY_7; + _glfw.wl.publicKeys[KEY_8] = GLFW_KEY_8; + _glfw.wl.publicKeys[KEY_9] = GLFW_KEY_9; + _glfw.wl.publicKeys[KEY_0] = GLFW_KEY_0; + _glfw.wl.publicKeys[KEY_MINUS] = GLFW_KEY_MINUS; + _glfw.wl.publicKeys[KEY_EQUAL] = GLFW_KEY_EQUAL; + _glfw.wl.publicKeys[KEY_Q] = GLFW_KEY_Q; + _glfw.wl.publicKeys[KEY_W] = GLFW_KEY_W; + _glfw.wl.publicKeys[KEY_E] = GLFW_KEY_E; + _glfw.wl.publicKeys[KEY_R] = GLFW_KEY_R; + _glfw.wl.publicKeys[KEY_T] = GLFW_KEY_T; + _glfw.wl.publicKeys[KEY_Y] = GLFW_KEY_Y; + _glfw.wl.publicKeys[KEY_U] = GLFW_KEY_U; + _glfw.wl.publicKeys[KEY_I] = GLFW_KEY_I; + _glfw.wl.publicKeys[KEY_O] = GLFW_KEY_O; + _glfw.wl.publicKeys[KEY_P] = GLFW_KEY_P; + _glfw.wl.publicKeys[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET; + _glfw.wl.publicKeys[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET; + _glfw.wl.publicKeys[KEY_A] = GLFW_KEY_A; + _glfw.wl.publicKeys[KEY_S] = GLFW_KEY_S; + _glfw.wl.publicKeys[KEY_D] = GLFW_KEY_D; + _glfw.wl.publicKeys[KEY_F] = GLFW_KEY_F; + _glfw.wl.publicKeys[KEY_G] = GLFW_KEY_G; + _glfw.wl.publicKeys[KEY_H] = GLFW_KEY_H; + _glfw.wl.publicKeys[KEY_J] = GLFW_KEY_J; + _glfw.wl.publicKeys[KEY_K] = GLFW_KEY_K; + _glfw.wl.publicKeys[KEY_L] = GLFW_KEY_L; + _glfw.wl.publicKeys[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON; + _glfw.wl.publicKeys[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE; + _glfw.wl.publicKeys[KEY_Z] = GLFW_KEY_Z; + _glfw.wl.publicKeys[KEY_X] = GLFW_KEY_X; + _glfw.wl.publicKeys[KEY_C] = GLFW_KEY_C; + _glfw.wl.publicKeys[KEY_V] = GLFW_KEY_V; + _glfw.wl.publicKeys[KEY_B] = GLFW_KEY_B; + _glfw.wl.publicKeys[KEY_N] = GLFW_KEY_N; + _glfw.wl.publicKeys[KEY_M] = GLFW_KEY_M; + _glfw.wl.publicKeys[KEY_COMMA] = GLFW_KEY_COMMA; + _glfw.wl.publicKeys[KEY_DOT] = GLFW_KEY_PERIOD; + _glfw.wl.publicKeys[KEY_SLASH] = GLFW_KEY_SLASH; + _glfw.wl.publicKeys[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH; + _glfw.wl.publicKeys[KEY_ESC] = GLFW_KEY_ESCAPE; + _glfw.wl.publicKeys[KEY_TAB] = GLFW_KEY_TAB; + _glfw.wl.publicKeys[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT; + _glfw.wl.publicKeys[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT; + _glfw.wl.publicKeys[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL; + _glfw.wl.publicKeys[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL; + _glfw.wl.publicKeys[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT; + _glfw.wl.publicKeys[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT; + _glfw.wl.publicKeys[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER; + _glfw.wl.publicKeys[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER; + _glfw.wl.publicKeys[KEY_MENU] = GLFW_KEY_MENU; + _glfw.wl.publicKeys[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK; + _glfw.wl.publicKeys[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK; + _glfw.wl.publicKeys[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN; + _glfw.wl.publicKeys[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK; + _glfw.wl.publicKeys[KEY_PAUSE] = GLFW_KEY_PAUSE; + _glfw.wl.publicKeys[KEY_DELETE] = GLFW_KEY_DELETE; + _glfw.wl.publicKeys[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE; + _glfw.wl.publicKeys[KEY_ENTER] = GLFW_KEY_ENTER; + _glfw.wl.publicKeys[KEY_HOME] = GLFW_KEY_HOME; + _glfw.wl.publicKeys[KEY_END] = GLFW_KEY_END; + _glfw.wl.publicKeys[KEY_PAGEUP] = GLFW_KEY_PAGE_UP; + _glfw.wl.publicKeys[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN; + _glfw.wl.publicKeys[KEY_INSERT] = GLFW_KEY_INSERT; + _glfw.wl.publicKeys[KEY_LEFT] = GLFW_KEY_LEFT; + _glfw.wl.publicKeys[KEY_RIGHT] = GLFW_KEY_RIGHT; + _glfw.wl.publicKeys[KEY_DOWN] = GLFW_KEY_DOWN; + _glfw.wl.publicKeys[KEY_UP] = GLFW_KEY_UP; + _glfw.wl.publicKeys[KEY_F1] = GLFW_KEY_F1; + _glfw.wl.publicKeys[KEY_F2] = GLFW_KEY_F2; + _glfw.wl.publicKeys[KEY_F3] = GLFW_KEY_F3; + _glfw.wl.publicKeys[KEY_F4] = GLFW_KEY_F4; + _glfw.wl.publicKeys[KEY_F5] = GLFW_KEY_F5; + _glfw.wl.publicKeys[KEY_F6] = GLFW_KEY_F6; + _glfw.wl.publicKeys[KEY_F7] = GLFW_KEY_F7; + _glfw.wl.publicKeys[KEY_F8] = GLFW_KEY_F8; + _glfw.wl.publicKeys[KEY_F9] = GLFW_KEY_F9; + _glfw.wl.publicKeys[KEY_F10] = GLFW_KEY_F10; + _glfw.wl.publicKeys[KEY_F11] = GLFW_KEY_F11; + _glfw.wl.publicKeys[KEY_F12] = GLFW_KEY_F12; + _glfw.wl.publicKeys[KEY_F13] = GLFW_KEY_F13; + _glfw.wl.publicKeys[KEY_F14] = GLFW_KEY_F14; + _glfw.wl.publicKeys[KEY_F15] = GLFW_KEY_F15; + _glfw.wl.publicKeys[KEY_F16] = GLFW_KEY_F16; + _glfw.wl.publicKeys[KEY_F17] = GLFW_KEY_F17; + _glfw.wl.publicKeys[KEY_F18] = GLFW_KEY_F18; + _glfw.wl.publicKeys[KEY_F19] = GLFW_KEY_F19; + _glfw.wl.publicKeys[KEY_F20] = GLFW_KEY_F20; + _glfw.wl.publicKeys[KEY_F21] = GLFW_KEY_F21; + _glfw.wl.publicKeys[KEY_F22] = GLFW_KEY_F22; + _glfw.wl.publicKeys[KEY_F23] = GLFW_KEY_F23; + _glfw.wl.publicKeys[KEY_F24] = GLFW_KEY_F24; + _glfw.wl.publicKeys[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE; + _glfw.wl.publicKeys[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY; + _glfw.wl.publicKeys[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT; + _glfw.wl.publicKeys[KEY_KPPLUS] = GLFW_KEY_KP_ADD; + _glfw.wl.publicKeys[KEY_KP0] = GLFW_KEY_KP_0; + _glfw.wl.publicKeys[KEY_KP1] = GLFW_KEY_KP_1; + _glfw.wl.publicKeys[KEY_KP2] = GLFW_KEY_KP_2; + _glfw.wl.publicKeys[KEY_KP3] = GLFW_KEY_KP_3; + _glfw.wl.publicKeys[KEY_KP4] = GLFW_KEY_KP_4; + _glfw.wl.publicKeys[KEY_KP5] = GLFW_KEY_KP_5; + _glfw.wl.publicKeys[KEY_KP6] = GLFW_KEY_KP_6; + _glfw.wl.publicKeys[KEY_KP7] = GLFW_KEY_KP_7; + _glfw.wl.publicKeys[KEY_KP8] = GLFW_KEY_KP_8; + _glfw.wl.publicKeys[KEY_KP9] = GLFW_KEY_KP_9; + _glfw.wl.publicKeys[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL; + _glfw.wl.publicKeys[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL; + _glfw.wl.publicKeys[KEY_KPENTER] = GLFW_KEY_KP_ENTER; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + _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, ®istryListener, NULL); + + _glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*)); + _glfw.wl.monitorsSize = 4; + + 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 (!_glfwInitThreadLocalStoragePOSIX()) + return GLFW_FALSE; + + 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(); + _glfwTerminateThreadLocalStoragePOSIX(); + + if (_glfw.wl.cursorTheme) + wl_cursor_theme_destroy(_glfw.wl.cursorTheme); + if (_glfw.wl.cursorSurface) + wl_surface_destroy(_glfw.wl.cursorSurface); + if (_glfw.wl.registry) + wl_registry_destroy(_glfw.wl.registry); + if (_glfw.wl.display) + wl_display_flush(_glfw.wl.display); + if (_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 +#if defined(__linux__) + " /dev/js" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; +} + diff --git a/extern/glfw-3.2.1/src/wl_monitor.c b/extern/glfw-3.2.1/src/wl_monitor.c new file mode 100644 index 0000000..27731c2 --- /dev/null +++ b/extern/glfw-3.2.1/src/wl_monitor.c @@ -0,0 +1,269 @@ +//======================================================================== +// GLFW 3.2 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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 +#include +#include +#include + + +struct _GLFWvidmodeWayland +{ + GLFWvidmode base; + uint32_t flags; +}; + +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; + + monitor->wl.x = x; + monitor->wl.y = y; + monitor->widthMM = physicalWidth; + monitor->heightMM = physicalHeight; +} + +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; + _GLFWvidmodeWayland mode = { { 0 }, }; + + mode.base.width = width; + mode.base.height = height; + mode.base.refreshRate = refresh / 1000; + mode.flags = flags; + + if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize) + { + int size = monitor->wl.modesSize * 2; + _GLFWvidmodeWayland* modes = + realloc(monitor->wl.modes, + size * sizeof(_GLFWvidmodeWayland)); + monitor->wl.modes = modes; + monitor->wl.modesSize = size; + } + + monitor->wl.modes[monitor->wl.modesCount++] = mode; +} + +static void done(void* data, + struct wl_output* output) +{ + struct _GLFWmonitor *monitor = data; + + monitor->wl.done = GLFW_TRUE; +} + +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 output_listener = { + geometry, + mode, + done, + scale, +}; + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwAddOutputWayland(uint32_t name, uint32_t version) +{ + _GLFWmonitor *monitor; + struct wl_output *output; + char name_str[80]; + + memset(name_str, 0, sizeof(name_str)); + snprintf(name_str, 79, "wl_output@%u", name); + + if (version < 2) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unsupported output interface version"); + return; + } + + monitor = _glfwAllocMonitor(name_str, 0, 0); + + output = wl_registry_bind(_glfw.wl.registry, + name, + &wl_output_interface, + 2); + if (!output) + { + _glfwFreeMonitor(monitor); + return; + } + + monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland)); + monitor->wl.modesSize = 4; + + monitor->wl.scale = 1; + + monitor->wl.output = output; + wl_output_add_listener(output, &output_listener, monitor); + + if (_glfw.wl.monitorsCount + 1 >= _glfw.wl.monitorsSize) + { + _GLFWmonitor** monitors = _glfw.wl.monitors; + int size = _glfw.wl.monitorsSize * 2; + + monitors = realloc(monitors, size * sizeof(_GLFWmonitor*)); + + _glfw.wl.monitors = monitors; + _glfw.wl.monitorsSize = size; + } + + _glfw.wl.monitors[_glfw.wl.monitorsCount++] = monitor; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + _GLFWmonitor** monitors; + _GLFWmonitor* monitor; + int i, monitorsCount = _glfw.wl.monitorsCount; + + if (_glfw.wl.monitorsCount == 0) + goto err; + + monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*)); + + for (i = 0; i < monitorsCount; i++) + { + _GLFWmonitor* origMonitor = _glfw.wl.monitors[i]; + monitor = calloc(1, sizeof(_GLFWmonitor)); + + monitor->modes = + _glfwPlatformGetVideoModes(origMonitor, + &origMonitor->wl.modesCount); + *monitor = *_glfw.wl.monitors[i]; + monitors[i] = monitor; + } + + *count = monitorsCount; + return monitors; + +err: + *count = 0; + return NULL; +} + +GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->wl.output == second->wl.output; +} + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ + if (xpos) + *xpos = monitor->wl.x; + if (ypos) + *ypos = monitor->wl.y; +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + GLFWvidmode *modes; + int i, modesCount = monitor->wl.modesCount; + + modes = calloc(modesCount, sizeof(GLFWvidmode)); + + for (i = 0; i < modesCount; i++) + modes[i] = monitor->wl.modes[i].base; + + *found = modesCount; + return modes; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ + int i; + + for (i = 0; i < monitor->wl.modesCount; i++) + { + if (monitor->wl.modes[i].flags & WL_OUTPUT_MODE_CURRENT) + { + *mode = monitor->wl.modes[i].base; + return; + } + } +} + +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/extern/glfw-3.2.1/src/wl_platform.h b/extern/glfw-3.2.1/src/wl_platform.h new file mode 100644 index 0000000..9e42b36 --- /dev/null +++ b/extern/glfw-3.2.1/src/wl_platform.h @@ -0,0 +1,179 @@ +//======================================================================== +// GLFW 3.2 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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_wayland_platform_h_ +#define _glfw3_wayland_platform_h_ + +#include +#include +#include + +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_tls.h" +#include "posix_time.h" +#include "linux_joystick.h" +#include "xkb_unicode.h" +#include "egl_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 + + +// Wayland-specific video mode data +// +typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland; + +// Wayland-specific per-window data +// +typedef struct _GLFWwindowWayland +{ + int width, height; + GLFWbool visible; + GLFWbool maximized; + struct wl_surface* surface; + struct wl_egl_window* native; + struct wl_shell_surface* shell_surface; + 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 wl_compositor_version; + + struct wl_cursor_theme* cursorTheme; + struct wl_surface* cursorSurface; + uint32_t pointerSerial; + + _GLFWmonitor** monitors; + int monitorsCount; + int monitorsSize; + + short int publicKeys[256]; + + struct { + struct xkb_context* context; + struct xkb_keymap* keymap; + struct xkb_state* state; + xkb_mod_mask_t control_mask; + xkb_mod_mask_t alt_mask; + xkb_mod_mask_t shift_mask; + xkb_mod_mask_t super_mask; + unsigned int modifiers; + } xkb; + + _GLFWwindow* pointerFocus; + _GLFWwindow* keyboardFocus; + +} _GLFWlibraryWayland; + +// Wayland-specific per-monitor data +// +typedef struct _GLFWmonitorWayland +{ + struct wl_output* output; + + _GLFWvidmodeWayland* modes; + int modesCount; + int modesSize; + GLFWbool done; + + 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); + +#endif // _glfw3_wayland_platform_h_ diff --git a/extern/glfw-3.2.1/src/wl_window.c b/extern/glfw-3.2.1/src/wl_window.c new file mode 100644 index 0000000..cf75ec8 --- /dev/null +++ b/extern/glfw-3.2.1/src/wl_window.c @@ -0,0 +1,1050 @@ +//======================================================================== +// GLFW 3.2 Wayland - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +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.wl_compositor_version < 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; + + // TODO: make this optional once issue #197 is fixed. + setOpaqueRegion(window); + + return GLFW_TRUE; +} + +static GLFWbool createShellSurface(_GLFWwindow* window) +{ + window->wl.shell_surface = wl_shell_get_shell_surface(_glfw.wl.shell, + window->wl.surface); + if (!window->wl.shell_surface) + return GLFW_FALSE; + + wl_shell_surface_add_listener(window->wl.shell_surface, + &shellSurfaceListener, + window); + + if (window->wl.title) + wl_shell_surface_set_title(window->wl.shell_surface, window->wl.title); + + if (window->monitor) + { + wl_shell_surface_set_fullscreen( + window->wl.shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, + window->monitor->wl.output); + } + else if (window->wl.maximized) + { + wl_shell_surface_set_maximized(window->wl.shell_surface, NULL); + } + else + { + wl_shell_surface_set_toplevel(window->wl.shell_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) +{ + if (!createSurface(window, wndconfig)) + return GLFW_FALSE; + + if (ctxconfig->client != GLFW_NO_API) + { + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwCreateContextEGL(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.shell_surface = 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.shell_surface) + wl_shell_surface_destroy(window->wl.shell_surface); + + 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.shell_surface) + wl_shell_surface_set_title(window->wl.shell_surface, 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); + 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 _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.shell_surface) + wl_shell_surface_set_toplevel(window->wl.shell_surface); + + window->wl.maximized = GLFW_FALSE; + } +} + +void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +{ + if (!window->monitor && !window->wl.maximized) + { + if (window->wl.shell_surface) + { + // Let the compositor select the best output. + wl_shell_surface_set_maximized(window->wl.shell_surface, NULL); + } + window->wl.maximized = GLFW_TRUE; + } +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ + if (!window->monitor) + { + if (!window->wl.shell_surface) + createShellSurface(window); + window->wl.visible = GLFW_TRUE; + } +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ + if (!window->monitor) + { + if (window->wl.shell_surface) + wl_shell_surface_destroy(window->wl.shell_surface); + window->wl.visible = GLFW_FALSE; + } +} + +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.shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + refreshRate * 1000, // Convert Hz to mHz. + monitor->wl.output); + } + else + { + wl_shell_surface_set_toplevel(window->wl.shell_surface); + } + _glfwInputWindowMonitorChange(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; +} + +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* _glfwPlatformGetKeyName(int key, int scancode) +{ + // TODO + return NULL; +} + +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; +} + +char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_wayland_surface) + return NULL; + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + extensions[1] = strdup("VK_KHR_wayland_surface"); + + *count = 2; + return extensions; +} + +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/extern/glfw-3.2.1/src/x11_init.c b/extern/glfw-3.2.1/src/x11_init.c new file mode 100644 index 0000000..f7a06c1 --- /dev/null +++ b/extern/glfw-3.2.1/src/x11_init.c @@ -0,0 +1,833 @@ +//======================================================================== +// GLFW 3.2 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 + +#include +#include +#include +#include +#include + + +// 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.publicKeys, -1, sizeof(_glfw.x11.publicKeys)); + memset(_glfw.x11.nativeKeys, -1, sizeof(_glfw.x11.nativeKeys)); + + 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.publicKeys[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.publicKeys[scancode] < 0) + _glfw.x11.publicKeys[scancode] = translateKeyCode(scancode); + + // Store the reverse translation for faster key name lookup + if (_glfw.x11.publicKeys[scancode] > 0) + _glfw.x11.nativeKeys[_glfw.x11.publicKeys[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) != 1) + { + if (windowFromRoot) + XFree(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) != 1) + { + XFree(windowFromRoot); + if (windowFromChild) + XFree(windowFromChild); + 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_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"); + + XFree(supportedAtoms); +} + +// Initialize X11 display and look for supported X11 extensions +// +static GLFWbool initExtensions(void) +{ +#if defined(_GLFW_HAS_XF86VM) + // Check for XF86VidMode extension + _glfw.x11.vidmode.available = + XF86VidModeQueryExtension(_glfw.x11.display, + &_glfw.x11.vidmode.eventBase, + &_glfw.x11.vidmode.errorBase); +#endif /*_GLFW_HAS_XF86VM*/ + + // Check for RandR extension + 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 = XRRGetScreenResources(_glfw.x11.display, + _glfw.x11.root); + + if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) + { + // This is either a headless system or an older Nvidia binary driver + // with broken gamma support + // Flag it as useless and fall back to Xf86VidMode gamma, if + // available + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: RandR gamma ramp support seems broken"); + _glfw.x11.randr.gammaBroken = GLFW_TRUE; + } + + XRRFreeScreenResources(sr); + + XRRSelectInput(_glfw.x11.display, _glfw.x11.root, + RROutputChangeNotifyMask); + } + + if (XineramaQueryExtension(_glfw.x11.display, + &_glfw.x11.xinerama.major, + &_glfw.x11.xinerama.minor)) + { + if (XineramaIsActive(_glfw.x11.display)) + _glfw.x11.xinerama.available = GLFW_TRUE; + } + + // Check if Xkb is supported on this display + _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", RTLD_LAZY | RTLD_GLOBAL); + if (_glfw.x11.x11xcb.handle) + { + _glfw.x11.x11xcb.XGetXCBConnection = (XGETXCBCONNECTION_T) + dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection"); + } + + // 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.COMPOUND_STRING = + XInternAtom(_glfw.x11.display, "COMPOUND_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.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.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False); + _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False); + _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", 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; +} + +// Create a blank cursor for hidden and disabled cursor modes +// +static Cursor createHiddenCursor(void) +{ + unsigned char pixels[16 * 16 * 4]; + GLFWimage image = { 16, 16, pixels }; + + memset(pixels, 0, sizeof(pixels)); + + return _glfwCreateCursorX11(&image, 0, 0); +} + +// 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[8192]; + 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; + + 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, apply the environment's locale + // This is done because the C locale breaks wide character input + if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0) + setlocale(LC_CTYPE, ""); +#endif + + XInitThreads(); + + _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(); + + if (!initExtensions()) + return GLFW_FALSE; + + _glfw.x11.cursor = 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 (!_glfwInitThreadLocalStoragePOSIX()) + return GLFW_FALSE; + + if (!_glfwInitJoysticksLinux()) + return GLFW_FALSE; + + _glfwInitTimerPOSIX(); + + return GLFW_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + if (_glfw.x11.x11xcb.handle) + { + dlclose(_glfw.x11.x11xcb.handle); + _glfw.x11.x11xcb.handle = NULL; + } + + if (_glfw.x11.cursor) + { + XFreeCursor(_glfw.x11.display, _glfw.x11.cursor); + _glfw.x11.cursor = (Cursor) 0; + } + + 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; + } + + // NOTE: This needs to be done after XCloseDisplay, as libGL registers + // cleanup callbacks that get called by it + _glfwTerminateGLX(); + + _glfwTerminateJoysticksLinux(); + _glfwTerminateThreadLocalStoragePOSIX(); +} + +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__) + " /dev/js" +#endif +#if defined(_GLFW_HAS_XF86VM) + " Xf86vm" +#endif +#if defined(_GLFW_BUILD_DLL) + " shared" +#endif + ; +} + diff --git a/extern/glfw-3.2.1/src/x11_monitor.c b/extern/glfw-3.2.1/src/x11_monitor.c new file mode 100644 index 0000000..2cec791 --- /dev/null +++ b/extern/glfw-3.2.1/src/x11_monitor.c @@ -0,0 +1,491 @@ +//======================================================================== +// GLFW 3.2 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include +#include + + +// 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 ////// +////////////////////////////////////////////////////////////////////////// + +// 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, ¤t); + if (_glfwCompareVideoModes(¤t, best) == 0) + return GLFW_TRUE; + + sr = XRRGetScreenResources(_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 = XRRGetScreenResources(_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 ////// +////////////////////////////////////////////////////////////////////////// + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int i, j, k, found = 0; + _GLFWmonitor** monitors = NULL; + + *count = 0; + + if (_glfw.x11.randr.available) + { + int screenCount = 0; + XineramaScreenInfo* screens = NULL; + XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, + _glfw.x11.root); + RROutput primary = XRRGetOutputPrimary(_glfw.x11.display, + _glfw.x11.root); + + monitors = calloc(sr->noutput, sizeof(_GLFWmonitor*)); + + if (_glfw.x11.xinerama.available) + screens = XineramaQueryScreens(_glfw.x11.display, &screenCount); + + for (i = 0; i < sr->ncrtc; i++) + { + XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, + sr, sr->crtcs[i]); + + for (j = 0; j < ci->noutput; j++) + { + int widthMM, heightMM; + _GLFWmonitor* monitor; + XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, + sr, ci->outputs[j]); + if (oi->connection != RR_Connected) + { + XRRFreeOutputInfo(oi); + continue; + } + + 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 = ci->outputs[j]; + monitor->x11.crtc = oi->crtc; + + for (k = 0; k < screenCount; k++) + { + if (screens[k].x_org == ci->x && + screens[k].y_org == ci->y && + screens[k].width == ci->width && + screens[k].height == ci->height) + { + monitor->x11.index = k; + break; + } + } + + XRRFreeOutputInfo(oi); + + found++; + monitors[found - 1] = monitor; + + if (ci->outputs[j] == primary) + _GLFW_SWAP_POINTERS(monitors[0], monitors[found - 1]); + } + + XRRFreeCrtcInfo(ci); + } + + XRRFreeScreenResources(sr); + + if (screens) + XFree(screens); + + if (found == 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: RandR monitor support seems broken"); + + _glfw.x11.randr.monitorBroken = GLFW_TRUE; + free(monitors); + monitors = NULL; + } + } + + if (!monitors) + { + monitors = calloc(1, sizeof(_GLFWmonitor*)); + monitors[0] = _glfwAllocMonitor("Display", + DisplayWidthMM(_glfw.x11.display, + _glfw.x11.screen), + DisplayHeightMM(_glfw.x11.display, + _glfw.x11.screen)); + found = 1; + } + + *count = found; + return monitors; +} + +GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second) +{ + return first->x11.crtc == second->x11.crtc; +} + +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); + } +} + +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); + } +#if defined(_GLFW_HAS_XF86VM) + 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); + } +#endif /*_GLFW_HAS_XF86VM*/ +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) + { + 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); + } +#if defined(_GLFW_HAS_XF86VM) + 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); + } +#endif /*_GLFW_HAS_XF86VM*/ +} + + +////////////////////////////////////////////////////////////////////////// +////// 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/extern/glfw-3.2.1/src/x11_platform.h b/extern/glfw-3.2.1/src/x11_platform.h new file mode 100644 index 0000000..3304306 --- /dev/null +++ b/extern/glfw-3.2.1/src/x11_platform.h @@ -0,0 +1,296 @@ +//======================================================================== +// GLFW 3.2 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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_x11_platform_h_ +#define _glfw3_x11_platform_h_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +// The XRandR extension provides mode setting and gamma control +#include + +// The Xkb extension provides improved keyboard support +#include + +// The Xinerama extension provides legacy monitor indices +#include + +#if defined(_GLFW_HAS_XF86VM) + // The Xf86VidMode extension provides fallback gamma control + #include +#endif + +typedef XID xcb_window_t; +typedef XID xcb_visualid_t; +typedef struct xcb_connection_t xcb_connection_t; +typedef xcb_connection_t* (* XGETXCBCONNECTION_T)(Display*); + +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_tls.h" +#include "posix_time.h" +#include "linux_joystick.h" +#include "xkb_unicode.h" +#include "glx_context.h" +#include "egl_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->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; + + // 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 information from the last KeyPress event + unsigned int lastKeyCode; + Time lastKeyTime; + +} _GLFWwindowX11; + +// X11-specific global data +// +typedef struct _GLFWlibraryX11 +{ + Display* display; + int screen; + Window root; + + // Invisible cursor for hidden cursor mode + Cursor cursor; + // 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; + // Clipboard string (while the selection is owned) + char* clipboardString; + // Key name string + char keyName[64]; + // X11 keycode to GLFW key LUT + short int publicKeys[256]; + // GLFW key to X11 keycode LUT + short int nativeKeys[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_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 XdndLeave; + Atom XdndFinished; + Atom XdndSelection; + + // Selection (clipboard) atoms + Atom TARGETS; + Atom MULTIPLE; + Atom CLIPBOARD; + Atom CLIPBOARD_MANAGER; + Atom SAVE_TARGETS; + Atom NULL_; + Atom UTF8_STRING; + Atom COMPOUND_STRING; + Atom ATOM_PAIR; + Atom GLFW_SELECTION; + + struct { + GLFWbool available; + int eventBase; + int errorBase; + int major; + int minor; + GLFWbool gammaBroken; + GLFWbool monitorBroken; + } 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 { + Window source; + } xdnd; + + struct { + GLFWbool available; + int major; + int minor; + } xinerama; + + struct { + void* handle; + XGETXCBCONNECTION_T XGetXCBConnection; + } x11xcb; + +#if defined(_GLFW_HAS_XF86VM) + struct { + GLFWbool available; + int eventBase; + int errorBase; + } vidmode; +#endif /*_GLFW_HAS_XF86VM*/ + +} _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; + + +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); + +void _glfwGrabErrorHandlerX11(void); +void _glfwReleaseErrorHandlerX11(void); +void _glfwInputErrorX11(int error, const char* message); + +#endif // _glfw3_x11_platform_h_ diff --git a/extern/glfw-3.2.1/src/x11_window.c b/extern/glfw-3.2.1/src/x11_window.c new file mode 100644 index 0000000..077eebb --- /dev/null +++ b/extern/glfw-3.2.1/src/x11_window.c @@ -0,0 +1,2475 @@ +//======================================================================== +// GLFW 3.2 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 +#include + +#include + +#include +#include +#include +#include +#include +#include + +// 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 + + +// 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; + + FD_ZERO(&fds); + FD_SET(fd, &fds); +#if defined(__linux__) + FD_SET(_glfw.linux_js.inotify, &fds); + + if (fd < _glfw.linux_js.inotify) + count = _glfw.linux_js.inotify + 1; +#endif + for (;;) + { + 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; + } + + XFree(state); + return result; +} + +// Returns whether the event is a selection event +// +static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer) +{ + 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; +} + +// 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.publicKeys[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 + { + 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 + { + 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); + + (*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; +} + +// 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.cursor); +} + +// 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); + + // 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) + { + 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)); + } + + 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; + } + } + + 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 pid_t 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 + // HACK: Until a mechanism for specifying the application name is added, the + // initial window title is used as the window class name + if (strlen(wndconfig->title)) + { + XClassHint* hint = XAllocClassHint(); + hint->res_name = (char*) wndconfig->title; + hint->res_class = (char*) wndconfig->title; + + XSetClassHint(_glfw.x11.display, window->x11.handle, hint); + XFree(hint); + } + + if (_glfw.x11.XdndAware) + { + // Announce support for Xdnd (drag and drop) + const Atom version = 5; + 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; + const Atom formats[] = { _glfw.x11.UTF8_STRING, + _glfw.x11.COMPOUND_STRING, + XA_STRING }; + const int formatCount = sizeof(formats) / sizeof(formats[0]); + + 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, + _glfw.x11.COMPOUND_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*) _glfw.x11.clipboardString, + strlen(_glfw.x11.clipboardString)); + } + 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*) _glfw.x11.clipboardString, + strlen(_glfw.x11.clipboardString)); + + return request->property; + } + } + + // The requested target is not supported + + return None; +} + +static void handleSelectionClear(XEvent* event) +{ + 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 void pushSelectionToManager(_GLFWwindow* window) +{ + XConvertSelection(_glfw.x11.display, + _glfw.x11.CLIPBOARD_MANAGER, + _glfw.x11.SAVE_TARGETS, + None, + window->x11.handle, + 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); + } +} + +// 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); + } + + _glfwInputMonitorWindowChange(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; + + _glfwInputMonitorWindowChange(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); + } +} + +// 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*/ + +// 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); + _glfwInputMonitorChange(); + return; + } + } + + if (event->type != GenericEvent) + { + 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 + // Corresponding release events are filtered out by the + // GLFW key repeat logic + if (window->x11.lastKeyCode != keycode || + window->x11.lastKeyTime != event->xkey.time) + { + if (keycode) + _glfwInputKey(window, key, keycode, GLFW_PRESS, mods); + } + + window->x11.lastKeyCode = keycode; + 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; + + 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 + // TODO: Check if UTF-8 string is supported by the source + } + else if (event->xclient.message_type == _glfw.x11.XdndDrop) + { + // The drag operation has finished dropping on + // the window, ask to convert it to a UTF-8 string + _glfw.x11.xdnd.source = event->xclient.data.l[0]; + XConvertSelection(_glfw.x11.display, + _glfw.x11.XdndSelection, + _glfw.x11.UTF8_STRING, + _glfw.x11.XdndSelection, + window->x11.handle, CurrentTime); + } + else if (event->xclient.message_type == _glfw.x11.XdndPosition) + { + // The drag operation has moved over the window + const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; + const int absY = (event->xclient.data.l[2]) & 0xFFFF; + int x, y; + + _glfwPlatformGetWindowPos(window, &x, &y); + _glfwInputCursorPos(window, absX - x, absY - y); + + // Reply that we are ready to copy the dragged data + XEvent reply; + memset(&reply, 0, sizeof(reply)); + + reply.type = ClientMessage; + reply.xclient.window = event->xclient.data.l[0]; + reply.xclient.message_type = _glfw.x11.XdndStatus; + reply.xclient.format = 32; + reply.xclient.data.l[0] = window->x11.handle; + reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle + reply.xclient.data.l[2] = 0; // Specify an empty rectangle + reply.xclient.data.l[3] = 0; + reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; + + XSendEvent(_glfw.x11.display, event->xclient.data.l[0], + False, NoEventMask, &reply); + XFlush(_glfw.x11.display); + } + + return; + } + + case SelectionNotify: + { + if (event->xselection.property) + { + // The converted data from the drag operation has arrived + char* data; + const int 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); + } + + XFree(data); + + 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; + + // Reply that all is well + 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.atom == _glfw.x11.WM_STATE && + event->xproperty.state == PropertyNewValue) + { + const int state = getWindowState(window); + if (state == IconicState) + { + if (window->monitor) + releaseMonitor(window); + + _glfwInputWindowIconify(window, GLFW_TRUE); + } + else if (state == NormalState) + { + if (window->monitor) + acquireMonitor(window); + + _glfwInputWindowIconify(window, GLFW_FALSE); + } + } + + return; + } + + case SelectionClear: + { + handleSelectionClear(event); + return; + } + + case SelectionRequest: + { + handleSelectionRequest(event); + 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); + + if (type != AnyPropertyType && actualType != type) + return 0; + + return itemCount; +} + + +////////////////////////////////////////////////////////////////////////// +////// 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) + { + visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen); + depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen); + } + else + { + if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API) + { + if (!_glfwInitGLX()) + return GLFW_FALSE; + if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) + return GLFW_FALSE; + } + else + { + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) + return GLFW_FALSE; + } + } + + 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 (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + } + + if (window->monitor) + { + _glfwPlatformShowWindow(window); + updateWindowMode(window); + if (!acquireMonitor(window)) + return GLFW_FALSE; + + 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) + { + if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) == + window->x11.handle) + { + pushSelectionToManager(window); + } + + 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 _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 _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); + + _glfwInputWindowMonitorChange(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; + } + } + + XFree(states); + return maximized; +} + +void _glfwPlatformPollEvents(void) +{ + _glfwPollJoystickEvents(); + + int count = XPending(_glfw.x11.display); + while (count--) + { + XEvent event; + XNextEvent(_glfw.x11.display, &event); + processEvent(&event); + } + + if (_glfw.x11.disabledCursorWindow) + centerCursor(_glfw.x11.disabledCursorWindow); + + 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; + _GLFWwindow* window = _glfw.windowListHead; + + 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 = _glfw.x11.NULL_; + + XSendEvent(_glfw.x11.display, window->x11.handle, 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) + { + _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.cursor, CurrentTime); + } + else if (_glfw.x11.disabledCursorWindow == window) + { + _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* _glfwPlatformGetKeyName(int key, int scancode) +{ + KeySym keysym; + int extra; + + if (!_glfw.x11.xkb.available) + return NULL; + + if (key != GLFW_KEY_UNKNOWN) + scancode = _glfw.x11.nativeKeys[key]; + + if (!_glfwIsPrintable(_glfw.x11.publicKeys[scancode])) + return NULL; + + keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0); + if (keysym == NoSymbol) + return NULL; + + XkbTranslateKeySym(_glfw.x11.display, &keysym, 0, + _glfw.x11.keyName, sizeof(_glfw.x11.keyName), + &extra); + + if (!strlen(_glfw.x11.keyName)) + return NULL; + + return _glfw.x11.keyName; +} + +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, + window->x11.handle, CurrentTime); + + if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) != + window->x11.handle) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to become owner of clipboard selection"); + } +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + size_t i; + const Atom formats[] = { _glfw.x11.UTF8_STRING, + _glfw.x11.COMPOUND_STRING, + XA_STRING }; + const size_t formatCount = sizeof(formats) / sizeof(formats[0]); + + if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display, + _glfw.x11.CLIPBOARD))) + { + // 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 _glfw.x11.clipboardString; + } + + free(_glfw.x11.clipboardString); + _glfw.x11.clipboardString = NULL; + + for (i = 0; i < formatCount; i++) + { + char* data; + XEvent event; + + XConvertSelection(_glfw.x11.display, + _glfw.x11.CLIPBOARD, + formats[i], + _glfw.x11.GLFW_SELECTION, + window->x11.handle, CurrentTime); + + while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event)) + waitForEvent(NULL); + + if (event.xselection.property == None) + continue; + + if (_glfwGetWindowPropertyX11(event.xselection.requestor, + event.xselection.property, + event.xselection.target, + (unsigned char**) &data)) + { + _glfw.x11.clipboardString = strdup(data); + } + + XFree(data); + + XDeleteProperty(_glfw.x11.display, + event.xselection.requestor, + event.xselection.property); + + if (_glfw.x11.clipboardString) + break; + } + + if (_glfw.x11.clipboardString == NULL) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "X11: Failed to convert clipboard to string"); + } + + return _glfw.x11.clipboardString; +} + +char** _glfwPlatformGetRequiredInstanceExtensions(uint32_t* count) +{ + char** extensions; + + *count = 0; + + if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle) + { + if (!_glfw.vk.KHR_xlib_surface) + return NULL; + } + + extensions = calloc(2, sizeof(char*)); + extensions[0] = strdup("VK_KHR_surface"); + + if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle) + extensions[1] = strdup("VK_KHR_xcb_surface"); + else + extensions[1] = strdup("VK_KHR_xlib_surface"); + + *count = 2; + return extensions; +} + +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 = + _glfw.x11.x11xcb.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 = + _glfw.x11.x11xcb.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; +} + diff --git a/extern/glfw-3.2.1/src/xkb_unicode.c b/extern/glfw-3.2.1/src/xkb_unicode.c new file mode 100644 index 0000000..3223335 --- /dev/null +++ b/extern/glfw-3.2.1/src/xkb_unicode.c @@ -0,0 +1,889 @@ +//======================================================================== +// GLFW 3.2 X11 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2016 Camilla Berglund +// +// 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 , University of + * Cambridge, April 2001 + * + * Special thanks to Richard Verhoeven 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 }, + // Numeric keypad with numlock on + { 0xff80 /*XKB_KEY_KP_Space*/, ' ' }, + { 0xffbd /*XKB_KEY_KP_Equal*/, '=' }, + { 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 } +}; + + +////////////////////////////////////////////////////////////////////////// +////// 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/extern/glfw-3.2.1/src/xkb_unicode.h b/extern/glfw-3.2.1/src/xkb_unicode.h new file mode 100644 index 0000000..688374d --- /dev/null +++ b/extern/glfw-3.2.1/src/xkb_unicode.h @@ -0,0 +1,33 @@ +//======================================================================== +// GLFW 3.2 Linux - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2014 Jonas Ådahl +// +// 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_xkb_unicode_h_ +#define _glfw3_xkb_unicode_h_ + + +long _glfwKeySym2Unicode(unsigned int keysym); + +#endif // _glfw3_xkb_unicode_h_ diff --git a/extern/glfw-3.2.1/tests/CMakeLists.txt b/extern/glfw-3.2.1/tests/CMakeLists.txt new file mode 100644 index 0000000..205ec37 --- /dev/null +++ b/extern/glfw-3.2.1/tests/CMakeLists.txt @@ -0,0 +1,80 @@ + +link_libraries(glfw) + +if (BUILD_SHARED_LIBS) + link_libraries("${MATH_LIBRARY}") +endif() + +if (MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories("${GLFW_SOURCE_DIR}/deps") + +set(GLAD "${GLFW_SOURCE_DIR}/deps/glad/glad.h" + "${GLFW_SOURCE_DIR}/deps/glad.c") +set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h" + "${GLFW_SOURCE_DIR}/deps/getopt.c") +set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h" + "${GLFW_SOURCE_DIR}/deps/tinycthread.c") + +add_executable(clipboard clipboard.c ${GETOPT} ${GLAD}) +add_executable(events events.c ${GETOPT} ${GLAD}) +add_executable(msaa msaa.c ${GETOPT} ${GLAD}) +add_executable(gamma gamma.c ${GETOPT} ${GLAD}) +add_executable(glfwinfo glfwinfo.c ${GETOPT} ${GLAD}) +add_executable(iconify iconify.c ${GETOPT} ${GLAD}) +add_executable(joysticks joysticks.c ${GLAD}) +add_executable(monitors monitors.c ${GETOPT} ${GLAD}) +add_executable(reopen reopen.c ${GLAD}) +add_executable(cursor cursor.c ${GLAD}) + +add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD} ${GLAD}) +add_executable(icon WIN32 MACOSX_BUNDLE icon.c ${GLAD}) +add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${GLAD}) +add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GETOPT} ${GLAD}) +add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD}) +add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD}) +add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD}) +add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GETOPT} ${GLAD}) + +target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") +target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}") + +set(WINDOWS_BINARIES empty icon sharing tearing threads timeout title windows) +set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo + iconify joysticks monitors reopen cursor) + +if (VULKAN_FOUND) + add_executable(vulkan WIN32 vulkan.c ${ICON}) + target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}") + if (NOT GLFW_VULKAN_STATIC) + target_link_libraries(vulkan "${VULKAN_LIBRARY}") + endif() + list(APPEND WINDOWS_BINARIES vulkan) +endif() + +set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + FOLDER "GLFW3/Tests") + +if (MSVC) + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set_target_properties(empty PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Empty Event") + set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") + set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") + set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads") + set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout") + set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") + set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") + + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL} + MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in") +endif() + diff --git a/extern/glfw-3.2.1/tests/clipboard.c b/extern/glfw-3.2.1/tests/clipboard.c new file mode 100644 index 0000000..d6c961c --- /dev/null +++ b/extern/glfw-3.2.1/tests/clipboard.c @@ -0,0 +1,157 @@ +//======================================================================== +// Clipboard test program +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This program is used to test the clipboard functionality. +// +//======================================================================== + +#include +#include + +#include +#include + +#include "getopt.h" + +#if defined(__APPLE__) + #define MODIFIER GLFW_MOD_SUPER +#else + #define MODIFIER GLFW_MOD_CONTROL +#endif + +static void usage(void) +{ + printf("Usage: clipboard [-h]\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + + case GLFW_KEY_V: + if (mods == MODIFIER) + { + const char* string; + + string = glfwGetClipboardString(window); + if (string) + printf("Clipboard contains \"%s\"\n", string); + else + printf("Clipboard does not contain a string\n"); + } + break; + + case GLFW_KEY_C: + if (mods == MODIFIER) + { + const char* string = "Hello GLFW World!"; + glfwSetClipboardString(window, string); + printf("Setting clipboard to \"%s\"\n", string); + } + break; + } +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(int argc, char** argv) +{ + int ch; + GLFWwindow* window; + + while ((ch = getopt(argc, argv, "h")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + window = glfwCreateWindow(200, 200, "Clipboard Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + + fprintf(stderr, "Failed to open GLFW window\n"); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); + glMatrixMode(GL_MODELVIEW); + + glClearColor(0.5f, 0.5f, 0.5f, 0); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(0.8f, 0.2f, 0.4f); + glRectf(-0.5f, -0.5f, 0.5f, 0.5f); + + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/cursor.c b/extern/glfw-3.2.1/tests/cursor.c new file mode 100644 index 0000000..71799dc --- /dev/null +++ b/extern/glfw-3.2.1/tests/cursor.c @@ -0,0 +1,317 @@ +//======================================================================== +// Cursor & input mode tests +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test provides an interface to the cursor image and cursor mode +// parts of the API. +// +// Custom cursor image generation by urraka. +// +//======================================================================== + +#include +#include + +#if defined(_MSC_VER) + // Make MS math.h define M_PI + #define _USE_MATH_DEFINES +#endif + +#include +#include +#include + +#define CURSOR_FRAME_COUNT 60 + +static double cursor_x; +static double cursor_y; +static int swap_interval = 1; +static int wait_events = GLFW_TRUE; +static int animate_cursor = GLFW_FALSE; +static int track_cursor = GLFW_FALSE; +static GLFWcursor* standard_cursors[6]; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static float star(int x, int y, float t) +{ + const float c = 64 / 2.f; + + const float i = (0.25f * (float) sin(2.f * M_PI * t) + 0.75f); + const float k = 64 * 0.046875f * i; + + const float dist = (float) sqrt((x - c) * (x - c) + (y - c) * (y - c)); + + const float salpha = 1.f - dist / c; + const float xalpha = (float) x == c ? c : k / (float) fabs(x - c); + const float yalpha = (float) y == c ? c : k / (float) fabs(y - c); + + return (float) fmax(0.f, fmin(1.f, i * salpha * 0.2f + salpha * xalpha * yalpha)); +} + +static GLFWcursor* create_cursor_frame(float t) +{ + int i = 0, x, y; + unsigned char buffer[64 * 64 * 4]; + const GLFWimage image = { 64, 64, buffer }; + + for (y = 0; y < image.width; y++) + { + for (x = 0; x < image.height; x++) + { + buffer[i++] = 255; + buffer[i++] = 255; + buffer[i++] = 255; + buffer[i++] = (unsigned char) (255 * star(x, y, t)); + } + } + + return glfwCreateCursor(&image, image.width / 2, image.height / 2); +} + +static void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + printf("%0.3f: Cursor position: %f %f (%+f %+f)\n", + glfwGetTime(), + x, y, x - cursor_x, y - cursor_y); + + cursor_x = x; + cursor_y = y; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_A: + { + animate_cursor = !animate_cursor; + if (!animate_cursor) + glfwSetCursor(window, NULL); + + break; + } + + case GLFW_KEY_ESCAPE: + { + if (glfwGetInputMode(window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED) + { + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } + + /* FALLTHROUGH */ + } + + case GLFW_KEY_N: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + printf("(( cursor is normal ))\n"); + break; + + case GLFW_KEY_D: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + printf("(( cursor is disabled ))\n"); + break; + + case GLFW_KEY_H: + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + printf("(( cursor is hidden ))\n"); + break; + + case GLFW_KEY_SPACE: + swap_interval = 1 - swap_interval; + printf("(( swap interval: %i ))\n", swap_interval); + glfwSwapInterval(swap_interval); + break; + + case GLFW_KEY_W: + wait_events = !wait_events; + printf("(( %sing for events ))\n", wait_events ? "wait" : "poll"); + break; + + case GLFW_KEY_T: + track_cursor = !track_cursor; + break; + + case GLFW_KEY_0: + glfwSetCursor(window, NULL); + break; + + case GLFW_KEY_1: + glfwSetCursor(window, standard_cursors[0]); + break; + + case GLFW_KEY_2: + glfwSetCursor(window, standard_cursors[1]); + break; + + case GLFW_KEY_3: + glfwSetCursor(window, standard_cursors[2]); + break; + + case GLFW_KEY_4: + glfwSetCursor(window, standard_cursors[3]); + break; + + case GLFW_KEY_5: + glfwSetCursor(window, standard_cursors[4]); + break; + + case GLFW_KEY_6: + glfwSetCursor(window, standard_cursors[5]); + break; + } +} + +int main(void) +{ + int i; + GLFWwindow* window; + GLFWcursor* star_cursors[CURSOR_FRAME_COUNT]; + GLFWcursor* current_frame = NULL; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + for (i = 0; i < CURSOR_FRAME_COUNT; i++) + { + star_cursors[i] = create_cursor_frame(i / (float) CURSOR_FRAME_COUNT); + if (!star_cursors[i]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + for (i = 0; i < sizeof(standard_cursors) / sizeof(standard_cursors[0]); i++) + { + const int shapes[] = { + GLFW_ARROW_CURSOR, + GLFW_IBEAM_CURSOR, + GLFW_CROSSHAIR_CURSOR, + GLFW_HAND_CURSOR, + GLFW_HRESIZE_CURSOR, + GLFW_VRESIZE_CURSOR + }; + + standard_cursors[i] = glfwCreateStandardCursor(shapes[i]); + if (!standard_cursors[i]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + window = glfwCreateWindow(640, 480, "Cursor Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + + glfwGetCursorPos(window, &cursor_x, &cursor_y); + printf("Cursor position: %f %f\n", cursor_x, cursor_y); + + glfwSetCursorPosCallback(window, cursor_position_callback); + glfwSetKeyCallback(window, key_callback); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + if (track_cursor) + { + int wnd_width, wnd_height, fb_width, fb_height; + float scale; + + glfwGetWindowSize(window, &wnd_width, &wnd_height); + glfwGetFramebufferSize(window, &fb_width, &fb_height); + + scale = (float) fb_width / (float) wnd_width; + + glViewport(0, 0, fb_width, fb_height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.f, fb_width, 0.f, fb_height, 0.f, 1.f); + + glBegin(GL_LINES); + glVertex2f(0.f, (GLfloat) (fb_height - cursor_y * scale)); + glVertex2f((GLfloat) fb_width, (GLfloat) (fb_height - cursor_y * scale)); + glVertex2f((GLfloat) cursor_x * scale, 0.f); + glVertex2f((GLfloat) cursor_x * scale, (GLfloat) fb_height); + glEnd(); + } + + glfwSwapBuffers(window); + + if (animate_cursor) + { + const int i = (int) (glfwGetTime() * 30.0) % CURSOR_FRAME_COUNT; + if (current_frame != star_cursors[i]) + { + glfwSetCursor(window, star_cursors[i]); + current_frame = star_cursors[i]; + } + } + else + current_frame = NULL; + + if (wait_events) + { + if (animate_cursor) + glfwWaitEventsTimeout(1.0 / 30.0); + else + glfwWaitEvents(); + } + else + glfwPollEvents(); + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + glfwDestroyWindow(window); + + for (i = 0; i < CURSOR_FRAME_COUNT; i++) + glfwDestroyCursor(star_cursors[i]); + + for (i = 0; i < sizeof(standard_cursors) / sizeof(standard_cursors[0]); i++) + glfwDestroyCursor(standard_cursors[i]); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/empty.c b/extern/glfw-3.2.1/tests/empty.c new file mode 100644 index 0000000..f4a51b7 --- /dev/null +++ b/extern/glfw-3.2.1/tests/empty.c @@ -0,0 +1,131 @@ +//======================================================================== +// Empty event test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test is intended to verify that posting of empty events works +// +//======================================================================== + +#include "tinycthread.h" + +#include +#include + +#include +#include +#include + +static volatile int running = GLFW_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + struct timespec time; + + while (running) + { + clock_gettime(CLOCK_REALTIME, &time); + time.tv_sec += 1; + thrd_sleep(&time, NULL); + + glfwPostEmptyEvent(); + } + + return 0; +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +static float nrand(void) +{ + return (float) rand() / (float) RAND_MAX; +} + +int main(void) +{ + int result; + thrd_t thread; + GLFWwindow* window; + + srand((unsigned int) time(NULL)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Empty Event Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSetKeyCallback(window, key_callback); + + if (thrd_create(&thread, thread_main, NULL) != thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + while (running) + { + int width, height; + float r = nrand(), g = nrand(), b = nrand(); + float l = (float) sqrt(r * r + g * g + b * b); + + glfwGetFramebufferSize(window, &width, &height); + + glViewport(0, 0, width, height); + glClearColor(r / l, g / l, b / l, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + + glfwWaitEvents(); + + if (glfwWindowShouldClose(window)) + running = GLFW_FALSE; + } + + glfwHideWindow(window); + thrd_join(thread, &result); + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/events.c b/extern/glfw-3.2.1/tests/events.c new file mode 100644 index 0000000..674b584 --- /dev/null +++ b/extern/glfw-3.2.1/tests/events.c @@ -0,0 +1,620 @@ +//======================================================================== +// Event linter (event spewer) +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test hooks every available callback and outputs their arguments +// +// Log messages go to stdout, error messages to stderr +// +// Every event also gets a (sequential) number to aid discussion of logs +// +//======================================================================== + +#include +#include + +#include +#include +#include +#include +#include + +#include "getopt.h" + +// Event index +static unsigned int counter = 0; + +typedef struct +{ + GLFWwindow* window; + int number; + int closeable; +} Slot; + +static void usage(void) +{ + printf("Usage: events [-f] [-h] [-n WINDOWS]\n"); + printf("Options:\n"); + printf(" -f use full screen\n"); + printf(" -h show this help\n"); + printf(" -n the number of windows to create\n"); +} + +static const char* get_key_name(int key) +{ + switch (key) + { + // Printable keys + case GLFW_KEY_A: return "A"; + case GLFW_KEY_B: return "B"; + case GLFW_KEY_C: return "C"; + case GLFW_KEY_D: return "D"; + case GLFW_KEY_E: return "E"; + case GLFW_KEY_F: return "F"; + case GLFW_KEY_G: return "G"; + case GLFW_KEY_H: return "H"; + case GLFW_KEY_I: return "I"; + case GLFW_KEY_J: return "J"; + case GLFW_KEY_K: return "K"; + case GLFW_KEY_L: return "L"; + case GLFW_KEY_M: return "M"; + case GLFW_KEY_N: return "N"; + case GLFW_KEY_O: return "O"; + case GLFW_KEY_P: return "P"; + case GLFW_KEY_Q: return "Q"; + case GLFW_KEY_R: return "R"; + case GLFW_KEY_S: return "S"; + case GLFW_KEY_T: return "T"; + case GLFW_KEY_U: return "U"; + case GLFW_KEY_V: return "V"; + case GLFW_KEY_W: return "W"; + case GLFW_KEY_X: return "X"; + case GLFW_KEY_Y: return "Y"; + case GLFW_KEY_Z: return "Z"; + case GLFW_KEY_1: return "1"; + case GLFW_KEY_2: return "2"; + case GLFW_KEY_3: return "3"; + case GLFW_KEY_4: return "4"; + case GLFW_KEY_5: return "5"; + case GLFW_KEY_6: return "6"; + case GLFW_KEY_7: return "7"; + case GLFW_KEY_8: return "8"; + case GLFW_KEY_9: return "9"; + case GLFW_KEY_0: return "0"; + case GLFW_KEY_SPACE: return "SPACE"; + case GLFW_KEY_MINUS: return "MINUS"; + case GLFW_KEY_EQUAL: return "EQUAL"; + case GLFW_KEY_LEFT_BRACKET: return "LEFT BRACKET"; + case GLFW_KEY_RIGHT_BRACKET: return "RIGHT BRACKET"; + case GLFW_KEY_BACKSLASH: return "BACKSLASH"; + case GLFW_KEY_SEMICOLON: return "SEMICOLON"; + case GLFW_KEY_APOSTROPHE: return "APOSTROPHE"; + case GLFW_KEY_GRAVE_ACCENT: return "GRAVE ACCENT"; + case GLFW_KEY_COMMA: return "COMMA"; + case GLFW_KEY_PERIOD: return "PERIOD"; + case GLFW_KEY_SLASH: return "SLASH"; + case GLFW_KEY_WORLD_1: return "WORLD 1"; + case GLFW_KEY_WORLD_2: return "WORLD 2"; + + // Function keys + case GLFW_KEY_ESCAPE: return "ESCAPE"; + case GLFW_KEY_F1: return "F1"; + case GLFW_KEY_F2: return "F2"; + case GLFW_KEY_F3: return "F3"; + case GLFW_KEY_F4: return "F4"; + case GLFW_KEY_F5: return "F5"; + case GLFW_KEY_F6: return "F6"; + case GLFW_KEY_F7: return "F7"; + case GLFW_KEY_F8: return "F8"; + case GLFW_KEY_F9: return "F9"; + case GLFW_KEY_F10: return "F10"; + case GLFW_KEY_F11: return "F11"; + case GLFW_KEY_F12: return "F12"; + case GLFW_KEY_F13: return "F13"; + case GLFW_KEY_F14: return "F14"; + case GLFW_KEY_F15: return "F15"; + case GLFW_KEY_F16: return "F16"; + case GLFW_KEY_F17: return "F17"; + case GLFW_KEY_F18: return "F18"; + case GLFW_KEY_F19: return "F19"; + case GLFW_KEY_F20: return "F20"; + case GLFW_KEY_F21: return "F21"; + case GLFW_KEY_F22: return "F22"; + case GLFW_KEY_F23: return "F23"; + case GLFW_KEY_F24: return "F24"; + case GLFW_KEY_F25: return "F25"; + case GLFW_KEY_UP: return "UP"; + case GLFW_KEY_DOWN: return "DOWN"; + case GLFW_KEY_LEFT: return "LEFT"; + case GLFW_KEY_RIGHT: return "RIGHT"; + case GLFW_KEY_LEFT_SHIFT: return "LEFT SHIFT"; + case GLFW_KEY_RIGHT_SHIFT: return "RIGHT SHIFT"; + case GLFW_KEY_LEFT_CONTROL: return "LEFT CONTROL"; + case GLFW_KEY_RIGHT_CONTROL: return "RIGHT CONTROL"; + case GLFW_KEY_LEFT_ALT: return "LEFT ALT"; + case GLFW_KEY_RIGHT_ALT: return "RIGHT ALT"; + case GLFW_KEY_TAB: return "TAB"; + case GLFW_KEY_ENTER: return "ENTER"; + case GLFW_KEY_BACKSPACE: return "BACKSPACE"; + case GLFW_KEY_INSERT: return "INSERT"; + case GLFW_KEY_DELETE: return "DELETE"; + case GLFW_KEY_PAGE_UP: return "PAGE UP"; + case GLFW_KEY_PAGE_DOWN: return "PAGE DOWN"; + case GLFW_KEY_HOME: return "HOME"; + case GLFW_KEY_END: return "END"; + case GLFW_KEY_KP_0: return "KEYPAD 0"; + case GLFW_KEY_KP_1: return "KEYPAD 1"; + case GLFW_KEY_KP_2: return "KEYPAD 2"; + case GLFW_KEY_KP_3: return "KEYPAD 3"; + case GLFW_KEY_KP_4: return "KEYPAD 4"; + case GLFW_KEY_KP_5: return "KEYPAD 5"; + case GLFW_KEY_KP_6: return "KEYPAD 6"; + case GLFW_KEY_KP_7: return "KEYPAD 7"; + case GLFW_KEY_KP_8: return "KEYPAD 8"; + case GLFW_KEY_KP_9: return "KEYPAD 9"; + case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE"; + case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY"; + case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT"; + case GLFW_KEY_KP_ADD: return "KEYPAD ADD"; + case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL"; + case GLFW_KEY_KP_EQUAL: return "KEYPAD EQUAL"; + case GLFW_KEY_KP_ENTER: return "KEYPAD ENTER"; + case GLFW_KEY_PRINT_SCREEN: return "PRINT SCREEN"; + case GLFW_KEY_NUM_LOCK: return "NUM LOCK"; + case GLFW_KEY_CAPS_LOCK: return "CAPS LOCK"; + case GLFW_KEY_SCROLL_LOCK: return "SCROLL LOCK"; + case GLFW_KEY_PAUSE: return "PAUSE"; + case GLFW_KEY_LEFT_SUPER: return "LEFT SUPER"; + case GLFW_KEY_RIGHT_SUPER: return "RIGHT SUPER"; + case GLFW_KEY_MENU: return "MENU"; + + default: return "UNKNOWN"; + } +} + +static const char* get_action_name(int action) +{ + switch (action) + { + case GLFW_PRESS: + return "pressed"; + case GLFW_RELEASE: + return "released"; + case GLFW_REPEAT: + return "repeated"; + } + + return "caused unknown action"; +} + +static const char* get_button_name(int button) +{ + switch (button) + { + case GLFW_MOUSE_BUTTON_LEFT: + return "left"; + case GLFW_MOUSE_BUTTON_RIGHT: + return "right"; + case GLFW_MOUSE_BUTTON_MIDDLE: + return "middle"; + default: + { + static char name[16]; + sprintf(name, "%i", button); + return name; + } + } +} + +static const char* get_mods_name(int mods) +{ + static char name[512]; + + if (mods == 0) + return " no mods"; + + name[0] = '\0'; + + if (mods & GLFW_MOD_SHIFT) + strcat(name, " shift"); + if (mods & GLFW_MOD_CONTROL) + strcat(name, " control"); + if (mods & GLFW_MOD_ALT) + strcat(name, " alt"); + if (mods & GLFW_MOD_SUPER) + strcat(name, " super"); + + return name; +} + +static const char* get_character_string(int codepoint) +{ + // This assumes UTF-8, which is stupid + static char result[6 + 1]; + + int length = wctomb(result, codepoint); + if (length == -1) + length = 0; + + result[length] = '\0'; + return result; +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void window_pos_callback(GLFWwindow* window, int x, int y) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window position: %i %i\n", + counter++, slot->number, glfwGetTime(), x, y); +} + +static void window_size_callback(GLFWwindow* window, int width, int height) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window size: %i %i\n", + counter++, slot->number, glfwGetTime(), width, height); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Framebuffer size: %i %i\n", + counter++, slot->number, glfwGetTime(), width, height); + + glViewport(0, 0, width, height); +} + +static void window_close_callback(GLFWwindow* window) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window close\n", + counter++, slot->number, glfwGetTime()); + + glfwSetWindowShouldClose(window, slot->closeable); +} + +static void window_refresh_callback(GLFWwindow* window) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window refresh\n", + counter++, slot->number, glfwGetTime()); + + glfwMakeContextCurrent(window); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); +} + +static void window_focus_callback(GLFWwindow* window, int focused) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window %s\n", + counter++, slot->number, glfwGetTime(), + focused ? "focused" : "defocused"); +} + +static void window_iconify_callback(GLFWwindow* window, int iconified) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Window was %s\n", + counter++, slot->number, glfwGetTime(), + iconified ? "iconified" : "restored"); +} + +static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), button, + get_button_name(button), + get_mods_name(mods), + get_action_name(action)); +} + +static void cursor_position_callback(GLFWwindow* window, double x, double y) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Cursor position: %f %f\n", + counter++, slot->number, glfwGetTime(), x, y); +} + +static void cursor_enter_callback(GLFWwindow* window, int entered) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Cursor %s window\n", + counter++, slot->number, glfwGetTime(), + entered ? "entered" : "left"); +} + +static void scroll_callback(GLFWwindow* window, double x, double y) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n", + counter++, slot->number, glfwGetTime(), x, y); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + Slot* slot = glfwGetWindowUserPointer(window); + const char* name = glfwGetKeyName(key, scancode); + + if (name) + { + printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), key, scancode, + get_key_name(key), + name, + get_mods_name(mods), + get_action_name(action)); + } + else + { + printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n", + counter++, slot->number, glfwGetTime(), key, scancode, + get_key_name(key), + get_mods_name(mods), + get_action_name(action)); + } + + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_C: + { + slot->closeable = !slot->closeable; + + printf("(( closing %s ))\n", slot->closeable ? "enabled" : "disabled"); + break; + } + } +} + +static void char_callback(GLFWwindow* window, unsigned int codepoint) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Character 0x%08x (%s) input\n", + counter++, slot->number, glfwGetTime(), codepoint, + get_character_string(codepoint)); +} + +static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int mods) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Character 0x%08x (%s) with modifiers (with%s) input\n", + counter++, slot->number, glfwGetTime(), codepoint, + get_character_string(codepoint), + get_mods_name(mods)); +} + +static void drop_callback(GLFWwindow* window, int count, const char** paths) +{ + int i; + Slot* slot = glfwGetWindowUserPointer(window); + + printf("%08x to %i at %0.3f: Drop input\n", + counter++, slot->number, glfwGetTime()); + + for (i = 0; i < count; i++) + printf(" %i: \"%s\"\n", i, paths[i]); +} + +static void monitor_callback(GLFWmonitor* monitor, int event) +{ + if (event == GLFW_CONNECTED) + { + int x, y, widthMM, heightMM; + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwGetMonitorPos(monitor, &x, &y); + glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); + + printf("%08x at %0.3f: Monitor %s (%ix%i at %ix%i, %ix%i mm) was connected\n", + counter++, + glfwGetTime(), + glfwGetMonitorName(monitor), + mode->width, mode->height, + x, y, + widthMM, heightMM); + } + else if (event == GLFW_DISCONNECTED) + { + printf("%08x at %0.3f: Monitor %s was disconnected\n", + counter++, + glfwGetTime(), + glfwGetMonitorName(monitor)); + } +} + +static void joystick_callback(int joy, int event) +{ + if (event == GLFW_CONNECTED) + { + int axisCount, buttonCount; + + glfwGetJoystickAxes(joy, &axisCount); + glfwGetJoystickButtons(joy, &buttonCount); + + printf("%08x at %0.3f: Joystick %i (%s) was connected with %i axes and %i buttons\n", + counter++, glfwGetTime(), + joy, + glfwGetJoystickName(joy), + axisCount, + buttonCount); + } + else + { + printf("%08x at %0.3f: Joystick %i was disconnected\n", + counter++, glfwGetTime(), joy); + } +} + +int main(int argc, char** argv) +{ + Slot* slots; + GLFWmonitor* monitor = NULL; + int ch, i, width, height, count = 1; + + setlocale(LC_ALL, ""); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + printf("Library initialized\n"); + + glfwSetMonitorCallback(monitor_callback); + glfwSetJoystickCallback(joystick_callback); + + while ((ch = getopt(argc, argv, "hfn:")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + + case 'n': + count = (int) strtol(optarg, NULL, 10); + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + if (!count) + { + fprintf(stderr, "Invalid user\n"); + exit(EXIT_FAILURE); + } + + slots = calloc(count, sizeof(Slot)); + + for (i = 0; i < count; i++) + { + char title[128]; + + slots[i].closeable = GLFW_TRUE; + slots[i].number = i + 1; + + sprintf(title, "Event Linter (Window %i)", slots[i].number); + + if (monitor) + { + printf("Creating full screen window %i (%ix%i on %s)\n", + slots[i].number, + width, height, + glfwGetMonitorName(monitor)); + } + else + { + printf("Creating windowed mode window %i (%ix%i)\n", + slots[i].number, + width, height); + } + + slots[i].window = glfwCreateWindow(width, height, title, monitor, NULL); + if (!slots[i].window) + { + free(slots); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowUserPointer(slots[i].window, slots + i); + + glfwSetWindowPosCallback(slots[i].window, window_pos_callback); + glfwSetWindowSizeCallback(slots[i].window, window_size_callback); + glfwSetFramebufferSizeCallback(slots[i].window, framebuffer_size_callback); + glfwSetWindowCloseCallback(slots[i].window, window_close_callback); + glfwSetWindowRefreshCallback(slots[i].window, window_refresh_callback); + glfwSetWindowFocusCallback(slots[i].window, window_focus_callback); + glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback); + glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback); + glfwSetCursorPosCallback(slots[i].window, cursor_position_callback); + glfwSetCursorEnterCallback(slots[i].window, cursor_enter_callback); + glfwSetScrollCallback(slots[i].window, scroll_callback); + glfwSetKeyCallback(slots[i].window, key_callback); + glfwSetCharCallback(slots[i].window, char_callback); + glfwSetCharModsCallback(slots[i].window, char_mods_callback); + glfwSetDropCallback(slots[i].window, drop_callback); + + glfwMakeContextCurrent(slots[i].window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + } + + printf("Main loop starting\n"); + + for (;;) + { + for (i = 0; i < count; i++) + { + if (glfwWindowShouldClose(slots[i].window)) + break; + } + + if (i < count) + break; + + glfwWaitEvents(); + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + free(slots); + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/gamma.c b/extern/glfw-3.2.1/tests/gamma.c new file mode 100644 index 0000000..a80392f --- /dev/null +++ b/extern/glfw-3.2.1/tests/gamma.c @@ -0,0 +1,188 @@ +//======================================================================== +// Gamma correction test program +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This program is used to test the gamma correction functionality for +// both full screen and windowed mode windows +// +//======================================================================== + +#include +#include + +#include +#include + +#include "getopt.h" + +#define STEP_SIZE 0.1f + +static GLfloat gamma_value = 1.0f; + +static void usage(void) +{ + printf("Usage: gamma [-h] [-f]\n"); + printf("Options:\n"); + printf(" -f create full screen window\n"); + printf(" -h show this help\n"); +} + +static void set_gamma(GLFWwindow* window, float value) +{ + GLFWmonitor* monitor = glfwGetWindowMonitor(window); + if (!monitor) + monitor = glfwGetPrimaryMonitor(); + + gamma_value = value; + printf("Gamma: %f\n", gamma_value); + glfwSetGamma(monitor, gamma_value); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + { + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } + + case GLFW_KEY_KP_ADD: + case GLFW_KEY_UP: + case GLFW_KEY_Q: + { + set_gamma(window, gamma_value + STEP_SIZE); + break; + } + + case GLFW_KEY_KP_SUBTRACT: + case GLFW_KEY_DOWN: + case GLFW_KEY_W: + { + if (gamma_value - STEP_SIZE > 0.f) + set_gamma(window, gamma_value - STEP_SIZE); + + break; + } + } +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(int argc, char** argv) +{ + int width, height, ch; + GLFWmonitor* monitor = NULL; + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + while ((ch = getopt(argc, argv, "fh")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + monitor = glfwGetPrimaryMonitor(); + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 200; + height = 200; + } + + window = glfwCreateWindow(width, height, "Gamma Test", monitor, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + set_gamma(window, 1.f); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); + glMatrixMode(GL_MODELVIEW); + + glClearColor(0.5f, 0.5f, 0.5f, 0); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(0.8f, 0.2f, 0.4f); + glRectf(-0.5f, -0.5f, 0.5f, 0.5f); + + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/glfwinfo.c b/extern/glfw-3.2.1/tests/glfwinfo.c new file mode 100644 index 0000000..a3e286f --- /dev/null +++ b/extern/glfw-3.2.1/tests/glfwinfo.c @@ -0,0 +1,899 @@ +//======================================================================== +// Context creation and information tool +// Copyright (c) Camilla Berglund +// +// 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 VK_NO_PROTOTYPES +#include +#include +#include + +#include +#include +#include + +#include "getopt.h" + +#ifdef _MSC_VER +#define strcasecmp(x, y) _stricmp(x, y) +#endif + +#define API_NAME_OPENGL "gl" +#define API_NAME_OPENGL_ES "es" + +#define API_NAME_NATIVE "native" +#define API_NAME_EGL "egl" + +#define PROFILE_NAME_CORE "core" +#define PROFILE_NAME_COMPAT "compat" + +#define STRATEGY_NAME_NONE "none" +#define STRATEGY_NAME_LOSE "lose" + +#define BEHAVIOR_NAME_NONE "none" +#define BEHAVIOR_NAME_FLUSH "flush" + +static void usage(void) +{ + printf("Usage: glfwinfo [OPTION]...\n"); + printf("Options:\n"); + printf(" -a, --client-api=API the client API to use (" + API_NAME_OPENGL " or " + API_NAME_OPENGL_ES ")\n"); + printf(" -b, --behavior=BEHAVIOR the release behavior to use (" + BEHAVIOR_NAME_NONE " or " + BEHAVIOR_NAME_FLUSH ")\n"); + printf(" -c, --context-api=API the context creation API to use (" + API_NAME_NATIVE " or " + API_NAME_EGL ")\n"); + printf(" -d, --debug request a debug context\n"); + printf(" -f, --forward require a forward-compatible context\n"); + printf(" -h, --help show this help\n"); + printf(" -l, --list-extensions list all Vulkan and client API extensions\n"); + printf(" --list-layers list all Vulkan layers\n"); + printf(" -m, --major=MAJOR the major number of the required " + "client API version\n"); + printf(" -n, --minor=MINOR the minor number of the required " + "client API version\n"); + printf(" -p, --profile=PROFILE the OpenGL profile to use (" + PROFILE_NAME_CORE " or " + PROFILE_NAME_COMPAT ")\n"); + printf(" -s, --robustness=STRATEGY the robustness strategy to use (" + STRATEGY_NAME_NONE " or " + STRATEGY_NAME_LOSE ")\n"); + printf(" -v, --version print version information\n"); + printf(" --red-bits=N the number of red bits to request\n"); + printf(" --green-bits=N the number of green bits to request\n"); + printf(" --blue-bits=N the number of blue bits to request\n"); + printf(" --alpha-bits=N the number of alpha bits to request\n"); + printf(" --depth-bits=N the number of depth bits to request\n"); + printf(" --stencil-bits=N the number of stencil bits to request\n"); + printf(" --accum-red-bits=N the number of red bits to request\n"); + printf(" --accum-green-bits=N the number of green bits to request\n"); + printf(" --accum-blue-bits=N the number of blue bits to request\n"); + printf(" --accum-alpha-bits=N the number of alpha bits to request\n"); + printf(" --aux-buffers=N the number of aux buffers to request\n"); + printf(" --samples=N the number of MSAA samples to request\n"); + printf(" --stereo request stereo rendering\n"); + printf(" --srgb request an sRGB capable framebuffer\n"); + printf(" --singlebuffer request single-buffering\n"); + printf(" --no-error request a context that does not emit errors\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static const char* get_device_type_name(VkPhysicalDeviceType type) +{ + if (type == VK_PHYSICAL_DEVICE_TYPE_OTHER) + return "other"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) + return "integrated GPU"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + return "discrete GPU"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) + return "virtual GPU"; + else if (type == VK_PHYSICAL_DEVICE_TYPE_CPU) + return "CPU"; + + return "unknown"; +} + +static const char* get_api_name(int api) +{ + if (api == GLFW_OPENGL_API) + return "OpenGL"; + else if (api == GLFW_OPENGL_ES_API) + return "OpenGL ES"; + + return "Unknown API"; +} + +static const char* get_profile_name_gl(GLint mask) +{ + if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + return PROFILE_NAME_COMPAT; + if (mask & GL_CONTEXT_CORE_PROFILE_BIT) + return PROFILE_NAME_CORE; + + return "unknown"; +} + +static const char* get_profile_name_glfw(int profile) +{ + if (profile == GLFW_OPENGL_COMPAT_PROFILE) + return PROFILE_NAME_COMPAT; + if (profile == GLFW_OPENGL_CORE_PROFILE) + return PROFILE_NAME_CORE; + + return "unknown"; +} + +static const char* get_strategy_name_gl(GLint strategy) +{ + if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB) + return STRATEGY_NAME_LOSE; + if (strategy == GL_NO_RESET_NOTIFICATION_ARB) + return STRATEGY_NAME_NONE; + + return "unknown"; +} + +static const char* get_strategy_name_glfw(int strategy) +{ + if (strategy == GLFW_LOSE_CONTEXT_ON_RESET) + return STRATEGY_NAME_LOSE; + if (strategy == GLFW_NO_RESET_NOTIFICATION) + return STRATEGY_NAME_NONE; + + return "unknown"; +} + +static void list_context_extensions(int client, int major, int minor) +{ + int i; + GLint count; + const GLubyte* extensions; + + printf("%s context extensions:\n", get_api_name(client)); + + if (client == GLFW_OPENGL_API && major > 2) + { + glGetIntegerv(GL_NUM_EXTENSIONS, &count); + + for (i = 0; i < count; i++) + printf(" %s\n", (const char*) glGetStringi(GL_EXTENSIONS, i)); + } + else + { + extensions = glGetString(GL_EXTENSIONS); + while (*extensions != '\0') + { + putchar(' '); + + while (*extensions != '\0' && *extensions != ' ') + { + putchar(*extensions); + extensions++; + } + + while (*extensions == ' ') + extensions++; + + putchar('\n'); + } + } +} + +static void list_vulkan_instance_extensions(void) +{ + uint32_t i, ep_count = 0; + VkExtensionProperties* ep; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = + (PFN_vkEnumerateInstanceExtensionProperties) + glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceExtensionProperties"); + + printf("Vulkan instance extensions:\n"); + + if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS) + return; + + ep = calloc(ep_count, sizeof(VkExtensionProperties)); + + if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS) + { + free(ep); + return; + } + + for (i = 0; i < ep_count; i++) + printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion); + + free(ep); +} + +static void list_vulkan_instance_layers(void) +{ + uint32_t i, lp_count = 0; + VkLayerProperties* lp; + PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = + (PFN_vkEnumerateInstanceLayerProperties) + glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceLayerProperties"); + + printf("Vulkan instance layers:\n"); + + if (vkEnumerateInstanceLayerProperties(&lp_count, NULL) != VK_SUCCESS) + return; + + lp = calloc(lp_count, sizeof(VkLayerProperties)); + + if (vkEnumerateInstanceLayerProperties(&lp_count, lp) != VK_SUCCESS) + { + free(lp); + return; + } + + for (i = 0; i < lp_count; i++) + { + printf(" %s (v%u) \"%s\"\n", + lp[i].layerName, + lp[i].specVersion >> 22, + lp[i].description); + } + + free(lp); +} + +static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device) +{ + uint32_t i, ep_count; + VkExtensionProperties* ep; + PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = + (PFN_vkEnumerateDeviceExtensionProperties) + glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceExtensionProperties"); + + printf("Vulkan device extensions:\n"); + + if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS) + return; + + ep = calloc(ep_count, sizeof(VkExtensionProperties)); + + if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS) + { + free(ep); + return; + } + + for (i = 0; i < ep_count; i++) + printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion); + + free(ep); +} + +static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device) +{ + uint32_t i, lp_count; + VkLayerProperties* lp; + PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties = + (PFN_vkEnumerateDeviceLayerProperties) + glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceLayerProperties"); + + printf("Vulkan device layers:\n"); + + if (vkEnumerateDeviceLayerProperties(device, &lp_count, NULL) != VK_SUCCESS) + return; + + lp = calloc(lp_count, sizeof(VkLayerProperties)); + + if (vkEnumerateDeviceLayerProperties(device, &lp_count, lp) != VK_SUCCESS) + { + free(lp); + return; + } + + for (i = 0; i < lp_count; i++) + { + printf(" %s (v%u) \"%s\"\n", + lp[i].layerName, + lp[i].specVersion >> 22, + lp[i].description); + } + + free(lp); +} + +static int valid_version(void) +{ + int major, minor, revision; + glfwGetVersion(&major, &minor, &revision); + + if (major != GLFW_VERSION_MAJOR) + { + printf("*** ERROR: GLFW major version mismatch! ***\n"); + return GLFW_FALSE; + } + + if (minor != GLFW_VERSION_MINOR || revision != GLFW_VERSION_REVISION) + printf("*** WARNING: GLFW version mismatch! ***\n"); + + return GLFW_TRUE; +} + +static void print_version(void) +{ + int major, minor, revision; + glfwGetVersion(&major, &minor, &revision); + + printf("GLFW header version: %u.%u.%u\n", + GLFW_VERSION_MAJOR, + GLFW_VERSION_MINOR, + GLFW_VERSION_REVISION); + printf("GLFW library version: %u.%u.%u\n", major, minor, revision); + printf("GLFW library version string: \"%s\"\n", glfwGetVersionString()); +} + +int main(int argc, char** argv) +{ + int ch, client, major, minor, revision, profile; + GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; + int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE; + GLenum error; + GLFWwindow* window; + + enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS, + MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION, + REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS, + ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS, + AUXBUFFERS, SAMPLES, STEREO, SRGB, SINGLEBUFFER, NOERROR_SRSLY }; + const struct option options[] = + { + { "behavior", 1, NULL, BEHAVIOR }, + { "client-api", 1, NULL, CLIENT }, + { "context-api", 1, NULL, CONTEXT }, + { "debug", 0, NULL, DEBUG }, + { "forward", 0, NULL, FORWARD }, + { "help", 0, NULL, HELP }, + { "list-extensions", 0, NULL, EXTENSIONS }, + { "list-layers", 0, NULL, LAYERS }, + { "major", 1, NULL, MAJOR }, + { "minor", 1, NULL, MINOR }, + { "profile", 1, NULL, PROFILE }, + { "robustness", 1, NULL, ROBUSTNESS }, + { "version", 0, NULL, VERSION }, + { "red-bits", 1, NULL, REDBITS }, + { "green-bits", 1, NULL, GREENBITS }, + { "blue-bits", 1, NULL, BLUEBITS }, + { "alpha-bits", 1, NULL, ALPHABITS }, + { "depth-bits", 1, NULL, DEPTHBITS }, + { "stencil-bits", 1, NULL, STENCILBITS }, + { "accum-red-bits", 1, NULL, ACCUMREDBITS }, + { "accum-green-bits", 1, NULL, ACCUMGREENBITS }, + { "accum-blue-bits", 1, NULL, ACCUMBLUEBITS }, + { "accum-alpha-bits", 1, NULL, ACCUMALPHABITS }, + { "aux-buffers", 1, NULL, AUXBUFFERS }, + { "samples", 1, NULL, SAMPLES }, + { "stereo", 0, NULL, STEREO }, + { "srgb", 0, NULL, SRGB }, + { "singlebuffer", 0, NULL, SINGLEBUFFER }, + { "no-error", 0, NULL, NOERROR_SRSLY }, + { NULL, 0, NULL, 0 } + }; + + // Initialize GLFW and create window + + if (!valid_version()) + exit(EXIT_FAILURE); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + while ((ch = getopt_long(argc, argv, "a:b:c:dfhlm:n:p:s:v", options, NULL)) != -1) + { + switch (ch) + { + case 'a': + case CLIENT: + if (strcasecmp(optarg, API_NAME_OPENGL) == 0) + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); + else if (strcasecmp(optarg, API_NAME_OPENGL_ES) == 0) + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 'b': + case BEHAVIOR: + if (strcasecmp(optarg, BEHAVIOR_NAME_NONE) == 0) + { + glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, + GLFW_RELEASE_BEHAVIOR_NONE); + } + else if (strcasecmp(optarg, BEHAVIOR_NAME_FLUSH) == 0) + { + glfwWindowHint(GLFW_CONTEXT_RELEASE_BEHAVIOR, + GLFW_RELEASE_BEHAVIOR_FLUSH); + } + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 'c': + case CONTEXT: + if (strcasecmp(optarg, API_NAME_NATIVE) == 0) + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); + else if (strcasecmp(optarg, API_NAME_EGL) == 0) + glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 'd': + case DEBUG: + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); + break; + case 'f': + case FORWARD: + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); + break; + case 'h': + case HELP: + usage(); + exit(EXIT_SUCCESS); + case 'l': + case EXTENSIONS: + list_extensions = GLFW_TRUE; + break; + case LAYERS: + list_layers = GLFW_TRUE; + break; + case 'm': + case MAJOR: + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, atoi(optarg)); + break; + case 'n': + case MINOR: + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, atoi(optarg)); + break; + case 'p': + case PROFILE: + if (strcasecmp(optarg, PROFILE_NAME_CORE) == 0) + { + glfwWindowHint(GLFW_OPENGL_PROFILE, + GLFW_OPENGL_CORE_PROFILE); + } + else if (strcasecmp(optarg, PROFILE_NAME_COMPAT) == 0) + { + glfwWindowHint(GLFW_OPENGL_PROFILE, + GLFW_OPENGL_COMPAT_PROFILE); + } + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 's': + case ROBUSTNESS: + if (strcasecmp(optarg, STRATEGY_NAME_NONE) == 0) + { + glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, + GLFW_NO_RESET_NOTIFICATION); + } + else if (strcasecmp(optarg, STRATEGY_NAME_LOSE) == 0) + { + glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, + GLFW_LOSE_CONTEXT_ON_RESET); + } + else + { + usage(); + exit(EXIT_FAILURE); + } + break; + case 'v': + case VERSION: + print_version(); + exit(EXIT_SUCCESS); + case REDBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_RED_BITS, atoi(optarg)); + break; + case GREENBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_GREEN_BITS, atoi(optarg)); + break; + case BLUEBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_BLUE_BITS, atoi(optarg)); + break; + case ALPHABITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_ALPHA_BITS, atoi(optarg)); + break; + case DEPTHBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_DEPTH_BITS, atoi(optarg)); + break; + case STENCILBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_STENCIL_BITS, atoi(optarg)); + break; + case ACCUMREDBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_ACCUM_RED_BITS, atoi(optarg)); + break; + case ACCUMGREENBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_ACCUM_GREEN_BITS, atoi(optarg)); + break; + case ACCUMBLUEBITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_ACCUM_BLUE_BITS, atoi(optarg)); + break; + case ACCUMALPHABITS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, atoi(optarg)); + break; + case AUXBUFFERS: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_AUX_BUFFERS, atoi(optarg)); + break; + case SAMPLES: + if (strcmp(optarg, "-") == 0) + glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE); + else + glfwWindowHint(GLFW_SAMPLES, atoi(optarg)); + break; + case STEREO: + glfwWindowHint(GLFW_STEREO, GLFW_TRUE); + break; + case SRGB: + glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE); + break; + case SINGLEBUFFER: + glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE); + break; + case NOERROR_SRSLY: + glfwWindowHint(GLFW_CONTEXT_NO_ERROR, GLFW_TRUE); + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + print_version(); + + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + window = glfwCreateWindow(200, 200, "Version", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + + error = glGetError(); + if (error != GL_NO_ERROR) + printf("*** OpenGL error after make current: 0x%08x ***\n", error); + + // Report client API version + + client = glfwGetWindowAttrib(window, GLFW_CLIENT_API); + major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); + minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); + revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); + profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE); + + printf("%s context version string: \"%s\"\n", + get_api_name(client), + glGetString(GL_VERSION)); + + printf("%s context version parsed by GLFW: %u.%u.%u\n", + get_api_name(client), + major, minor, revision); + + // Report client API context properties + + if (client == GLFW_OPENGL_API) + { + if (major >= 3) + { + GLint flags; + + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + printf("%s context flags (0x%08x):", get_api_name(client), flags); + + if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) + printf(" forward-compatible"); + if (flags & 2/*GL_CONTEXT_FLAG_DEBUG_BIT*/) + printf(" debug"); + if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) + printf(" robustness"); + if (flags & 8/*GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR*/) + printf(" no-error"); + putchar('\n'); + + printf("%s context flags parsed by GLFW:", get_api_name(client)); + + if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT)) + printf(" forward-compatible"); + if (glfwGetWindowAttrib(window, GLFW_OPENGL_DEBUG_CONTEXT)) + printf(" debug"); + if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET) + printf(" robustness"); + if (glfwGetWindowAttrib(window, GLFW_CONTEXT_NO_ERROR)) + printf(" no-error"); + putchar('\n'); + } + + if (major >= 4 || (major == 3 && minor >= 2)) + { + GLint mask; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); + + printf("%s profile mask (0x%08x): %s\n", + get_api_name(client), + mask, + get_profile_name_gl(mask)); + + printf("%s profile mask parsed by GLFW: %s\n", + get_api_name(client), + get_profile_name_glfw(profile)); + } + + if (glfwExtensionSupported("GL_ARB_robustness")) + { + const int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS); + GLint strategy; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy); + + printf("%s robustness strategy (0x%08x): %s\n", + get_api_name(client), + strategy, + get_strategy_name_gl(strategy)); + + printf("%s robustness strategy parsed by GLFW: %s\n", + get_api_name(client), + get_strategy_name_glfw(robustness)); + } + } + + printf("%s context renderer string: \"%s\"\n", + get_api_name(client), + glGetString(GL_RENDERER)); + printf("%s context vendor string: \"%s\"\n", + get_api_name(client), + glGetString(GL_VENDOR)); + + if (major >= 2) + { + printf("%s context shading language version: \"%s\"\n", + get_api_name(client), + glGetString(GL_SHADING_LANGUAGE_VERSION)); + } + + printf("%s framebuffer:\n", get_api_name(client)); + + if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE) + { + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, + &redbits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, + &greenbits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, + &bluebits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, + &alphabits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_DEPTH, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, + &depthbits); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, + GL_STENCIL, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + &stencilbits); + } + else + { + glGetIntegerv(GL_RED_BITS, &redbits); + glGetIntegerv(GL_GREEN_BITS, &greenbits); + glGetIntegerv(GL_BLUE_BITS, &bluebits); + glGetIntegerv(GL_ALPHA_BITS, &alphabits); + glGetIntegerv(GL_DEPTH_BITS, &depthbits); + glGetIntegerv(GL_STENCIL_BITS, &stencilbits); + } + + printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n", + redbits, greenbits, bluebits, alphabits, depthbits, stencilbits); + + if (client == GLFW_OPENGL_ES_API || + glfwExtensionSupported("GL_ARB_multisample") || + major > 1 || minor >= 3) + { + GLint samples, samplebuffers; + glGetIntegerv(GL_SAMPLES, &samples); + glGetIntegerv(GL_SAMPLE_BUFFERS, &samplebuffers); + + printf(" samples: %u sample buffers: %u\n", samples, samplebuffers); + } + + if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE) + { + GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits; + GLint auxbuffers; + + glGetIntegerv(GL_ACCUM_RED_BITS, &accumredbits); + glGetIntegerv(GL_ACCUM_GREEN_BITS, &accumgreenbits); + glGetIntegerv(GL_ACCUM_BLUE_BITS, &accumbluebits); + glGetIntegerv(GL_ACCUM_ALPHA_BITS, &accumalphabits); + glGetIntegerv(GL_AUX_BUFFERS, &auxbuffers); + + printf(" accum red: %u accum green: %u accum blue: %u accum alpha: %u aux buffers: %u\n", + accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers); + } + + if (list_extensions) + list_context_extensions(client, major, minor); + + printf("Vulkan loader: %s\n", + glfwVulkanSupported() ? "available" : "missing"); + + if (glfwVulkanSupported()) + { + uint32_t i, re_count, pd_count; + const char** re; + VkApplicationInfo ai = {0}; + VkInstanceCreateInfo ici = {0}; + VkInstance instance; + VkPhysicalDevice* pd; + PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance) + glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); + PFN_vkDestroyInstance vkDestroyInstance; + PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; + + re = glfwGetRequiredInstanceExtensions(&re_count); + + printf("Vulkan required instance extensions:"); + for (i = 0; i < re_count; i++) + printf(" %s", re[i]); + putchar('\n'); + + if (list_extensions) + list_vulkan_instance_extensions(); + + if (list_layers) + list_vulkan_instance_layers(); + + ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + ai.pApplicationName = "glfwinfo"; + ai.applicationVersion = GLFW_VERSION_MAJOR; + ai.pEngineName = "GLFW"; + ai.engineVersion = GLFW_VERSION_MAJOR; + ai.apiVersion = VK_API_VERSION_1_0; + + ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + ici.pApplicationInfo = &ai; + ici.enabledExtensionCount = re_count; + ici.ppEnabledExtensionNames = re; + + if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + vkDestroyInstance = (PFN_vkDestroyInstance) + glfwGetInstanceProcAddress(instance, "vkDestroyInstance"); + vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) + glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices"); + vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) + glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceProperties"); + + if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS) + { + vkDestroyInstance(instance, NULL); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + pd = calloc(pd_count, sizeof(VkPhysicalDevice)); + + if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS) + { + free(pd); + vkDestroyInstance(instance, NULL); + glfwTerminate(); + exit(EXIT_FAILURE); + } + + for (i = 0; i < pd_count; i++) + { + VkPhysicalDeviceProperties pdp; + + vkGetPhysicalDeviceProperties(pd[i], &pdp); + + printf("Vulkan %s device: \"%s\"\n", + get_device_type_name(pdp.deviceType), + pdp.deviceName); + + if (list_extensions) + list_vulkan_device_extensions(instance, pd[i]); + + if (list_layers) + list_vulkan_device_layers(instance, pd[i]); + } + + free(pd); + vkDestroyInstance(instance, NULL); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/icon.c b/extern/glfw-3.2.1/tests/icon.c new file mode 100644 index 0000000..d866ff1 --- /dev/null +++ b/extern/glfw-3.2.1/tests/icon.c @@ -0,0 +1,148 @@ +//======================================================================== +// Window icon test program +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This program is used to test the icon feature. +// +//======================================================================== + +#include +#include + +#include +#include +#include + +// a simple glfw logo +const char* const logo[] = +{ + "................", + "................", + "...0000..0......", + "...0.....0......", + "...0.00..0......", + "...0..0..0......", + "...0000..0000...", + "................", + "................", + "...000..0...0...", + "...0....0...0...", + "...000..0.0.0...", + "...0....0.0.0...", + "...0....00000...", + "................", + "................" +}; + +const unsigned char icon_colors[5][4] = +{ + { 0, 0, 0, 255 }, // black + { 255, 0, 0, 255 }, // red + { 0, 255, 0, 255 }, // green + { 0, 0, 255, 255 }, // blue + { 255, 255, 255, 255 } // white +}; + +static int cur_icon_color = 0; + +static void set_icon(GLFWwindow* window, int icon_color) +{ + int x, y; + unsigned char pixels[16 * 16 * 4]; + unsigned char* target = pixels; + GLFWimage img = { 16, 16, pixels }; + + for (y = 0; y < img.width; y++) + { + for (x = 0; x < img.height; x++) + { + if (logo[y][x] == '0') + memcpy(target, icon_colors[icon_color], 4); + else + memset(target, 0, 4); + + target += 4; + } + } + + glfwSetWindowIcon(window, 1, &img); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + case GLFW_KEY_SPACE: + cur_icon_color = (cur_icon_color + 1) % 5; + set_icon(window, cur_icon_color); + break; + case GLFW_KEY_X: + glfwSetWindowIcon(window, 0, NULL); + break; + } +} + +int main(int argc, char** argv) +{ + GLFWwindow* window; + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + window = glfwCreateWindow(200, 200, "Window Icon", NULL, NULL); + if (!window) + { + glfwTerminate(); + + fprintf(stderr, "Failed to open GLFW window\n"); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + + glfwSetKeyCallback(window, key_callback); + set_icon(window, cur_icon_color); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwDestroyWindow(window); + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/iconify.c b/extern/glfw-3.2.1/tests/iconify.c new file mode 100644 index 0000000..b7c7423 --- /dev/null +++ b/extern/glfw-3.2.1/tests/iconify.c @@ -0,0 +1,298 @@ +//======================================================================== +// Iconify/restore test program +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This program is used to test the iconify/restore functionality for +// both full screen and windowed mode windows +// +//======================================================================== + +#include +#include + +#include +#include + +#include "getopt.h" + +static int windowed_xpos, windowed_ypos, windowed_width, windowed_height; + +static void usage(void) +{ + printf("Usage: iconify [-h] [-f [-a] [-n]]\n"); + printf("Options:\n"); + printf(" -a create windows for all monitors\n"); + printf(" -f create full screen window(s)\n"); + printf(" -h show this help\n"); + printf(" -n no automatic iconification of full screen windows\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + printf("%0.2f Key %s\n", + glfwGetTime(), + action == GLFW_PRESS ? "pressed" : "released"); + + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_I: + glfwIconifyWindow(window); + break; + case GLFW_KEY_M: + glfwMaximizeWindow(window); + break; + case GLFW_KEY_R: + glfwRestoreWindow(window); + break; + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + case GLFW_KEY_F11: + case GLFW_KEY_ENTER: + { + if (mods != GLFW_MOD_ALT) + return; + + if (glfwGetWindowMonitor(window)) + { + glfwSetWindowMonitor(window, NULL, + windowed_xpos, windowed_ypos, + windowed_width, windowed_height, + 0); + } + else + { + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos); + glfwGetWindowSize(window, &windowed_width, &windowed_height); + glfwSetWindowMonitor(window, monitor, + 0, 0, mode->width, mode->height, + mode->refreshRate); + } + } + + break; + } + } +} + +static void window_size_callback(GLFWwindow* window, int width, int height) +{ + printf("%0.2f Window resized to %ix%i\n", glfwGetTime(), width, height); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + printf("%0.2f Framebuffer resized to %ix%i\n", glfwGetTime(), width, height); + + glViewport(0, 0, width, height); +} + +static void window_focus_callback(GLFWwindow* window, int focused) +{ + printf("%0.2f Window %s\n", + glfwGetTime(), + focused ? "focused" : "defocused"); +} + +static void window_iconify_callback(GLFWwindow* window, int iconified) +{ + printf("%0.2f Window %s\n", + glfwGetTime(), + iconified ? "iconified" : "restored"); +} + +static void window_refresh_callback(GLFWwindow* window) +{ + int width, height; + + printf("%0.2f Window refresh\n", glfwGetTime()); + + glfwGetFramebufferSize(window, &width, &height); + + glfwMakeContextCurrent(window); + + glEnable(GL_SCISSOR_TEST); + + glScissor(0, 0, width, height); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glScissor(0, 0, 640, 480); + glClearColor(1, 1, 1, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glfwSwapBuffers(window); +} + +static GLFWwindow* create_window(GLFWmonitor* monitor) +{ + int width, height; + GLFWwindow* window; + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + window = glfwCreateWindow(width, height, "Iconify", monitor, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + + return window; +} + +int main(int argc, char** argv) +{ + int ch, i, window_count; + int auto_iconify = GLFW_TRUE, fullscreen = GLFW_FALSE, all_monitors = GLFW_FALSE; + GLFWwindow** windows; + + while ((ch = getopt(argc, argv, "afhn")) != -1) + { + switch (ch) + { + case 'a': + all_monitors = GLFW_TRUE; + break; + + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + fullscreen = GLFW_TRUE; + break; + + case 'n': + auto_iconify = GLFW_FALSE; + break; + + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_AUTO_ICONIFY, auto_iconify); + + if (fullscreen && all_monitors) + { + int monitor_count; + GLFWmonitor** monitors = glfwGetMonitors(&monitor_count); + + window_count = monitor_count; + windows = calloc(window_count, sizeof(GLFWwindow*)); + + for (i = 0; i < monitor_count; i++) + { + windows[i] = create_window(monitors[i]); + if (!windows[i]) + break; + } + } + else + { + GLFWmonitor* monitor = NULL; + + if (fullscreen) + monitor = glfwGetPrimaryMonitor(); + + window_count = 1; + windows = calloc(window_count, sizeof(GLFWwindow*)); + windows[0] = create_window(monitor); + } + + for (i = 0; i < window_count; i++) + { + glfwSetKeyCallback(windows[i], key_callback); + glfwSetFramebufferSizeCallback(windows[i], framebuffer_size_callback); + glfwSetWindowSizeCallback(windows[i], window_size_callback); + glfwSetWindowFocusCallback(windows[i], window_focus_callback); + glfwSetWindowIconifyCallback(windows[i], window_iconify_callback); + glfwSetWindowRefreshCallback(windows[i], window_refresh_callback); + + window_refresh_callback(windows[i]); + + printf("Window is %s and %s\n", + glfwGetWindowAttrib(windows[i], GLFW_ICONIFIED) ? "iconified" : "restored", + glfwGetWindowAttrib(windows[i], GLFW_FOCUSED) ? "focused" : "defocused"); + } + + for (;;) + { + glfwWaitEvents(); + + for (i = 0; i < window_count; i++) + { + if (glfwWindowShouldClose(windows[i])) + break; + } + + if (i < window_count) + break; + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/joysticks.c b/extern/glfw-3.2.1/tests/joysticks.c new file mode 100644 index 0000000..fa9800e --- /dev/null +++ b/extern/glfw-3.2.1/tests/joysticks.c @@ -0,0 +1,216 @@ +//======================================================================== +// Joystick input test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test displays the state of every button and axis of every connected +// joystick and/or gamepad +// +//======================================================================== + +#include +#include + +#include +#include +#include + +#ifdef _MSC_VER +#define strdup(x) _strdup(x) +#endif + +static int joysticks[GLFW_JOYSTICK_LAST + 1]; +static int joystick_count = 0; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void draw_joystick(int index, int x, int y, int width, int height) +{ + int i; + int axis_count, button_count; + const float* axes; + const unsigned char* buttons; + const int axis_height = 3 * height / 4; + const int button_height = height / 4; + + axes = glfwGetJoystickAxes(joysticks[index], &axis_count); + if (axis_count) + { + const int axis_width = width / axis_count; + + for (i = 0; i < axis_count; i++) + { + float value = axes[i] / 2.f + 0.5f; + + glColor3f(0.3f, 0.3f, 0.3f); + glRecti(x + i * axis_width, + y, + x + (i + 1) * axis_width, + y + axis_height); + + glColor3f(1.f, 1.f, 1.f); + glRecti(x + i * axis_width, + y + (int) (value * (axis_height - 5)), + x + (i + 1) * axis_width, + y + 5 + (int) (value * (axis_height - 5))); + } + } + + buttons = glfwGetJoystickButtons(joysticks[index], &button_count); + if (button_count) + { + const int button_width = width / button_count; + + for (i = 0; i < button_count; i++) + { + if (buttons[i]) + glColor3f(1.f, 1.f, 1.f); + else + glColor3f(0.3f, 0.3f, 0.3f); + + glRecti(x + i * button_width, + y + axis_height, + x + (i + 1) * button_width, + y + axis_height + button_height); + } + } +} + +static void draw_joysticks(GLFWwindow* window) +{ + int i, width, height, offset = 0; + + glfwGetFramebufferSize(window, &width, &height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.f, width, height, 0.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + for (i = 0; i < joystick_count; i++) + { + draw_joystick(i, + 0, offset * height / joystick_count, + width, height / joystick_count); + offset++; + } +} + +static void joystick_callback(int joy, int event) +{ + if (event == GLFW_CONNECTED) + { + int axis_count, button_count; + + glfwGetJoystickAxes(joy, &axis_count); + glfwGetJoystickButtons(joy, &button_count); + + printf("Found joystick %i named \'%s\' with %i axes, %i buttons\n", + joy + 1, + glfwGetJoystickName(joy), + axis_count, + button_count); + + joysticks[joystick_count++] = joy; + } + else if (event == GLFW_DISCONNECTED) + { + int i; + + for (i = 0; i < joystick_count; i++) + { + if (joysticks[i] == joy) + break; + } + + for (i = i + 1; i < joystick_count; i++) + joysticks[i - 1] = joysticks[i]; + + printf("Lost joystick %i\n", joy + 1); + joystick_count--; + } +} + +static void find_joysticks(void) +{ + int joy; + + for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) + { + if (glfwJoystickPresent(joy)) + joystick_callback(joy, GLFW_CONNECTED); + } +} + +int main(void) +{ + GLFWwindow* window; + + memset(joysticks, 0, sizeof(joysticks)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + find_joysticks(); + glfwSetJoystickCallback(joystick_callback); + + window = glfwCreateWindow(640, 480, "Joystick Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + draw_joysticks(window); + + glfwSwapBuffers(window); + glfwPollEvents(); + + // Workaround for an issue with msvcrt and mintty + fflush(stdout); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/monitors.c b/extern/glfw-3.2.1/tests/monitors.c new file mode 100644 index 0000000..d1d5810 --- /dev/null +++ b/extern/glfw-3.2.1/tests/monitors.c @@ -0,0 +1,243 @@ +//======================================================================== +// Monitor information tool +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test prints monitor and video mode information or verifies video +// modes +// +//======================================================================== + +#include +#include + +#include +#include +#include + +#include "getopt.h" + +enum Mode +{ + LIST_MODE, + TEST_MODE +}; + +static void usage(void) +{ + printf("Usage: monitors [-t]\n"); + printf(" monitors -h\n"); +} + +static const char* format_mode(const GLFWvidmode* mode) +{ + static char buffer[512]; + + sprintf(buffer, + "%i x %i x %i (%i %i %i) %i Hz", + mode->width, mode->height, + mode->redBits + mode->greenBits + mode->blueBits, + mode->redBits, mode->greenBits, mode->blueBits, + mode->refreshRate); + + buffer[sizeof(buffer) - 1] = '\0'; + return buffer; +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + printf("Framebuffer resized to %ix%i\n", width, height); + + glViewport(0, 0, width, height); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +static void list_modes(GLFWmonitor* monitor) +{ + int count, x, y, widthMM, heightMM, i; + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); + + glfwGetMonitorPos(monitor, &x, &y); + glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); + + printf("Name: %s (%s)\n", + glfwGetMonitorName(monitor), + glfwGetPrimaryMonitor() == monitor ? "primary" : "secondary"); + printf("Current mode: %s\n", format_mode(mode)); + printf("Virtual position: %i %i\n", x, y); + + printf("Physical size: %i x %i mm (%0.2f dpi)\n", + widthMM, heightMM, mode->width * 25.4f / widthMM); + + printf("Modes:\n"); + + for (i = 0; i < count; i++) + { + printf("%3u: %s", (unsigned int) i, format_mode(modes + i)); + + if (memcmp(mode, modes + i, sizeof(GLFWvidmode)) == 0) + printf(" (current mode)"); + + putchar('\n'); + } +} + +static void test_modes(GLFWmonitor* monitor) +{ + int i, count; + GLFWwindow* window; + const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); + + for (i = 0; i < count; i++) + { + const GLFWvidmode* mode = modes + i; + GLFWvidmode current; + + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + + printf("Testing mode %u on monitor %s: %s\n", + (unsigned int) i, + glfwGetMonitorName(monitor), + format_mode(mode)); + + window = glfwCreateWindow(mode->width, mode->height, + "Video Mode Test", + glfwGetPrimaryMonitor(), + NULL); + if (!window) + { + printf("Failed to enter mode %u: %s\n", + (unsigned int) i, + format_mode(mode)); + continue; + } + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwSetTime(0.0); + + while (glfwGetTime() < 5.0) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + glfwPollEvents(); + + if (glfwWindowShouldClose(window)) + { + printf("User terminated program\n"); + + glfwTerminate(); + exit(EXIT_SUCCESS); + } + } + + glGetIntegerv(GL_RED_BITS, ¤t.redBits); + glGetIntegerv(GL_GREEN_BITS, ¤t.greenBits); + glGetIntegerv(GL_BLUE_BITS, ¤t.blueBits); + + glfwGetWindowSize(window, ¤t.width, ¤t.height); + + if (current.redBits != mode->redBits || + current.greenBits != mode->greenBits || + current.blueBits != mode->blueBits) + { + printf("*** Color bit mismatch: (%i %i %i) instead of (%i %i %i)\n", + current.redBits, current.greenBits, current.blueBits, + mode->redBits, mode->greenBits, mode->blueBits); + } + + if (current.width != mode->width || current.height != mode->height) + { + printf("*** Size mismatch: %ix%i instead of %ix%i\n", + current.width, current.height, + mode->width, mode->height); + } + + printf("Closing window\n"); + + glfwDestroyWindow(window); + window = NULL; + + glfwPollEvents(); + } +} + +int main(int argc, char** argv) +{ + int ch, i, count, mode = LIST_MODE; + GLFWmonitor** monitors; + + while ((ch = getopt(argc, argv, "th")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 't': + mode = TEST_MODE; + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + monitors = glfwGetMonitors(&count); + + for (i = 0; i < count; i++) + { + if (mode == LIST_MODE) + list_modes(monitors[i]); + else if (mode == TEST_MODE) + test_modes(monitors[i]); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/msaa.c b/extern/glfw-3.2.1/tests/msaa.c new file mode 100644 index 0000000..d6e7df3 --- /dev/null +++ b/extern/glfw-3.2.1/tests/msaa.c @@ -0,0 +1,163 @@ +//======================================================================== +// Multisample anti-aliasing test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test renders two high contrast, slowly rotating quads, one aliased +// and one (hopefully) anti-aliased, thus allowing for visual verification +// of whether MSAA is indeed enabled +// +//======================================================================== + +#include +#include + +#include +#include + +#include "getopt.h" + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_SPACE: + glfwSetTime(0.0); + break; + } +} + +static void usage(void) +{ + printf("Usage: msaa [-h] [-s SAMPLES]\n"); +} + +int main(int argc, char** argv) +{ + int ch, samples = 4; + GLFWwindow* window; + + while ((ch = getopt(argc, argv, "hs:")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 's': + samples = atoi(optarg); + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + if (samples) + printf("Requesting MSAA with %i samples\n", samples); + else + printf("Requesting that MSAA not be available\n"); + + glfwWindowHint(GLFW_SAMPLES, samples); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + window = glfwCreateWindow(800, 400, "Aliasing Detector", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(window, key_callback); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + if (!GLAD_GL_ARB_multisample && !GLAD_GL_VERSION_1_3) + { + printf("Multisampling is not supported\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwShowWindow(window); + + glGetIntegerv(GL_SAMPLES, &samples); + if (samples) + printf("Context reports MSAA is available with %i samples\n", samples); + else + printf("Context reports MSAA is unavailable\n"); + + glMatrixMode(GL_PROJECTION); + glOrtho(0.f, 1.f, 0.f, 0.5f, 0.f, 1.f); + glMatrixMode(GL_MODELVIEW); + + while (!glfwWindowShouldClose(window)) + { + GLfloat time = (GLfloat) glfwGetTime(); + + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glTranslatef(0.25f, 0.25f, 0.f); + glRotatef(time, 0.f, 0.f, 1.f); + + glDisable(GL_MULTISAMPLE_ARB); + glRectf(-0.15f, -0.15f, 0.15f, 0.15f); + + glLoadIdentity(); + glTranslatef(0.75f, 0.25f, 0.f); + glRotatef(time, 0.f, 0.f, 1.f); + + glEnable(GL_MULTISAMPLE_ARB); + glRectf(-0.15f, -0.15f, 0.15f, 0.15f); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/reopen.c b/extern/glfw-3.2.1/tests/reopen.c new file mode 100644 index 0000000..caaf362 --- /dev/null +++ b/extern/glfw-3.2.1/tests/reopen.c @@ -0,0 +1,192 @@ +//======================================================================== +// Window re-opener (open/close stress test) +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test came about as the result of bug #1262773 +// +// It closes and re-opens the GLFW window every five seconds, alternating +// between windowed and full screen mode +// +// It also times and logs opening and closing actions and attempts to separate +// user initiated window closing from its own +// +//======================================================================== + +#include +#include + +#include +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void window_close_callback(GLFWwindow* window) +{ + printf("Close callback triggered\n"); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_Q: + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } +} + +static GLFWwindow* open_window(int width, int height, GLFWmonitor* monitor) +{ + double base; + GLFWwindow* window; + + base = glfwGetTime(); + + window = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL); + if (!window) + return NULL; + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetWindowCloseCallback(window, window_close_callback); + glfwSetKeyCallback(window, key_callback); + + if (monitor) + { + printf("Opening full screen window on monitor %s took %0.3f seconds\n", + glfwGetMonitorName(monitor), + glfwGetTime() - base); + } + else + { + printf("Opening regular window took %0.3f seconds\n", + glfwGetTime() - base); + } + + return window; +} + +static void close_window(GLFWwindow* window) +{ + double base = glfwGetTime(); + glfwDestroyWindow(window); + printf("Closing window took %0.3f seconds\n", glfwGetTime() - base); +} + +int main(int argc, char** argv) +{ + int count = 0; + GLFWwindow* window; + + srand((unsigned int) time(NULL)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + for (;;) + { + int width, height; + GLFWmonitor* monitor = NULL; + + if (count % 2 == 0) + { + int monitorCount; + GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); + monitor = monitors[rand() % monitorCount]; + } + + if (monitor) + { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + window = open_window(width, height, monitor); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + glfwSetTime(0.0); + + while (glfwGetTime() < 5.0) + { + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glRotatef((GLfloat) glfwGetTime() * 100.f, 0.f, 0.f, 1.f); + glRectf(-0.5f, -0.5f, 1.f, 1.f); + glPopMatrix(); + + glfwSwapBuffers(window); + glfwPollEvents(); + + if (glfwWindowShouldClose(window)) + { + close_window(window); + printf("User closed window\n"); + + glfwTerminate(); + exit(EXIT_SUCCESS); + } + } + + printf("Closing window\n"); + close_window(window); + + count++; + } + + glfwTerminate(); +} + diff --git a/extern/glfw-3.2.1/tests/sharing.c b/extern/glfw-3.2.1/tests/sharing.c new file mode 100644 index 0000000..a7f1a31 --- /dev/null +++ b/extern/glfw-3.2.1/tests/sharing.c @@ -0,0 +1,186 @@ +//======================================================================== +// Context sharing test program +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This program is used to test sharing of objects between contexts +// +//======================================================================== + +#include +#include + +#include +#include + +#define WIDTH 400 +#define HEIGHT 400 +#define OFFSET 50 + +static GLFWwindow* windows[2]; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +static GLFWwindow* open_window(const char* title, GLFWwindow* share, int posX, int posY) +{ + GLFWwindow* window; + + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + window = glfwCreateWindow(WIDTH, HEIGHT, title, NULL, share); + if (!window) + return NULL; + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + glfwSetWindowPos(window, posX, posY); + glfwShowWindow(window); + + glfwSetKeyCallback(window, key_callback); + + return window; +} + +static GLuint create_texture(void) +{ + int x, y; + char pixels[256 * 256]; + GLuint texture; + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + for (y = 0; y < 256; y++) + { + for (x = 0; x < 256; x++) + pixels[y * 256 + x] = rand() % 256; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + return texture; +} + +static void draw_quad(GLuint texture) +{ + int width, height; + glfwGetFramebufferSize(glfwGetCurrentContext(), &width, &height); + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.f, 1.f, 0.f, 1.f, 0.f, 1.f); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glBegin(GL_QUADS); + + glTexCoord2f(0.f, 0.f); + glVertex2f(0.f, 0.f); + + glTexCoord2f(1.f, 0.f); + glVertex2f(1.f, 0.f); + + glTexCoord2f(1.f, 1.f); + glVertex2f(1.f, 1.f); + + glTexCoord2f(0.f, 1.f); + glVertex2f(0.f, 1.f); + + glEnd(); +} + +int main(int argc, char** argv) +{ + int x, y, width; + GLuint texture; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + windows[0] = open_window("First", NULL, OFFSET, OFFSET); + if (!windows[0]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + // This is the one and only time we create a texture + // It is created inside the first context, created above + // It will then be shared with the second context, created below + texture = create_texture(); + + glfwGetWindowPos(windows[0], &x, &y); + glfwGetWindowSize(windows[0], &width, NULL); + + // Put the second window to the right of the first one + windows[1] = open_window("Second", windows[0], x + width + OFFSET, y); + if (!windows[1]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + // Set drawing color for both contexts + glfwMakeContextCurrent(windows[0]); + glColor3f(0.6f, 0.f, 0.6f); + glfwMakeContextCurrent(windows[1]); + glColor3f(0.6f, 0.6f, 0.f); + + glfwMakeContextCurrent(windows[0]); + + while (!glfwWindowShouldClose(windows[0]) && + !glfwWindowShouldClose(windows[1])) + { + glfwMakeContextCurrent(windows[0]); + draw_quad(texture); + + glfwMakeContextCurrent(windows[1]); + draw_quad(texture); + + glfwSwapBuffers(windows[0]); + glfwSwapBuffers(windows[1]); + + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/tearing.c b/extern/glfw-3.2.1/tests/tearing.c new file mode 100644 index 0000000..5cd48b3 --- /dev/null +++ b/extern/glfw-3.2.1/tests/tearing.c @@ -0,0 +1,214 @@ +//======================================================================== +// Vsync enabling test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test renders a high contrast, horizontally moving bar, allowing for +// visual verification of whether the set swap interval is indeed obeyed +// +//======================================================================== + +#include +#include + +#include +#include +#include + +#include "getopt.h" + +static int swap_tear; +static int swap_interval; +static double frame_rate; + +static void usage(void) +{ + printf("Usage: tearing [-h] [-f]\n"); + printf("Options:\n"); + printf(" -f create full screen window\n"); + printf(" -h show this help\n"); +} + +static void update_window_title(GLFWwindow* window) +{ + char title[256]; + + sprintf(title, "Tearing detector (interval %i%s, %0.1f Hz)", + swap_interval, + (swap_tear && swap_interval < 0) ? " (swap tear)" : "", + frame_rate); + + glfwSetWindowTitle(window, title); +} + +static void set_swap_interval(GLFWwindow* window, int interval) +{ + swap_interval = interval; + glfwSwapInterval(swap_interval); + update_window_title(window); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_UP: + { + if (swap_interval + 1 > swap_interval) + set_swap_interval(window, swap_interval + 1); + break; + } + + case GLFW_KEY_DOWN: + { + if (swap_tear) + { + if (swap_interval - 1 < swap_interval) + set_swap_interval(window, swap_interval - 1); + } + else + { + if (swap_interval - 1 >= 0) + set_swap_interval(window, swap_interval - 1); + } + break; + } + + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, 1); + break; + } +} + +int main(int argc, char** argv) +{ + int ch, width, height; + float position; + unsigned long frame_count = 0; + double last_time, current_time; + int fullscreen = GLFW_FALSE; + GLFWmonitor* monitor = NULL; + GLFWwindow* window; + + while ((ch = getopt(argc, argv, "fh")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + + case 'f': + fullscreen = GLFW_TRUE; + break; + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + if (fullscreen) + { + const GLFWvidmode* mode; + + monitor = glfwGetPrimaryMonitor(); + mode = glfwGetVideoMode(monitor); + + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + + width = mode->width; + height = mode->height; + } + else + { + width = 640; + height = 480; + } + + window = glfwCreateWindow(width, height, "", monitor, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + set_swap_interval(window, 0); + + last_time = glfwGetTime(); + frame_rate = 0.0; + swap_tear = (glfwExtensionSupported("WGL_EXT_swap_control_tear") || + glfwExtensionSupported("GLX_EXT_swap_control_tear")); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + glfwSetKeyCallback(window, key_callback); + + glMatrixMode(GL_PROJECTION); + glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); + glMatrixMode(GL_MODELVIEW); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + position = cosf((float) glfwGetTime() * 4.f) * 0.75f; + glRectf(position - 0.25f, -1.f, position + 0.25f, 1.f); + + glfwSwapBuffers(window); + glfwPollEvents(); + + frame_count++; + + current_time = glfwGetTime(); + if (current_time - last_time > 1.0) + { + frame_rate = frame_count / (current_time - last_time); + frame_count = 0; + last_time = current_time; + update_window_title(window); + } + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/threads.c b/extern/glfw-3.2.1/tests/threads.c new file mode 100644 index 0000000..699a0ad --- /dev/null +++ b/extern/glfw-3.2.1/tests/threads.c @@ -0,0 +1,143 @@ +//======================================================================== +// Multi-threading test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test is intended to verify whether the OpenGL context part of +// the GLFW API is able to be used from multiple threads +// +//======================================================================== + +#include "tinycthread.h" + +#include +#include + +#include +#include +#include + +typedef struct +{ + GLFWwindow* window; + const char* title; + float r, g, b; + thrd_t id; +} Thread; + +static volatile int running = GLFW_TRUE; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static int thread_main(void* data) +{ + const Thread* thread = data; + + glfwMakeContextCurrent(thread->window); + glfwSwapInterval(1); + + while (running) + { + const float v = (float) fabs(sin(glfwGetTime() * 2.f)); + glClearColor(thread->r * v, thread->g * v, thread->b * v, 0.f); + + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(thread->window); + } + + glfwMakeContextCurrent(NULL); + return 0; +} + +int main(void) +{ + int i, result; + Thread threads[] = + { + { NULL, "Red", 1.f, 0.f, 0.f, 0 }, + { NULL, "Green", 0.f, 1.f, 0.f, 0 }, + { NULL, "Blue", 0.f, 0.f, 1.f, 0 } + }; + const int count = sizeof(threads) / sizeof(Thread); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + for (i = 0; i < count; i++) + { + threads[i].window = glfwCreateWindow(200, 200, + threads[i].title, + NULL, NULL); + if (!threads[i].window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200); + glfwShowWindow(threads[i].window); + } + + glfwMakeContextCurrent(threads[0].window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwMakeContextCurrent(NULL); + + for (i = 0; i < count; i++) + { + if (thrd_create(&threads[i].id, thread_main, threads + i) != + thrd_success) + { + fprintf(stderr, "Failed to create secondary thread\n"); + + glfwTerminate(); + exit(EXIT_FAILURE); + } + } + + while (running) + { + glfwWaitEvents(); + + for (i = 0; i < count; i++) + { + if (glfwWindowShouldClose(threads[i].window)) + running = GLFW_FALSE; + } + } + + for (i = 0; i < count; i++) + glfwHideWindow(threads[i].window); + + for (i = 0; i < count; i++) + thrd_join(threads[i].id, &result); + + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/timeout.c b/extern/glfw-3.2.1/tests/timeout.c new file mode 100644 index 0000000..4bf0551 --- /dev/null +++ b/extern/glfw-3.2.1/tests/timeout.c @@ -0,0 +1,97 @@ +//======================================================================== +// Event wait timeout test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test is intended to verify that waiting for events with timeout works +// +//======================================================================== + +#include +#include + +#include +#include +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +static float nrand(void) +{ + return (float) rand() / (float) RAND_MAX; +} + +int main(void) +{ + GLFWwindow* window; + + srand((unsigned int) time(NULL)); + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(640, 480, "Event Wait Timeout Test", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSetKeyCallback(window, key_callback); + + while (!glfwWindowShouldClose(window)) + { + int width, height; + float r = nrand(), g = nrand(), b = nrand(); + float l = (float) sqrt(r * r + g * g + b * b); + + glfwGetFramebufferSize(window, &width, &height); + + glViewport(0, 0, width, height); + glClearColor(r / l, g / l, b / l, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + + glfwWaitEventsTimeout(1.0); + } + + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/title.c b/extern/glfw-3.2.1/tests/title.c new file mode 100644 index 0000000..9fe67f4 --- /dev/null +++ b/extern/glfw-3.2.1/tests/title.c @@ -0,0 +1,78 @@ +//======================================================================== +// UTF-8 window title test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test sets a UTF-8 window title +// +//======================================================================== + +#include +#include + +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(void) +{ + GLFWwindow* window; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + window = glfwCreateWindow(400, 400, "English 日本語 русский язык 官話", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + while (!glfwWindowShouldClose(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(window); + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/extern/glfw-3.2.1/tests/vulkan.c b/extern/glfw-3.2.1/tests/vulkan.c new file mode 100644 index 0000000..1b62d68 --- /dev/null +++ b/extern/glfw-3.2.1/tests/vulkan.c @@ -0,0 +1,2245 @@ +/* + * Copyright (c) 2015-2016 The Khronos Group Inc. + * Copyright (c) 2015-2016 Valve Corporation + * Copyright (c) 2015-2016 LunarG, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and/or associated documentation files (the "Materials"), to + * deal in the Materials without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Materials, and to permit persons to whom the Materials are + * furnished to do so, subject to the following conditions: + * + * The above copyright notice(s) and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE + * USE OR OTHER DEALINGS IN THE MATERIALS. + * + * Author: Chia-I Wu + * Author: Cody Northrop + * Author: Courtney Goeltzenleuchter + * Author: Ian Elliott + * Author: Jon Ashburn + * Author: Piers Daniell + */ +/* + * Draw a textured triangle with depth testing. This is written against Intel + * ICD. It does not do state transition nor object memory binding like it + * should. It also does no error checking. + */ + +#ifndef _MSC_VER +#define _ISOC11_SOURCE /* for aligned_alloc() */ +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#define DEMO_TEXTURE_COUNT 1 +#define VERTEX_BUFFER_BIND_ID 0 +#define APP_SHORT_NAME "vulkan" +#define APP_LONG_NAME "The Vulkan Triangle Demo Program" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#if defined(NDEBUG) && defined(__GNUC__) +#define U_ASSERT_ONLY __attribute__((unused)) +#else +#define U_ASSERT_ONLY +#endif + +#define ERR_EXIT(err_msg, err_class) \ + do { \ + printf(err_msg); \ + fflush(stdout); \ + exit(1); \ + } while (0) + +#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ + { \ + demo->fp##entrypoint = \ + (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \ + if (demo->fp##entrypoint == NULL) { \ + ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint, \ + "vkGetInstanceProcAddr Failure"); \ + } \ + } + +#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ + { \ + demo->fp##entrypoint = \ + (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint); \ + if (demo->fp##entrypoint == NULL) { \ + ERR_EXIT("vkGetDeviceProcAddr failed to find vk" #entrypoint, \ + "vkGetDeviceProcAddr Failure"); \ + } \ + } + +static const char fragShaderCode[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, + 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, + 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, + 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, + 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, + 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x75, 0x46, 0x72, 0x61, + 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00 +}; + +static const char vertShaderCode[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, + 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, + 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, + 0x04, 0x00, 0x09, 0x00, 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, + 0x68, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x61, 0x74, 0x74, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43, + 0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x70, 0x6f, 0x73, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x56, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x49, 0x44, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x44, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0x38, 0x00, 0x01, 0x00 +}; + +struct texture_object { + VkSampler sampler; + + VkImage image; + VkImageLayout imageLayout; + + VkDeviceMemory mem; + VkImageView view; + int32_t tex_width, tex_height; +}; + +VKAPI_ATTR VkBool32 VKAPI_CALL +dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, + uint64_t srcObject, size_t location, int32_t msgCode, + const char *pLayerPrefix, const char *pMsg, void *pUserData) { + char *message = (char *)malloc(strlen(pMsg) + 100); + + assert(message); + + if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, + pMsg); + } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, + pMsg); + } else { + return false; + } + + printf("%s\n", message); + fflush(stdout); + free(message); + + /* + * false indicates that layer should not bail-out of an + * API call that had validation failures. This may mean that the + * app dies inside the driver due to invalid parameter(s). + * That's what would happen without validation layers, so we'll + * keep that behavior here. + */ + return false; +} + +typedef struct _SwapchainBuffers { + VkImage image; + VkCommandBuffer cmd; + VkImageView view; +} SwapchainBuffers; + +struct demo { + GLFWwindow* window; + VkSurfaceKHR surface; + bool use_staging_buffer; + + VkAllocationCallbacks allocator; + + VkInstance inst; + VkPhysicalDevice gpu; + VkDevice device; + VkQueue queue; + VkPhysicalDeviceProperties gpu_props; + VkQueueFamilyProperties *queue_props; + uint32_t graphics_queue_node_index; + + uint32_t enabled_extension_count; + uint32_t enabled_layer_count; + const char *extension_names[64]; + char *device_validation_layers[64]; + + int width, height; + VkFormat format; + VkColorSpaceKHR color_space; + + PFN_vkGetPhysicalDeviceSurfaceSupportKHR + fpGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR + fpGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR + fpGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR + fpGetPhysicalDeviceSurfacePresentModesKHR; + PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR; + PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR; + PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR; + PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR; + PFN_vkQueuePresentKHR fpQueuePresentKHR; + uint32_t swapchainImageCount; + VkSwapchainKHR swapchain; + SwapchainBuffers *buffers; + + VkCommandPool cmd_pool; + + struct { + VkFormat format; + + VkImage image; + VkDeviceMemory mem; + VkImageView view; + } depth; + + struct texture_object textures[DEMO_TEXTURE_COUNT]; + + struct { + VkBuffer buf; + VkDeviceMemory mem; + + VkPipelineVertexInputStateCreateInfo vi; + VkVertexInputBindingDescription vi_bindings[1]; + VkVertexInputAttributeDescription vi_attrs[2]; + } vertices; + + VkCommandBuffer setup_cmd; // Command Buffer for initialization commands + VkCommandBuffer draw_cmd; // Command Buffer for drawing commands + VkPipelineLayout pipeline_layout; + VkDescriptorSetLayout desc_layout; + VkPipelineCache pipelineCache; + VkRenderPass render_pass; + VkPipeline pipeline; + + VkShaderModule vert_shader_module; + VkShaderModule frag_shader_module; + + VkDescriptorPool desc_pool; + VkDescriptorSet desc_set; + + VkFramebuffer *framebuffers; + + VkPhysicalDeviceMemoryProperties memory_properties; + + bool validate; + PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback; + PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback; + VkDebugReportCallbackEXT msg_callback; + + float depthStencil; + float depthIncrement; + + uint32_t current_buffer; + uint32_t queue_count; +}; + +// Forward declaration: +static void demo_resize(struct demo *demo); + +static bool memory_type_from_properties(struct demo *demo, uint32_t typeBits, + VkFlags requirements_mask, + uint32_t *typeIndex) { + uint32_t i; + + // Search memtypes to find first index with those properties + for (i = 0; i < 32; i++) { + if ((typeBits & 1) == 1) { + // Type is available, does it match user properties? + if ((demo->memory_properties.memoryTypes[i].propertyFlags & + requirements_mask) == requirements_mask) { + *typeIndex = i; + return true; + } + } + typeBits >>= 1; + } + // No memory types matched, return failure + return false; +} + +static void demo_flush_init_cmd(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + + if (demo->setup_cmd == VK_NULL_HANDLE) + return; + + err = vkEndCommandBuffer(demo->setup_cmd); + assert(!err); + + const VkCommandBuffer cmd_bufs[] = {demo->setup_cmd}; + VkFence nullFence = {VK_NULL_HANDLE}; + VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = NULL, + .waitSemaphoreCount = 0, + .pWaitSemaphores = NULL, + .pWaitDstStageMask = NULL, + .commandBufferCount = 1, + .pCommandBuffers = cmd_bufs, + .signalSemaphoreCount = 0, + .pSignalSemaphores = NULL}; + + err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence); + assert(!err); + + err = vkQueueWaitIdle(demo->queue); + assert(!err); + + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, cmd_bufs); + demo->setup_cmd = VK_NULL_HANDLE; +} + +static void demo_set_image_layout(struct demo *demo, VkImage image, + VkImageAspectFlags aspectMask, + VkImageLayout old_image_layout, + VkImageLayout new_image_layout) { + VkResult U_ASSERT_ONLY err; + + if (demo->setup_cmd == VK_NULL_HANDLE) { + const VkCommandBufferAllocateInfo cmd = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = NULL, + .commandPool = demo->cmd_pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + + err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->setup_cmd); + assert(!err); + + VkCommandBufferInheritanceInfo cmd_buf_hinfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + .pNext = NULL, + .renderPass = VK_NULL_HANDLE, + .subpass = 0, + .framebuffer = VK_NULL_HANDLE, + .occlusionQueryEnable = VK_FALSE, + .queryFlags = 0, + .pipelineStatistics = 0, + }; + VkCommandBufferBeginInfo cmd_buf_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = 0, + .pInheritanceInfo = &cmd_buf_hinfo, + }; + err = vkBeginCommandBuffer(demo->setup_cmd, &cmd_buf_info); + assert(!err); + } + + VkImageMemoryBarrier image_memory_barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = 0, + .dstAccessMask = 0, + .oldLayout = old_image_layout, + .newLayout = new_image_layout, + .image = image, + .subresourceRange = {aspectMask, 0, 1, 0, 1}}; + + if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + /* Make sure anything that was copying from this image has completed */ + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { + image_memory_barrier.dstAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { + image_memory_barrier.dstAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + + if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + /* Make sure any Copy or CPU writes to image are flushed */ + image_memory_barrier.dstAccessMask = + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + } + + VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier; + + VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + vkCmdPipelineBarrier(demo->setup_cmd, src_stages, dest_stages, 0, 0, NULL, + 0, NULL, 1, pmemory_barrier); +} + +static void demo_draw_build_cmd(struct demo *demo) { + const VkCommandBufferInheritanceInfo cmd_buf_hinfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + .pNext = NULL, + .renderPass = VK_NULL_HANDLE, + .subpass = 0, + .framebuffer = VK_NULL_HANDLE, + .occlusionQueryEnable = VK_FALSE, + .queryFlags = 0, + .pipelineStatistics = 0, + }; + const VkCommandBufferBeginInfo cmd_buf_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = 0, + .pInheritanceInfo = &cmd_buf_hinfo, + }; + const VkClearValue clear_values[2] = { + [0] = {.color.float32 = {0.2f, 0.2f, 0.2f, 0.2f}}, + [1] = {.depthStencil = {demo->depthStencil, 0}}, + }; + const VkRenderPassBeginInfo rp_begin = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = NULL, + .renderPass = demo->render_pass, + .framebuffer = demo->framebuffers[demo->current_buffer], + .renderArea.offset.x = 0, + .renderArea.offset.y = 0, + .renderArea.extent.width = demo->width, + .renderArea.extent.height = demo->height, + .clearValueCount = 2, + .pClearValues = clear_values, + }; + VkResult U_ASSERT_ONLY err; + + err = vkBeginCommandBuffer(demo->draw_cmd, &cmd_buf_info); + assert(!err); + + vkCmdBeginRenderPass(demo->draw_cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); + vkCmdBindPipeline(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + demo->pipeline); + vkCmdBindDescriptorSets(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + demo->pipeline_layout, 0, 1, &demo->desc_set, 0, + NULL); + + VkViewport viewport; + memset(&viewport, 0, sizeof(viewport)); + viewport.height = (float)demo->height; + viewport.width = (float)demo->width; + viewport.minDepth = (float)0.0f; + viewport.maxDepth = (float)1.0f; + vkCmdSetViewport(demo->draw_cmd, 0, 1, &viewport); + + VkRect2D scissor; + memset(&scissor, 0, sizeof(scissor)); + scissor.extent.width = demo->width; + scissor.extent.height = demo->height; + scissor.offset.x = 0; + scissor.offset.y = 0; + vkCmdSetScissor(demo->draw_cmd, 0, 1, &scissor); + + VkDeviceSize offsets[1] = {0}; + vkCmdBindVertexBuffers(demo->draw_cmd, VERTEX_BUFFER_BIND_ID, 1, + &demo->vertices.buf, offsets); + + vkCmdDraw(demo->draw_cmd, 3, 1, 0, 0); + vkCmdEndRenderPass(demo->draw_cmd); + + VkImageMemoryBarrier prePresentBarrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + prePresentBarrier.image = demo->buffers[demo->current_buffer].image; + VkImageMemoryBarrier *pmemory_barrier = &prePresentBarrier; + vkCmdPipelineBarrier(demo->draw_cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, + NULL, 1, pmemory_barrier); + + err = vkEndCommandBuffer(demo->draw_cmd); + assert(!err); +} + +static void demo_draw(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + VkSemaphore presentCompleteSemaphore; + VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = NULL, + .flags = 0, + }; + + err = vkCreateSemaphore(demo->device, &presentCompleteSemaphoreCreateInfo, + NULL, &presentCompleteSemaphore); + assert(!err); + + // Get the index of the next available swapchain image: + err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX, + presentCompleteSemaphore, + (VkFence)0, // TODO: Show use of fence + &demo->current_buffer); + if (err == VK_ERROR_OUT_OF_DATE_KHR) { + // demo->swapchain is out of date (e.g. the window was resized) and + // must be recreated: + demo_resize(demo); + demo_draw(demo); + vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL); + return; + } else if (err == VK_SUBOPTIMAL_KHR) { + // demo->swapchain is not as optimal as it could be, but the platform's + // presentation engine will still present the image correctly. + } else { + assert(!err); + } + + // Assume the command buffer has been run on current_buffer before so + // we need to set the image layout back to COLOR_ATTACHMENT_OPTIMAL + demo_set_image_layout(demo, demo->buffers[demo->current_buffer].image, + VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + demo_flush_init_cmd(demo); + + // Wait for the present complete semaphore to be signaled to ensure + // that the image won't be rendered to until the presentation + // engine has fully released ownership to the application, and it is + // okay to render to the image. + + // FIXME/TODO: DEAL WITH VK_IMAGE_LAYOUT_PRESENT_SRC_KHR + demo_draw_build_cmd(demo); + VkFence nullFence = VK_NULL_HANDLE; + VkPipelineStageFlags pipe_stage_flags = + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = NULL, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &presentCompleteSemaphore, + .pWaitDstStageMask = &pipe_stage_flags, + .commandBufferCount = 1, + .pCommandBuffers = &demo->draw_cmd, + .signalSemaphoreCount = 0, + .pSignalSemaphores = NULL}; + + err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence); + assert(!err); + + VkPresentInfoKHR present = { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .pNext = NULL, + .swapchainCount = 1, + .pSwapchains = &demo->swapchain, + .pImageIndices = &demo->current_buffer, + }; + + // TBD/TODO: SHOULD THE "present" PARAMETER BE "const" IN THE HEADER? + err = demo->fpQueuePresentKHR(demo->queue, &present); + if (err == VK_ERROR_OUT_OF_DATE_KHR) { + // demo->swapchain is out of date (e.g. the window was resized) and + // must be recreated: + demo_resize(demo); + } else if (err == VK_SUBOPTIMAL_KHR) { + // demo->swapchain is not as optimal as it could be, but the platform's + // presentation engine will still present the image correctly. + } else { + assert(!err); + } + + err = vkQueueWaitIdle(demo->queue); + assert(err == VK_SUCCESS); + + vkDestroySemaphore(demo->device, presentCompleteSemaphore, NULL); +} + +static void demo_prepare_buffers(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + VkSwapchainKHR oldSwapchain = demo->swapchain; + + // Check the surface capabilities and formats + VkSurfaceCapabilitiesKHR surfCapabilities; + err = demo->fpGetPhysicalDeviceSurfaceCapabilitiesKHR( + demo->gpu, demo->surface, &surfCapabilities); + assert(!err); + + uint32_t presentModeCount; + err = demo->fpGetPhysicalDeviceSurfacePresentModesKHR( + demo->gpu, demo->surface, &presentModeCount, NULL); + assert(!err); + VkPresentModeKHR *presentModes = + (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR)); + assert(presentModes); + err = demo->fpGetPhysicalDeviceSurfacePresentModesKHR( + demo->gpu, demo->surface, &presentModeCount, presentModes); + assert(!err); + + VkExtent2D swapchainExtent; + // width and height are either both -1, or both not -1. + if (surfCapabilities.currentExtent.width == (uint32_t)-1) { + // If the surface size is undefined, the size is set to + // the size of the images requested. + swapchainExtent.width = demo->width; + swapchainExtent.height = demo->height; + } else { + // If the surface size is defined, the swap chain size must match + swapchainExtent = surfCapabilities.currentExtent; + demo->width = surfCapabilities.currentExtent.width; + demo->height = surfCapabilities.currentExtent.height; + } + + VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; + + // Determine the number of VkImage's to use in the swap chain (we desire to + // own only 1 image at a time, besides the images being displayed and + // queued for display): + uint32_t desiredNumberOfSwapchainImages = + surfCapabilities.minImageCount + 1; + if ((surfCapabilities.maxImageCount > 0) && + (desiredNumberOfSwapchainImages > surfCapabilities.maxImageCount)) { + // Application must settle for fewer images than desired: + desiredNumberOfSwapchainImages = surfCapabilities.maxImageCount; + } + + VkSurfaceTransformFlagsKHR preTransform; + if (surfCapabilities.supportedTransforms & + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + } else { + preTransform = surfCapabilities.currentTransform; + } + + const VkSwapchainCreateInfoKHR swapchain = { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = NULL, + .surface = demo->surface, + .minImageCount = desiredNumberOfSwapchainImages, + .imageFormat = demo->format, + .imageColorSpace = demo->color_space, + .imageExtent = + { + .width = swapchainExtent.width, .height = swapchainExtent.height, + }, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .preTransform = preTransform, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .imageArrayLayers = 1, + .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = NULL, + .presentMode = swapchainPresentMode, + .oldSwapchain = oldSwapchain, + .clipped = true, + }; + uint32_t i; + + err = demo->fpCreateSwapchainKHR(demo->device, &swapchain, NULL, + &demo->swapchain); + assert(!err); + + // If we just re-created an existing swapchain, we should destroy the old + // swapchain at this point. + // Note: destroying the swapchain also cleans up all its associated + // presentable images once the platform is done with them. + if (oldSwapchain != VK_NULL_HANDLE) { + demo->fpDestroySwapchainKHR(demo->device, oldSwapchain, NULL); + } + + err = demo->fpGetSwapchainImagesKHR(demo->device, demo->swapchain, + &demo->swapchainImageCount, NULL); + assert(!err); + + VkImage *swapchainImages = + (VkImage *)malloc(demo->swapchainImageCount * sizeof(VkImage)); + assert(swapchainImages); + err = demo->fpGetSwapchainImagesKHR(demo->device, demo->swapchain, + &demo->swapchainImageCount, + swapchainImages); + assert(!err); + + demo->buffers = (SwapchainBuffers *)malloc(sizeof(SwapchainBuffers) * + demo->swapchainImageCount); + assert(demo->buffers); + + for (i = 0; i < demo->swapchainImageCount; i++) { + VkImageViewCreateInfo color_attachment_view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .format = demo->format, + .components = + { + .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B, + .a = VK_COMPONENT_SWIZZLE_A, + }, + .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1}, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .flags = 0, + }; + + demo->buffers[i].image = swapchainImages[i]; + + // Render loop will expect image to have been used before and in + // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR + // layout and will change to COLOR_ATTACHMENT_OPTIMAL, so init the image + // to that state + demo_set_image_layout( + demo, demo->buffers[i].image, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + + color_attachment_view.image = demo->buffers[i].image; + + err = vkCreateImageView(demo->device, &color_attachment_view, NULL, + &demo->buffers[i].view); + assert(!err); + } + + demo->current_buffer = 0; + + if (NULL != presentModes) { + free(presentModes); + } +} + +static void demo_prepare_depth(struct demo *demo) { + const VkFormat depth_format = VK_FORMAT_D16_UNORM; + const VkImageCreateInfo image = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = depth_format, + .extent = {demo->width, demo->height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + .flags = 0, + }; + VkMemoryAllocateInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = NULL, + .allocationSize = 0, + .memoryTypeIndex = 0, + }; + VkImageViewCreateInfo view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = VK_NULL_HANDLE, + .format = depth_format, + .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1}, + .flags = 0, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + }; + + VkMemoryRequirements mem_reqs; + VkResult U_ASSERT_ONLY err; + bool U_ASSERT_ONLY pass; + + demo->depth.format = depth_format; + + /* create image */ + err = vkCreateImage(demo->device, &image, NULL, &demo->depth.image); + assert(!err); + + /* get memory requirements for this object */ + vkGetImageMemoryRequirements(demo->device, demo->depth.image, &mem_reqs); + + /* select memory size and type */ + mem_alloc.allocationSize = mem_reqs.size; + pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, + 0, /* No requirements */ + &mem_alloc.memoryTypeIndex); + assert(pass); + + /* allocate memory */ + err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->depth.mem); + assert(!err); + + /* bind memory */ + err = + vkBindImageMemory(demo->device, demo->depth.image, demo->depth.mem, 0); + assert(!err); + + demo_set_image_layout(demo, demo->depth.image, VK_IMAGE_ASPECT_DEPTH_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + /* create image view */ + view.image = demo->depth.image; + err = vkCreateImageView(demo->device, &view, NULL, &demo->depth.view); + assert(!err); +} + +static void +demo_prepare_texture_image(struct demo *demo, const uint32_t *tex_colors, + struct texture_object *tex_obj, VkImageTiling tiling, + VkImageUsageFlags usage, VkFlags required_props) { + const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; + const int32_t tex_width = 2; + const int32_t tex_height = 2; + VkResult U_ASSERT_ONLY err; + bool U_ASSERT_ONLY pass; + + tex_obj->tex_width = tex_width; + tex_obj->tex_height = tex_height; + + const VkImageCreateInfo image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = NULL, + .imageType = VK_IMAGE_TYPE_2D, + .format = tex_format, + .extent = {tex_width, tex_height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = tiling, + .usage = usage, + .flags = 0, + }; + VkMemoryAllocateInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = NULL, + .allocationSize = 0, + .memoryTypeIndex = 0, + }; + + VkMemoryRequirements mem_reqs; + + err = + vkCreateImage(demo->device, &image_create_info, NULL, &tex_obj->image); + assert(!err); + + vkGetImageMemoryRequirements(demo->device, tex_obj->image, &mem_reqs); + + mem_alloc.allocationSize = mem_reqs.size; + pass = + memory_type_from_properties(demo, mem_reqs.memoryTypeBits, + required_props, &mem_alloc.memoryTypeIndex); + assert(pass); + + /* allocate memory */ + err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &tex_obj->mem); + assert(!err); + + /* bind memory */ + err = vkBindImageMemory(demo->device, tex_obj->image, tex_obj->mem, 0); + assert(!err); + + if (required_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + const VkImageSubresource subres = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .arrayLayer = 0, + }; + VkSubresourceLayout layout; + void *data; + int32_t x, y; + + vkGetImageSubresourceLayout(demo->device, tex_obj->image, &subres, + &layout); + + err = vkMapMemory(demo->device, tex_obj->mem, 0, + mem_alloc.allocationSize, 0, &data); + assert(!err); + + for (y = 0; y < tex_height; y++) { + uint32_t *row = (uint32_t *)((char *)data + layout.rowPitch * y); + for (x = 0; x < tex_width; x++) + row[x] = tex_colors[(x & 1) ^ (y & 1)]; + } + + vkUnmapMemory(demo->device, tex_obj->mem); + } + + tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + demo_set_image_layout(demo, tex_obj->image, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, tex_obj->imageLayout); + /* setting the image layout does not reference the actual memory so no need + * to add a mem ref */ +} + +static void demo_destroy_texture_image(struct demo *demo, + struct texture_object *tex_obj) { + /* clean up staging resources */ + vkDestroyImage(demo->device, tex_obj->image, NULL); + vkFreeMemory(demo->device, tex_obj->mem, NULL); +} + +static void demo_prepare_textures(struct demo *demo) { + const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; + VkFormatProperties props; + const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = { + {0xffff0000, 0xff00ff00}, + }; + uint32_t i; + VkResult U_ASSERT_ONLY err; + + vkGetPhysicalDeviceFormatProperties(demo->gpu, tex_format, &props); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + if ((props.linearTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) && + !demo->use_staging_buffer) { + /* Device can texture using linear textures */ + demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i], + VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + } else if (props.optimalTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { + /* Must use staging buffer to copy linear texture to optimized */ + struct texture_object staging_texture; + + memset(&staging_texture, 0, sizeof(staging_texture)); + demo_prepare_texture_image(demo, tex_colors[i], &staging_texture, + VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + + demo_prepare_texture_image( + demo, tex_colors[i], &demo->textures[i], + VK_IMAGE_TILING_OPTIMAL, + (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + demo_set_image_layout(demo, staging_texture.image, + VK_IMAGE_ASPECT_COLOR_BIT, + staging_texture.imageLayout, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + demo_set_image_layout(demo, demo->textures[i].image, + VK_IMAGE_ASPECT_COLOR_BIT, + demo->textures[i].imageLayout, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkImageCopy copy_region = { + .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + .srcOffset = {0, 0, 0}, + .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + .dstOffset = {0, 0, 0}, + .extent = {staging_texture.tex_width, + staging_texture.tex_height, 1}, + }; + vkCmdCopyImage( + demo->setup_cmd, staging_texture.image, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, demo->textures[i].image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); + + demo_set_image_layout(demo, demo->textures[i].image, + VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + demo->textures[i].imageLayout); + + demo_flush_init_cmd(demo); + + demo_destroy_texture_image(demo, &staging_texture); + } else { + /* Can't support VK_FORMAT_B8G8R8A8_UNORM !? */ + assert(!"No support for B8G8R8A8_UNORM as texture image format"); + } + + const VkSamplerCreateInfo sampler = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = NULL, + .magFilter = VK_FILTER_NEAREST, + .minFilter = VK_FILTER_NEAREST, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .mipLodBias = 0.0f, + .anisotropyEnable = VK_FALSE, + .maxAnisotropy = 1, + .compareOp = VK_COMPARE_OP_NEVER, + .minLod = 0.0f, + .maxLod = 0.0f, + .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + .unnormalizedCoordinates = VK_FALSE, + }; + VkImageViewCreateInfo view = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = VK_NULL_HANDLE, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = tex_format, + .components = + { + VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A, + }, + .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, + .flags = 0, + }; + + /* create sampler */ + err = vkCreateSampler(demo->device, &sampler, NULL, + &demo->textures[i].sampler); + assert(!err); + + /* create image view */ + view.image = demo->textures[i].image; + err = vkCreateImageView(demo->device, &view, NULL, + &demo->textures[i].view); + assert(!err); + } +} + +static void demo_prepare_vertices(struct demo *demo) { + // clang-format off + const float vb[3][5] = { + /* position texcoord */ + { -1.0f, -1.0f, 0.25f, 0.0f, 0.0f }, + { 1.0f, -1.0f, 0.25f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 1.0f, 0.5f, 1.0f }, + }; + // clang-format on + const VkBufferCreateInfo buf_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = NULL, + .size = sizeof(vb), + .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + .flags = 0, + }; + VkMemoryAllocateInfo mem_alloc = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = NULL, + .allocationSize = 0, + .memoryTypeIndex = 0, + }; + VkMemoryRequirements mem_reqs; + VkResult U_ASSERT_ONLY err; + bool U_ASSERT_ONLY pass; + void *data; + + memset(&demo->vertices, 0, sizeof(demo->vertices)); + + err = vkCreateBuffer(demo->device, &buf_info, NULL, &demo->vertices.buf); + assert(!err); + + vkGetBufferMemoryRequirements(demo->device, demo->vertices.buf, &mem_reqs); + assert(!err); + + mem_alloc.allocationSize = mem_reqs.size; + pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + &mem_alloc.memoryTypeIndex); + assert(pass); + + err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->vertices.mem); + assert(!err); + + err = vkMapMemory(demo->device, demo->vertices.mem, 0, + mem_alloc.allocationSize, 0, &data); + assert(!err); + + memcpy(data, vb, sizeof(vb)); + + vkUnmapMemory(demo->device, demo->vertices.mem); + + err = vkBindBufferMemory(demo->device, demo->vertices.buf, + demo->vertices.mem, 0); + assert(!err); + + demo->vertices.vi.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + demo->vertices.vi.pNext = NULL; + demo->vertices.vi.vertexBindingDescriptionCount = 1; + demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings; + demo->vertices.vi.vertexAttributeDescriptionCount = 2; + demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs; + + demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_bindings[0].stride = sizeof(vb[0]); + demo->vertices.vi_bindings[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + demo->vertices.vi_attrs[0].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_attrs[0].location = 0; + demo->vertices.vi_attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT; + demo->vertices.vi_attrs[0].offset = 0; + + demo->vertices.vi_attrs[1].binding = VERTEX_BUFFER_BIND_ID; + demo->vertices.vi_attrs[1].location = 1; + demo->vertices.vi_attrs[1].format = VK_FORMAT_R32G32_SFLOAT; + demo->vertices.vi_attrs[1].offset = sizeof(float) * 3; +} + +static void demo_prepare_descriptor_layout(struct demo *demo) { + const VkDescriptorSetLayoutBinding layout_binding = { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = DEMO_TEXTURE_COUNT, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = NULL, + }; + const VkDescriptorSetLayoutCreateInfo descriptor_layout = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = NULL, + .bindingCount = 1, + .pBindings = &layout_binding, + }; + VkResult U_ASSERT_ONLY err; + + err = vkCreateDescriptorSetLayout(demo->device, &descriptor_layout, NULL, + &demo->desc_layout); + assert(!err); + + const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = NULL, + .setLayoutCount = 1, + .pSetLayouts = &demo->desc_layout, + }; + + err = vkCreatePipelineLayout(demo->device, &pPipelineLayoutCreateInfo, NULL, + &demo->pipeline_layout); + assert(!err); +} + +static void demo_prepare_render_pass(struct demo *demo) { + const VkAttachmentDescription attachments[2] = { + [0] = + { + .format = demo->format, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }, + [1] = + { + .format = demo->depth.format, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .finalLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }, + }; + const VkAttachmentReference color_reference = { + .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; + const VkAttachmentReference depth_reference = { + .attachment = 1, + .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }; + const VkSubpassDescription subpass = { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .flags = 0, + .inputAttachmentCount = 0, + .pInputAttachments = NULL, + .colorAttachmentCount = 1, + .pColorAttachments = &color_reference, + .pResolveAttachments = NULL, + .pDepthStencilAttachment = &depth_reference, + .preserveAttachmentCount = 0, + .pPreserveAttachments = NULL, + }; + const VkRenderPassCreateInfo rp_info = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .pNext = NULL, + .attachmentCount = 2, + .pAttachments = attachments, + .subpassCount = 1, + .pSubpasses = &subpass, + .dependencyCount = 0, + .pDependencies = NULL, + }; + VkResult U_ASSERT_ONLY err; + + err = vkCreateRenderPass(demo->device, &rp_info, NULL, &demo->render_pass); + assert(!err); +} + +static VkShaderModule +demo_prepare_shader_module(struct demo *demo, const void *code, size_t size) { + VkShaderModuleCreateInfo moduleCreateInfo; + VkShaderModule module; + VkResult U_ASSERT_ONLY err; + + moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleCreateInfo.pNext = NULL; + + moduleCreateInfo.codeSize = size; + moduleCreateInfo.pCode = code; + moduleCreateInfo.flags = 0; + err = vkCreateShaderModule(demo->device, &moduleCreateInfo, NULL, &module); + assert(!err); + + return module; +} + +static VkShaderModule demo_prepare_vs(struct demo *demo) { + size_t size = sizeof(vertShaderCode); + + demo->vert_shader_module = + demo_prepare_shader_module(demo, vertShaderCode, size); + + return demo->vert_shader_module; +} + +static VkShaderModule demo_prepare_fs(struct demo *demo) { + size_t size = sizeof(fragShaderCode); + + demo->frag_shader_module = + demo_prepare_shader_module(demo, fragShaderCode, size); + + return demo->frag_shader_module; +} + +static void demo_prepare_pipeline(struct demo *demo) { + VkGraphicsPipelineCreateInfo pipeline; + VkPipelineCacheCreateInfo pipelineCache; + + VkPipelineVertexInputStateCreateInfo vi; + VkPipelineInputAssemblyStateCreateInfo ia; + VkPipelineRasterizationStateCreateInfo rs; + VkPipelineColorBlendStateCreateInfo cb; + VkPipelineDepthStencilStateCreateInfo ds; + VkPipelineViewportStateCreateInfo vp; + VkPipelineMultisampleStateCreateInfo ms; + VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; + VkPipelineDynamicStateCreateInfo dynamicState; + + VkResult U_ASSERT_ONLY err; + + memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); + memset(&dynamicState, 0, sizeof dynamicState); + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.pDynamicStates = dynamicStateEnables; + + memset(&pipeline, 0, sizeof(pipeline)); + pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipeline.layout = demo->pipeline_layout; + + vi = demo->vertices.vi; + + memset(&ia, 0, sizeof(ia)); + ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + memset(&rs, 0, sizeof(rs)); + rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rs.polygonMode = VK_POLYGON_MODE_FILL; + rs.cullMode = VK_CULL_MODE_BACK_BIT; + rs.frontFace = VK_FRONT_FACE_CLOCKWISE; + rs.depthClampEnable = VK_FALSE; + rs.rasterizerDiscardEnable = VK_FALSE; + rs.depthBiasEnable = VK_FALSE; + + memset(&cb, 0, sizeof(cb)); + cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + VkPipelineColorBlendAttachmentState att_state[1]; + memset(att_state, 0, sizeof(att_state)); + att_state[0].colorWriteMask = 0xf; + att_state[0].blendEnable = VK_FALSE; + cb.attachmentCount = 1; + cb.pAttachments = att_state; + + memset(&vp, 0, sizeof(vp)); + vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + vp.viewportCount = 1; + dynamicStateEnables[dynamicState.dynamicStateCount++] = + VK_DYNAMIC_STATE_VIEWPORT; + vp.scissorCount = 1; + dynamicStateEnables[dynamicState.dynamicStateCount++] = + VK_DYNAMIC_STATE_SCISSOR; + + memset(&ds, 0, sizeof(ds)); + ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + ds.depthTestEnable = VK_TRUE; + ds.depthWriteEnable = VK_TRUE; + ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + ds.depthBoundsTestEnable = VK_FALSE; + ds.back.failOp = VK_STENCIL_OP_KEEP; + ds.back.passOp = VK_STENCIL_OP_KEEP; + ds.back.compareOp = VK_COMPARE_OP_ALWAYS; + ds.stencilTestEnable = VK_FALSE; + ds.front = ds.back; + + memset(&ms, 0, sizeof(ms)); + ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms.pSampleMask = NULL; + ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + // Two stages: vs and fs + pipeline.stageCount = 2; + VkPipelineShaderStageCreateInfo shaderStages[2]; + memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo)); + + shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + shaderStages[0].module = demo_prepare_vs(demo); + shaderStages[0].pName = "main"; + + shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shaderStages[1].module = demo_prepare_fs(demo); + shaderStages[1].pName = "main"; + + pipeline.pVertexInputState = &vi; + pipeline.pInputAssemblyState = &ia; + pipeline.pRasterizationState = &rs; + pipeline.pColorBlendState = &cb; + pipeline.pMultisampleState = &ms; + pipeline.pViewportState = &vp; + pipeline.pDepthStencilState = &ds; + pipeline.pStages = shaderStages; + pipeline.renderPass = demo->render_pass; + pipeline.pDynamicState = &dynamicState; + + memset(&pipelineCache, 0, sizeof(pipelineCache)); + pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + + err = vkCreatePipelineCache(demo->device, &pipelineCache, NULL, + &demo->pipelineCache); + assert(!err); + err = vkCreateGraphicsPipelines(demo->device, demo->pipelineCache, 1, + &pipeline, NULL, &demo->pipeline); + assert(!err); + + vkDestroyPipelineCache(demo->device, demo->pipelineCache, NULL); + + vkDestroyShaderModule(demo->device, demo->frag_shader_module, NULL); + vkDestroyShaderModule(demo->device, demo->vert_shader_module, NULL); +} + +static void demo_prepare_descriptor_pool(struct demo *demo) { + const VkDescriptorPoolSize type_count = { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = DEMO_TEXTURE_COUNT, + }; + const VkDescriptorPoolCreateInfo descriptor_pool = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = NULL, + .maxSets = 1, + .poolSizeCount = 1, + .pPoolSizes = &type_count, + }; + VkResult U_ASSERT_ONLY err; + + err = vkCreateDescriptorPool(demo->device, &descriptor_pool, NULL, + &demo->desc_pool); + assert(!err); +} + +static void demo_prepare_descriptor_set(struct demo *demo) { + VkDescriptorImageInfo tex_descs[DEMO_TEXTURE_COUNT]; + VkWriteDescriptorSet write; + VkResult U_ASSERT_ONLY err; + uint32_t i; + + VkDescriptorSetAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = NULL, + .descriptorPool = demo->desc_pool, + .descriptorSetCount = 1, + .pSetLayouts = &demo->desc_layout}; + err = vkAllocateDescriptorSets(demo->device, &alloc_info, &demo->desc_set); + assert(!err); + + memset(&tex_descs, 0, sizeof(tex_descs)); + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + tex_descs[i].sampler = demo->textures[i].sampler; + tex_descs[i].imageView = demo->textures[i].view; + tex_descs[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL; + } + + memset(&write, 0, sizeof(write)); + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstSet = demo->desc_set; + write.descriptorCount = DEMO_TEXTURE_COUNT; + write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write.pImageInfo = tex_descs; + + vkUpdateDescriptorSets(demo->device, 1, &write, 0, NULL); +} + +static void demo_prepare_framebuffers(struct demo *demo) { + VkImageView attachments[2]; + attachments[1] = demo->depth.view; + + const VkFramebufferCreateInfo fb_info = { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .pNext = NULL, + .renderPass = demo->render_pass, + .attachmentCount = 2, + .pAttachments = attachments, + .width = demo->width, + .height = demo->height, + .layers = 1, + }; + VkResult U_ASSERT_ONLY err; + uint32_t i; + + demo->framebuffers = (VkFramebuffer *)malloc(demo->swapchainImageCount * + sizeof(VkFramebuffer)); + assert(demo->framebuffers); + + for (i = 0; i < demo->swapchainImageCount; i++) { + attachments[0] = demo->buffers[i].view; + err = vkCreateFramebuffer(demo->device, &fb_info, NULL, + &demo->framebuffers[i]); + assert(!err); + } +} + +static void demo_prepare(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + + const VkCommandPoolCreateInfo cmd_pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = NULL, + .queueFamilyIndex = demo->graphics_queue_node_index, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + }; + err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL, + &demo->cmd_pool); + assert(!err); + + const VkCommandBufferAllocateInfo cmd = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = NULL, + .commandPool = demo->cmd_pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->draw_cmd); + assert(!err); + + demo_prepare_buffers(demo); + demo_prepare_depth(demo); + demo_prepare_textures(demo); + demo_prepare_vertices(demo); + demo_prepare_descriptor_layout(demo); + demo_prepare_render_pass(demo); + demo_prepare_pipeline(demo); + + demo_prepare_descriptor_pool(demo); + demo_prepare_descriptor_set(demo); + + demo_prepare_framebuffers(demo); +} + +static void demo_error_callback(int error, const char* description) { + printf("GLFW error: %s\n", description); + fflush(stdout); +} + +static void demo_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +static void demo_refresh_callback(GLFWwindow* window) { + struct demo* demo = glfwGetWindowUserPointer(window); + demo_draw(demo); +} + +static void demo_resize_callback(GLFWwindow* window, int width, int height) { + struct demo* demo = glfwGetWindowUserPointer(window); + demo->width = width; + demo->height = height; + demo_resize(demo); +} + +static void demo_run(struct demo *demo) { + while (!glfwWindowShouldClose(demo->window)) { + glfwPollEvents(); + + demo_draw(demo); + + if (demo->depthStencil > 0.99f) + demo->depthIncrement = -0.001f; + if (demo->depthStencil < 0.8f) + demo->depthIncrement = 0.001f; + + demo->depthStencil += demo->depthIncrement; + + // Wait for work to finish before updating MVP. + vkDeviceWaitIdle(demo->device); + } +} + +static void demo_create_window(struct demo *demo) { + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + demo->window = glfwCreateWindow(demo->width, + demo->height, + APP_LONG_NAME, + NULL, + NULL); + if (!demo->window) { + // It didn't work, so try to give a useful error: + printf("Cannot create a window in which to draw!\n"); + fflush(stdout); + exit(1); + } + + glfwSetWindowUserPointer(demo->window, demo); + glfwSetWindowRefreshCallback(demo->window, demo_refresh_callback); + glfwSetFramebufferSizeCallback(demo->window, demo_resize_callback); + glfwSetKeyCallback(demo->window, demo_key_callback); +} + +/* + * Return 1 (true) if all layer names specified in check_names + * can be found in given layer properties. + */ +static VkBool32 demo_check_layers(uint32_t check_count, char **check_names, + uint32_t layer_count, + VkLayerProperties *layers) { + uint32_t i, j; + for (i = 0; i < check_count; i++) { + VkBool32 found = 0; + for (j = 0; j < layer_count; j++) { + if (!strcmp(check_names[i], layers[j].layerName)) { + found = 1; + break; + } + } + if (!found) { + fprintf(stderr, "Cannot find layer: %s\n", check_names[i]); + return 0; + } + } + return 1; +} + +VKAPI_ATTR void *VKAPI_CALL myrealloc(void *pUserData, void *pOriginal, + size_t size, size_t alignment, + VkSystemAllocationScope allocationScope) { + return realloc(pOriginal, size); +} + +VKAPI_ATTR void *VKAPI_CALL myalloc(void *pUserData, size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope) { +#ifdef _MSC_VER + return _aligned_malloc(size, alignment); +#else + return aligned_alloc(alignment, size); +#endif +} + +VKAPI_ATTR void VKAPI_CALL myfree(void *pUserData, void *pMemory) { +#ifdef _MSC_VER + _aligned_free(pMemory); +#else + free(pMemory); +#endif +} + +static void demo_init_vk(struct demo *demo) { + VkResult err; + uint32_t required_extension_count; + const char** required_extensions; + uint32_t i; + uint32_t instance_extension_count = 0; + uint32_t instance_layer_count = 0; + uint32_t device_validation_layer_count = 0; + demo->enabled_extension_count = 0; + demo->enabled_layer_count = 0; + + char *instance_validation_layers[] = { + "VK_LAYER_LUNARG_mem_tracker", + "VK_LAYER_GOOGLE_unique_objects", + }; + + demo->device_validation_layers[0] = "VK_LAYER_LUNARG_mem_tracker"; + demo->device_validation_layers[1] = "VK_LAYER_GOOGLE_unique_objects"; + device_validation_layer_count = 2; + + /* Look for validation layers */ + VkBool32 validation_found = 0; + err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL); + assert(!err); + + if (instance_layer_count > 0) { + VkLayerProperties *instance_layers = + malloc(sizeof(VkLayerProperties) * instance_layer_count); + err = vkEnumerateInstanceLayerProperties(&instance_layer_count, + instance_layers); + assert(!err); + + if (demo->validate) { + validation_found = demo_check_layers( + ARRAY_SIZE(instance_validation_layers), + instance_validation_layers, instance_layer_count, + instance_layers); + demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers); + } + + free(instance_layers); + } + + if (demo->validate && !validation_found) { + ERR_EXIT("vkEnumerateInstanceLayerProperties failed to find" + "required validation layer.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + /* Look for instance extensions */ + required_extensions = glfwGetRequiredInstanceExtensions(&required_extension_count); + if (!required_extensions) { + ERR_EXIT("glfwGetRequiredInstanceExtensions failed to find the " + "platform surface extensions.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + for (i = 0; i < required_extension_count; i++) { + demo->extension_names[demo->enabled_extension_count++] = required_extensions[i]; + assert(demo->enabled_extension_count < 64); + } + + err = vkEnumerateInstanceExtensionProperties( + NULL, &instance_extension_count, NULL); + assert(!err); + + if (instance_extension_count > 0) { + VkExtensionProperties *instance_extensions = + malloc(sizeof(VkExtensionProperties) * instance_extension_count); + err = vkEnumerateInstanceExtensionProperties( + NULL, &instance_extension_count, instance_extensions); + assert(!err); + for (i = 0; i < instance_extension_count; i++) { + if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, + instance_extensions[i].extensionName)) { + if (demo->validate) { + demo->extension_names[demo->enabled_extension_count++] = + VK_EXT_DEBUG_REPORT_EXTENSION_NAME; + } + } + assert(demo->enabled_extension_count < 64); + } + + free(instance_extensions); + } + + const VkApplicationInfo app = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = NULL, + .pApplicationName = APP_SHORT_NAME, + .applicationVersion = 0, + .pEngineName = APP_SHORT_NAME, + .engineVersion = 0, + .apiVersion = VK_API_VERSION_1_0, + }; + VkInstanceCreateInfo inst_info = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = NULL, + .pApplicationInfo = &app, + .enabledLayerCount = demo->enabled_layer_count, + .ppEnabledLayerNames = (const char *const *)instance_validation_layers, + .enabledExtensionCount = demo->enabled_extension_count, + .ppEnabledExtensionNames = (const char *const *)demo->extension_names, + }; + + uint32_t gpu_count; + + demo->allocator.pfnAllocation = myalloc; + demo->allocator.pfnFree = myfree; + demo->allocator.pfnReallocation = myrealloc; + + err = vkCreateInstance(&inst_info, &demo->allocator, &demo->inst); + if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { + ERR_EXIT("Cannot find a compatible Vulkan installable client driver " + "(ICD).\n\nPlease look at the Getting Started guide for " + "additional information.\n", + "vkCreateInstance Failure"); + } else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) { + ERR_EXIT("Cannot find a specified extension library" + ".\nMake sure your layers path is set appropriately\n", + "vkCreateInstance Failure"); + } else if (err) { + ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan " + "installable client driver (ICD) installed?\nPlease look at " + "the Getting Started guide for additional information.\n", + "vkCreateInstance Failure"); + } + + /* Make initial call to query gpu_count, then second call for gpu info*/ + err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL); + assert(!err && gpu_count > 0); + + if (gpu_count > 0) { + VkPhysicalDevice *physical_devices = + malloc(sizeof(VkPhysicalDevice) * gpu_count); + err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, + physical_devices); + assert(!err); + /* For tri demo we just grab the first physical device */ + demo->gpu = physical_devices[0]; + free(physical_devices); + } else { + ERR_EXIT("vkEnumeratePhysicalDevices reported zero accessible devices." + "\n\nDo you have a compatible Vulkan installable client" + " driver (ICD) installed?\nPlease look at the Getting Started" + " guide for additional information.\n", + "vkEnumeratePhysicalDevices Failure"); + } + + /* Look for validation layers */ + validation_found = 0; + demo->enabled_layer_count = 0; + uint32_t device_layer_count = 0; + err = + vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count, NULL); + assert(!err); + + if (device_layer_count > 0) { + VkLayerProperties *device_layers = + malloc(sizeof(VkLayerProperties) * device_layer_count); + err = vkEnumerateDeviceLayerProperties(demo->gpu, &device_layer_count, + device_layers); + assert(!err); + + if (demo->validate) { + validation_found = demo_check_layers(device_validation_layer_count, + demo->device_validation_layers, + device_layer_count, + device_layers); + demo->enabled_layer_count = device_validation_layer_count; + } + + free(device_layers); + } + + if (demo->validate && !validation_found) { + ERR_EXIT("vkEnumerateDeviceLayerProperties failed to find " + "a required validation layer.\n\n" + "Please look at the Getting Started guide for additional " + "information.\n", + "vkCreateDevice Failure"); + } + + /* Look for device extensions */ + uint32_t device_extension_count = 0; + VkBool32 swapchainExtFound = 0; + demo->enabled_extension_count = 0; + + err = vkEnumerateDeviceExtensionProperties(demo->gpu, NULL, + &device_extension_count, NULL); + assert(!err); + + if (device_extension_count > 0) { + VkExtensionProperties *device_extensions = + malloc(sizeof(VkExtensionProperties) * device_extension_count); + err = vkEnumerateDeviceExtensionProperties( + demo->gpu, NULL, &device_extension_count, device_extensions); + assert(!err); + + for (i = 0; i < device_extension_count; i++) { + if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, + device_extensions[i].extensionName)) { + swapchainExtFound = 1; + demo->extension_names[demo->enabled_extension_count++] = + VK_KHR_SWAPCHAIN_EXTENSION_NAME; + } + assert(demo->enabled_extension_count < 64); + } + + free(device_extensions); + } + + if (!swapchainExtFound) { + ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find " + "the " VK_KHR_SWAPCHAIN_EXTENSION_NAME + " extension.\n\nDo you have a compatible " + "Vulkan installable client driver (ICD) installed?\nPlease " + "look at the Getting Started guide for additional " + "information.\n", + "vkCreateInstance Failure"); + } + + if (demo->validate) { + demo->CreateDebugReportCallback = + (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr( + demo->inst, "vkCreateDebugReportCallbackEXT"); + if (!demo->CreateDebugReportCallback) { + ERR_EXIT( + "GetProcAddr: Unable to find vkCreateDebugReportCallbackEXT\n", + "vkGetProcAddr Failure"); + } + VkDebugReportCallbackCreateInfoEXT dbgCreateInfo; + dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + dbgCreateInfo.flags = + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + dbgCreateInfo.pfnCallback = dbgFunc; + dbgCreateInfo.pUserData = NULL; + dbgCreateInfo.pNext = NULL; + err = demo->CreateDebugReportCallback(demo->inst, &dbgCreateInfo, NULL, + &demo->msg_callback); + switch (err) { + case VK_SUCCESS: + break; + case VK_ERROR_OUT_OF_HOST_MEMORY: + ERR_EXIT("CreateDebugReportCallback: out of host memory\n", + "CreateDebugReportCallback Failure"); + break; + default: + ERR_EXIT("CreateDebugReportCallback: unknown failure\n", + "CreateDebugReportCallback Failure"); + break; + } + } + + // Having these GIPA queries of device extension entry points both + // BEFORE and AFTER vkCreateDevice is a good test for the loader + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceCapabilitiesKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceFormatsKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfacePresentModesKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceSupportKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, CreateSwapchainKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, DestroySwapchainKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, GetSwapchainImagesKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, AcquireNextImageKHR); + GET_INSTANCE_PROC_ADDR(demo->inst, QueuePresentKHR); + + vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props); + + // Query with NULL data to get count + vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count, + NULL); + + demo->queue_props = (VkQueueFamilyProperties *)malloc( + demo->queue_count * sizeof(VkQueueFamilyProperties)); + vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count, + demo->queue_props); + assert(demo->queue_count >= 1); + + // Graphics queue and MemMgr queue can be separate. + // TODO: Add support for separate queues, including synchronization, + // and appropriate tracking for QueueSubmit +} + +static void demo_init_device(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + + float queue_priorities[1] = {0.0}; + const VkDeviceQueueCreateInfo queue = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .pNext = NULL, + .queueFamilyIndex = demo->graphics_queue_node_index, + .queueCount = 1, + .pQueuePriorities = queue_priorities}; + + VkDeviceCreateInfo device = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = NULL, + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &queue, + .enabledLayerCount = demo->enabled_layer_count, + .ppEnabledLayerNames = + (const char *const *)((demo->validate) + ? demo->device_validation_layers + : NULL), + .enabledExtensionCount = demo->enabled_extension_count, + .ppEnabledExtensionNames = (const char *const *)demo->extension_names, + }; + + err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device); + assert(!err); + + GET_DEVICE_PROC_ADDR(demo->device, CreateSwapchainKHR); + GET_DEVICE_PROC_ADDR(demo->device, DestroySwapchainKHR); + GET_DEVICE_PROC_ADDR(demo->device, GetSwapchainImagesKHR); + GET_DEVICE_PROC_ADDR(demo->device, AcquireNextImageKHR); + GET_DEVICE_PROC_ADDR(demo->device, QueuePresentKHR); +} + +static void demo_init_vk_swapchain(struct demo *demo) { + VkResult U_ASSERT_ONLY err; + uint32_t i; + + // Create a WSI surface for the window: + glfwCreateWindowSurface(demo->inst, demo->window, NULL, &demo->surface); + + // Iterate over each queue to learn whether it supports presenting: + VkBool32 *supportsPresent = + (VkBool32 *)malloc(demo->queue_count * sizeof(VkBool32)); + for (i = 0; i < demo->queue_count; i++) { + demo->fpGetPhysicalDeviceSurfaceSupportKHR(demo->gpu, i, demo->surface, + &supportsPresent[i]); + } + + // Search for a graphics and a present queue in the array of queue + // families, try to find one that supports both + uint32_t graphicsQueueNodeIndex = UINT32_MAX; + uint32_t presentQueueNodeIndex = UINT32_MAX; + for (i = 0; i < demo->queue_count; i++) { + if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) { + if (graphicsQueueNodeIndex == UINT32_MAX) { + graphicsQueueNodeIndex = i; + } + + if (supportsPresent[i] == VK_TRUE) { + graphicsQueueNodeIndex = i; + presentQueueNodeIndex = i; + break; + } + } + } + if (presentQueueNodeIndex == UINT32_MAX) { + // If didn't find a queue that supports both graphics and present, then + // find a separate present queue. + for (i = 0; i < demo->queue_count; ++i) { + if (supportsPresent[i] == VK_TRUE) { + presentQueueNodeIndex = i; + break; + } + } + } + free(supportsPresent); + + // Generate error if could not find both a graphics and a present queue + if (graphicsQueueNodeIndex == UINT32_MAX || + presentQueueNodeIndex == UINT32_MAX) { + ERR_EXIT("Could not find a graphics and a present queue\n", + "Swapchain Initialization Failure"); + } + + // TODO: Add support for separate queues, including presentation, + // synchronization, and appropriate tracking for QueueSubmit. + // NOTE: While it is possible for an application to use a separate graphics + // and a present queues, this demo program assumes it is only using + // one: + if (graphicsQueueNodeIndex != presentQueueNodeIndex) { + ERR_EXIT("Could not find a common graphics and a present queue\n", + "Swapchain Initialization Failure"); + } + + demo->graphics_queue_node_index = graphicsQueueNodeIndex; + + demo_init_device(demo); + + vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index, 0, + &demo->queue); + + // Get the list of VkFormat's that are supported: + uint32_t formatCount; + err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, + &formatCount, NULL); + assert(!err); + VkSurfaceFormatKHR *surfFormats = + (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); + err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, + &formatCount, surfFormats); + assert(!err); + // If the format list includes just one entry of VK_FORMAT_UNDEFINED, + // the surface has no preferred format. Otherwise, at least one + // supported format will be returned. + if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) { + demo->format = VK_FORMAT_B8G8R8A8_UNORM; + } else { + assert(formatCount >= 1); + demo->format = surfFormats[0].format; + } + demo->color_space = surfFormats[0].colorSpace; + + // Get Memory information and properties + vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties); +} + +static void demo_init_connection(struct demo *demo) { + glfwSetErrorCallback(demo_error_callback); + + if (!glfwInit()) { + printf("Cannot initialize GLFW.\nExiting ...\n"); + fflush(stdout); + exit(1); + } + + if (!glfwVulkanSupported()) { + printf("GLFW failed to find the Vulkan loader.\nExiting ...\n"); + fflush(stdout); + exit(1); + } +} + +static void demo_init(struct demo *demo, const int argc, const char *argv[]) +{ + int i; + + memset(demo, 0, sizeof(*demo)); + + for (i = 0; i < argc; i++) { + if (strncmp(argv[i], "--use_staging", strlen("--use_staging")) == 0) + demo->use_staging_buffer = true; + } + + demo_init_connection(demo); + demo_init_vk(demo); + + demo->width = 300; + demo->height = 300; + demo->depthStencil = 1.0; + demo->depthIncrement = -0.01f; +} + +static void demo_cleanup(struct demo *demo) { + uint32_t i; + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL); + } + free(demo->framebuffers); + vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL); + + if (demo->setup_cmd) { + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->setup_cmd); + } + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->draw_cmd); + vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL); + + vkDestroyPipeline(demo->device, demo->pipeline, NULL); + vkDestroyRenderPass(demo->device, demo->render_pass, NULL); + vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL); + + vkDestroyBuffer(demo->device, demo->vertices.buf, NULL); + vkFreeMemory(demo->device, demo->vertices.mem, NULL); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + vkDestroyImageView(demo->device, demo->textures[i].view, NULL); + vkDestroyImage(demo->device, demo->textures[i].image, NULL); + vkFreeMemory(demo->device, demo->textures[i].mem, NULL); + vkDestroySampler(demo->device, demo->textures[i].sampler, NULL); + } + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyImageView(demo->device, demo->buffers[i].view, NULL); + } + + vkDestroyImageView(demo->device, demo->depth.view, NULL); + vkDestroyImage(demo->device, demo->depth.image, NULL); + vkFreeMemory(demo->device, demo->depth.mem, NULL); + + demo->fpDestroySwapchainKHR(demo->device, demo->swapchain, NULL); + free(demo->buffers); + + vkDestroyDevice(demo->device, NULL); + vkDestroySurfaceKHR(demo->inst, demo->surface, NULL); + vkDestroyInstance(demo->inst, &demo->allocator); + + free(demo->queue_props); + + glfwDestroyWindow(demo->window); + glfwTerminate(); +} + +static void demo_resize(struct demo *demo) { + uint32_t i; + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL); + } + free(demo->framebuffers); + vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL); + + if (demo->setup_cmd) { + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->setup_cmd); + } + vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->draw_cmd); + vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL); + + vkDestroyPipeline(demo->device, demo->pipeline, NULL); + vkDestroyRenderPass(demo->device, demo->render_pass, NULL); + vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL); + vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL); + + vkDestroyBuffer(demo->device, demo->vertices.buf, NULL); + vkFreeMemory(demo->device, demo->vertices.mem, NULL); + + for (i = 0; i < DEMO_TEXTURE_COUNT; i++) { + vkDestroyImageView(demo->device, demo->textures[i].view, NULL); + vkDestroyImage(demo->device, demo->textures[i].image, NULL); + vkFreeMemory(demo->device, demo->textures[i].mem, NULL); + vkDestroySampler(demo->device, demo->textures[i].sampler, NULL); + } + + for (i = 0; i < demo->swapchainImageCount; i++) { + vkDestroyImageView(demo->device, demo->buffers[i].view, NULL); + } + + vkDestroyImageView(demo->device, demo->depth.view, NULL); + vkDestroyImage(demo->device, demo->depth.image, NULL); + vkFreeMemory(demo->device, demo->depth.mem, NULL); + + free(demo->buffers); + + // Second, re-perform the demo_prepare() function, which will re-create the + // swapchain: + demo_prepare(demo); +} + +int main(const int argc, const char *argv[]) { + struct demo demo; + + demo_init(&demo, argc, argv); + demo_create_window(&demo); + demo_init_vk_swapchain(&demo); + + demo_prepare(&demo); + demo_run(&demo); + + demo_cleanup(&demo); + + return 0; +} + diff --git a/extern/glfw-3.2.1/tests/windows.c b/extern/glfw-3.2.1/tests/windows.c new file mode 100644 index 0000000..025cce2 --- /dev/null +++ b/extern/glfw-3.2.1/tests/windows.c @@ -0,0 +1,166 @@ +//======================================================================== +// Simple multi-window test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test creates four windows and clears each in a different color +// +//======================================================================== + +#include +#include + +#include +#include + +#include "getopt.h" + +static const char* titles[] = +{ + "Red", + "Green", + "Blue", + "Yellow" +}; + +static const struct +{ + float r, g, b; +} colors[] = +{ + { 0.95f, 0.32f, 0.11f }, + { 0.50f, 0.80f, 0.16f }, + { 0.f, 0.68f, 0.94f }, + { 0.98f, 0.74f, 0.04f } +}; + +static void usage(void) +{ + printf("Usage: windows [-h] [-b]\n"); + printf("Options:\n"); + printf(" -b create decorated windows\n"); + printf(" -h show this help\n"); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (action != GLFW_PRESS) + return; + + switch (key) + { + case GLFW_KEY_SPACE: + { + int xpos, ypos; + glfwGetWindowPos(window, &xpos, &ypos); + glfwSetWindowPos(window, xpos, ypos); + break; + } + + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, GLFW_TRUE); + break; + } +} + +int main(int argc, char** argv) +{ + int i, ch; + int decorated = GLFW_FALSE; + int running = GLFW_TRUE; + GLFWwindow* windows[4]; + + while ((ch = getopt(argc, argv, "bh")) != -1) + { + switch (ch) + { + case 'b': + decorated = GLFW_TRUE; + break; + case 'h': + usage(); + exit(EXIT_SUCCESS); + default: + usage(); + exit(EXIT_FAILURE); + } + } + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_DECORATED, decorated); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + + for (i = 0; i < 4; i++) + { + int left, top, right, bottom; + + windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL); + if (!windows[i]) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetKeyCallback(windows[i], key_callback); + + glfwMakeContextCurrent(windows[i]); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f); + + glfwGetWindowFrameSize(windows[i], &left, &top, &right, &bottom); + glfwSetWindowPos(windows[i], + 100 + (i & 1) * (200 + left + right), + 100 + (i >> 1) * (200 + top + bottom)); + } + + for (i = 0; i < 4; i++) + glfwShowWindow(windows[i]); + + while (running) + { + for (i = 0; i < 4; i++) + { + glfwMakeContextCurrent(windows[i]); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(windows[i]); + + if (glfwWindowShouldClose(windows[i])) + running = GLFW_FALSE; + } + + glfwWaitEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/include/sb7ext.h b/include/sb7ext.h index 432155c..306dc9b 100644 --- a/include/sb7ext.h +++ b/include/sb7ext.h @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 Graham Sellers + * Copyright � 2012-2013 Graham Sellers * * This code is part of the OpenGL SuperBible, 6th Edition. * @@ -26,7 +26,9 @@ #ifndef __SB6EXT_H__ #define __SB6EXT_H__ +#ifndef __APPLE__ #include "GL/glext.h" +#endif GL3WglProc sb6GetProcAddress(const char * funcname); int sb6IsExtensionSupported(const char * extname); diff --git a/src/compressrgtc/compressrgtc.cpp b/src/compressrgtc/compressrgtc.cpp index bc6576d..91f72dd 100644 --- a/src/compressrgtc/compressrgtc.cpp +++ b/src/compressrgtc/compressrgtc.cpp @@ -107,7 +107,9 @@ void rgtccompressor::render(double T) { glClearBufferfv(GL_COLOR, 0, sb7::color::Black); +#if defined(_WIN32) && !defined(__MINGW32__) Sleep(1); +#endif glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, input_texture); diff --git a/src/deferredshading/deferredshading.cpp b/src/deferredshading/deferredshading.cpp index e8ecc12..e4455d5 100644 --- a/src/deferredshading/deferredshading.cpp +++ b/src/deferredshading/deferredshading.cpp @@ -118,7 +118,7 @@ class deferred_shading_app : public sb7::application } else { -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW32__) Sleep(10); #endif } diff --git a/src/fragcolorfrompos/fragcolorfrompos.cpp b/src/fragcolorfrompos/fragcolorfrompos.cpp index 5fa99fe..f43e15d 100644 --- a/src/fragcolorfrompos/fragcolorfrompos.cpp +++ b/src/fragcolorfrompos/fragcolorfrompos.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -42,7 +42,7 @@ class colorfromposition_app : public sb7::application #ifndef INTERPOLATE_COLOR static const char * vs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "void main(void) \n" "{ \n" @@ -56,7 +56,7 @@ class colorfromposition_app : public sb7::application static const char * fs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "out vec4 color; \n" " \n" @@ -71,7 +71,7 @@ class colorfromposition_app : public sb7::application #else static const char * vs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "out vec4 vs_color; \n" "void main(void) \n" @@ -90,7 +90,7 @@ class colorfromposition_app : public sb7::application static const char * fs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "in vec4 vs_color; \n" "out vec4 color; \n" diff --git a/src/hqfilter/hqfilter.cpp b/src/hqfilter/hqfilter.cpp index 1be4332..9f8dd19 100644 --- a/src/hqfilter/hqfilter.cpp +++ b/src/hqfilter/hqfilter.cpp @@ -90,7 +90,9 @@ void cubicfilter_app::render(double currentTime) glUseProgram(draw_tex_program); +#if defined(_WIN32) && !defined(__MINGW32__) Sleep(20); +#endif // defined glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, source_tex); diff --git a/src/ktxview/ktxview.cpp b/src/ktxview/ktxview.cpp index 4507199..d1037e3 100644 --- a/src/ktxview/ktxview.cpp +++ b/src/ktxview/ktxview.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -42,7 +42,7 @@ static void print_shader_log(GLuint shader) static const char * vs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "void main(void) \n" "{ \n" @@ -57,7 +57,7 @@ static const char * vs_source[] = static const char * fs_source[] = { - "#version 430 core \n" + "#version 410 core \n" " \n" "uniform sampler2D s; \n" " \n" diff --git a/src/mirrorclampedge/mirrorclampedge.cpp b/src/mirrorclampedge/mirrorclampedge.cpp index 05deb96..18c966c 100644 --- a/src/mirrorclampedge/mirrorclampedge.cpp +++ b/src/mirrorclampedge/mirrorclampedge.cpp @@ -93,7 +93,9 @@ void mirrorclamp_app::render(double T) glClearBufferfv(GL_COLOR, 0, sb7::color::Black); +#if defined(_WIN32) && !defined(__MINGW32__) Sleep(1); +#endif glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, input_texture); diff --git a/src/movingtri/movingtri.cpp b/src/movingtri/movingtri.cpp index 758b66b..0c2b3a3 100644 --- a/src/movingtri/movingtri.cpp +++ b/src/movingtri/movingtri.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,13 +22,13 @@ */ #include -#include +#include -class singlepoint_app : public sb7::application +class movingtri_app : public sb7::application { void init() { - static const char title[] = "OpenGL SuperBible - Single Point"; + static const char title[] = "OpenGL SuperBible - Moving Triangle"; sb7::application::init(); @@ -91,8 +91,9 @@ class singlepoint_app : public sb7::application glUseProgram(program); - GLfloat attrib[] = { (float)sin(currentTime) * 0.5f, - (float)cos(currentTime) * 0.6f, + const float time = static_cast(currentTime); + GLfloat attrib[] = { std::sin(time) * 0.5f, + std::cos(time) * 0.6f, 0.0f, 0.0f }; glVertexAttrib4fv(0, attrib); @@ -111,4 +112,4 @@ class singlepoint_app : public sb7::application GLuint vao; }; -DECLARE_MAIN(singlepoint_app) +DECLARE_MAIN(movingtri_app) diff --git a/src/sb7/sb7.cpp b/src/sb7/sb7.cpp index 12ce6f6..6f65196 100644 --- a/src/sb7/sb7.cpp +++ b/src/sb7/sb7.cpp @@ -27,7 +27,9 @@ sb7::application * sb7::application::app = 0; +#ifndef __APPLE__ #include +#endif #include @@ -63,4 +65,4 @@ void APIENTRY sb7::application::debug_callback(GLenum source, GLvoid* userParam) { reinterpret_cast(userParam)->onDebugMessage(source, type, id, severity, length, message); -} \ No newline at end of file +} diff --git a/src/simpleclear/simpleclear.cpp b/src/simpleclear/simpleclear.cpp index 4674ea9..c98ec7f 100644 --- a/src/simpleclear/simpleclear.cpp +++ b/src/simpleclear/simpleclear.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,7 @@ */ #include +#include class simpleclear_app : public sb7::application { @@ -36,7 +37,10 @@ class simpleclear_app : public sb7::application virtual void render(double currentTime) { - static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f }; + const float time = static_cast(currentTime); + const GLfloat red[] = {std::sin(time)*0.5f+0.5f, + std::cos(time)*0.5f+0.5f, + 0.0f, 1.0f }; glClearBufferfv(GL_COLOR, 0, red); } }; diff --git a/src/simpletexture/simpletexture.cpp b/src/simpletexture/simpletexture.cpp index c5e64a3..4e8ce8c 100644 --- a/src/simpletexture/simpletexture.cpp +++ b/src/simpletexture/simpletexture.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -44,7 +44,7 @@ static void print_shader_log(GLuint shader) static const char * vs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "void main(void) \n" "{ \n" @@ -58,7 +58,7 @@ static const char * vs_source[] = static const char * fs_source[] = { - "#version 430 core \n" + "#version 410 core \n" " \n" "uniform sampler2D s; \n" " \n" diff --git a/src/singlepoint/singlepoint.cpp b/src/singlepoint/singlepoint.cpp index 8846ee0..e34deab 100644 --- a/src/singlepoint/singlepoint.cpp +++ b/src/singlepoint/singlepoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -38,7 +38,7 @@ class singlepoint_app : public sb7::application { static const char * vs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "void main(void) \n" "{ \n" @@ -48,7 +48,7 @@ class singlepoint_app : public sb7::application static const char * fs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "out vec4 color; \n" " \n" diff --git a/src/singletri/singletri.cpp b/src/singletri/singletri.cpp index 8e580c2..69f9516 100644 --- a/src/singletri/singletri.cpp +++ b/src/singletri/singletri.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 Graham Sellers + * Copyright © 2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,7 @@ #include -class singlepoint_app : public sb7::application +class singletri_app : public sb7::application { void init() { @@ -38,7 +38,7 @@ class singlepoint_app : public sb7::application { static const char * vs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "void main(void) \n" "{ \n" @@ -52,7 +52,7 @@ class singlepoint_app : public sb7::application static const char * fs_source[] = { - "#version 420 core \n" + "#version 410 core \n" " \n" "out vec4 color; \n" " \n" @@ -100,4 +100,4 @@ class singlepoint_app : public sb7::application GLuint vao; }; -DECLARE_MAIN(singlepoint_app) +DECLARE_MAIN(singletri_app)