Initial commit
This commit is contained in:
commit
81e03851eb
117
.gitignore
vendored
Normal file
117
.gitignore
vendored
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/clion
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=clion
|
||||||
|
|
||||||
|
### CLion ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### CLion Patch ###
|
||||||
|
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||||
|
|
||||||
|
# *.iml
|
||||||
|
# modules.xml
|
||||||
|
# .idea/misc.xml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
||||||
|
.idea/**/sonarlint/
|
||||||
|
|
||||||
|
# SonarQube Plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
||||||
|
.idea/**/sonarIssues.xml
|
||||||
|
|
||||||
|
# Markdown Navigator plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
||||||
|
.idea/**/markdown-navigator.xml
|
||||||
|
.idea/**/markdown-navigator-enh.xml
|
||||||
|
.idea/**/markdown-navigator/
|
||||||
|
|
||||||
|
# Cache file creation bug
|
||||||
|
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
||||||
|
.idea/$CACHE_FILE$
|
||||||
|
|
||||||
|
# CodeStream plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/12206-codestream
|
||||||
|
.idea/codestream.xml
|
||||||
|
|
||||||
|
# Azure Toolkit for IntelliJ plugin
|
||||||
|
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
|
||||||
|
.idea/**/azureSettings.xml
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/clion
|
2
.idea/mcalc.iml
Normal file
2
.idea/mcalc.iml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
9
.idea/misc.xml
Normal file
9
.idea/misc.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
<component name="CidrRootsConfiguration">
|
||||||
|
<libraryRoots>
|
||||||
|
<file path="$PROJECT_DIR$/external" />
|
||||||
|
</libraryRoots>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/mcalc.iml" filepath="$PROJECT_DIR$/.idea/mcalc.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
30
CMakeLists.txt
Normal file
30
CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.26)
|
||||||
|
project(mcalc)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
|
find_package(FLEX REQUIRED)
|
||||||
|
find_package(BISON REQUIRED)
|
||||||
|
|
||||||
|
add_subdirectory(external)
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fb)
|
||||||
|
|
||||||
|
BISON_TARGET(parser src/parser.y ${CMAKE_CURRENT_BINARY_DIR}/fb/parser.cpp DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/fb/parser.h)
|
||||||
|
FLEX_TARGET(scanner src/tokens.l ${CMAKE_CURRENT_BINARY_DIR}/fb/lexer.cpp DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/fb/lexer.h)
|
||||||
|
ADD_FLEX_BISON_DEPENDENCY(scanner parser)
|
||||||
|
|
||||||
|
add_executable(mcalc
|
||||||
|
${BISON_parser_OUTPUTS}
|
||||||
|
${FLEX_scanner_OUTPUTS}
|
||||||
|
|
||||||
|
src/main.cpp
|
||||||
|
src/gui.cpp
|
||||||
|
src/state.cpp
|
||||||
|
src/mcalc.h
|
||||||
|
include/lexer_base.h
|
||||||
|
include/node.h
|
||||||
|
)
|
||||||
|
target_link_libraries(mcalc PRIVATE ext)
|
||||||
|
target_include_directories(mcalc PRIVATE include ${CMAKE_CURRENT_BINARY_DIR}/fb)
|
32
external/CMakeLists.txt
vendored
Executable file
32
external/CMakeLists.txt
vendored
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
add_subdirectory(glfw-3.3.8 EXCLUDE_FROM_ALL)
|
||||||
|
add_subdirectory(nativefiledialog-extended-1.1.0 EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_library(ext STATIC
|
||||||
|
glad/glad.c
|
||||||
|
|
||||||
|
imgui-docking/imgui.cpp
|
||||||
|
imgui-docking/imgui_draw.cpp
|
||||||
|
imgui-docking/imgui_widgets.cpp
|
||||||
|
imgui-docking/imgui_tables.cpp
|
||||||
|
imgui-docking/imgui_demo.cpp
|
||||||
|
imgui-docking/imgui_stdlib.cpp
|
||||||
|
imgui-docking/backends/imgui_impl_glfw.cpp
|
||||||
|
imgui-docking/backends/imgui_impl_opengl3.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(ext PUBLIC
|
||||||
|
imgui-docking
|
||||||
|
ImGuiFileDialog
|
||||||
|
glad
|
||||||
|
glfw-3.3.8/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(ext PUBLIC
|
||||||
|
glfw
|
||||||
|
${GLFW_LIBRARIES}
|
||||||
|
nfd
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(ext PROPERTIES LINKER_LANGUAGE CXX)
|
311
external/glad/KHR/khrplatform.h
vendored
Executable file
311
external/glad/KHR/khrplatform.h
vendored
Executable file
@ -0,0 +1,311 @@
|
|||||||
|
#ifndef __khrplatform_h_
|
||||||
|
#define __khrplatform_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Khronos platform-specific types and definitions.
|
||||||
|
*
|
||||||
|
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||||
|
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||||
|
* The last semantic modification to khrplatform.h was at commit ID:
|
||||||
|
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||||
|
*
|
||||||
|
* Adopters may modify this file to suit their platform. Adopters are
|
||||||
|
* encouraged to submit platform specific modifications to the Khronos
|
||||||
|
* group so that they can be included in future versions of this file.
|
||||||
|
* Please submit changes by filing pull requests or issues on
|
||||||
|
* the EGL Registry repository linked above.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* See the Implementer's Guidelines for information about where this file
|
||||||
|
* should be located on your system and for more details of its use:
|
||||||
|
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||||
|
*
|
||||||
|
* This file should be included as
|
||||||
|
* #include <KHR/khrplatform.h>
|
||||||
|
* by Khronos client API header files that use its types and defines.
|
||||||
|
*
|
||||||
|
* The types in khrplatform.h should only be used to define API-specific types.
|
||||||
|
*
|
||||||
|
* Types defined in khrplatform.h:
|
||||||
|
* khronos_int8_t signed 8 bit
|
||||||
|
* khronos_uint8_t unsigned 8 bit
|
||||||
|
* khronos_int16_t signed 16 bit
|
||||||
|
* khronos_uint16_t unsigned 16 bit
|
||||||
|
* khronos_int32_t signed 32 bit
|
||||||
|
* khronos_uint32_t unsigned 32 bit
|
||||||
|
* khronos_int64_t signed 64 bit
|
||||||
|
* khronos_uint64_t unsigned 64 bit
|
||||||
|
* khronos_intptr_t signed same number of bits as a pointer
|
||||||
|
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||||
|
* khronos_ssize_t signed size
|
||||||
|
* khronos_usize_t unsigned size
|
||||||
|
* khronos_float_t signed 32 bit floating point
|
||||||
|
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||||
|
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||||
|
* nanoseconds
|
||||||
|
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||||
|
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||||
|
* only be used as a base type when a client API's boolean type is
|
||||||
|
* an enum. Client APIs which use an integer or other type for
|
||||||
|
* booleans cannot use this as the base type for their boolean.
|
||||||
|
*
|
||||||
|
* Tokens defined in khrplatform.h:
|
||||||
|
*
|
||||||
|
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||||
|
*
|
||||||
|
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||||
|
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||||
|
*
|
||||||
|
* Calling convention macros defined in this file:
|
||||||
|
* KHRONOS_APICALL
|
||||||
|
* KHRONOS_APIENTRY
|
||||||
|
* KHRONOS_APIATTRIBUTES
|
||||||
|
*
|
||||||
|
* These may be used in function prototypes as:
|
||||||
|
*
|
||||||
|
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||||
|
* int arg1,
|
||||||
|
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||||
|
# define KHRONOS_STATIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(KHRONOS_STATIC)
|
||||||
|
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||||
|
* header compatible with static linking. */
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# define KHRONOS_APICALL __declspec(dllimport)
|
||||||
|
#elif defined (__SYMBIAN32__)
|
||||||
|
# define KHRONOS_APICALL IMPORT_C
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIENTRY
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the return type of the function and precedes the function
|
||||||
|
* name in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||||
|
/* Win32 but not WinCE */
|
||||||
|
# define KHRONOS_APIENTRY __stdcall
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIATTRIBUTES
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the closing parenthesis of the function prototype arguments.
|
||||||
|
*/
|
||||||
|
#if defined (__ARMCC_2__)
|
||||||
|
#define KHRONOS_APIATTRIBUTES __softfp
|
||||||
|
#else
|
||||||
|
#define KHRONOS_APIATTRIBUTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* basic type definitions
|
||||||
|
*-----------------------------------------------------------------------*/
|
||||||
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <stdint.h>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
/*
|
||||||
|
* To support platform where unsigned long cannot be used interchangeably with
|
||||||
|
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||||
|
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||||
|
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||||
|
* unsigned long long or similar (this results in different C++ name mangling).
|
||||||
|
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||||
|
* platforms where the size of a pointer is larger than the size of long.
|
||||||
|
*/
|
||||||
|
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||||
|
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||||
|
#define KHRONOS_USE_INTPTR_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__VMS ) || defined(__sgi)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <inttypes.h>
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32
|
||||||
|
*/
|
||||||
|
typedef __int32 khronos_int32_t;
|
||||||
|
typedef unsigned __int32 khronos_uint32_t;
|
||||||
|
typedef __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__sun__) || defined(__digital__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sun or Digital
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#if defined(__arch64__) || defined(_LP64)
|
||||||
|
typedef long int khronos_int64_t;
|
||||||
|
typedef unsigned long int khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef long long int khronos_int64_t;
|
||||||
|
typedef unsigned long long int khronos_uint64_t;
|
||||||
|
#endif /* __arch64__ */
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hypothetical platform with no float or int64 support
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 0
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 0
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic fallback
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that are (so far) the same on all platforms
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||||
|
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||||
|
* to be the only LLP64 architecture in current use.
|
||||||
|
*/
|
||||||
|
#ifdef KHRONOS_USE_INTPTR_T
|
||||||
|
typedef intptr_t khronos_intptr_t;
|
||||||
|
typedef uintptr_t khronos_uintptr_t;
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
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_ */
|
2532
external/glad/glad.c
vendored
Executable file
2532
external/glad/glad.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
5169
external/glad/glad/glad.h
vendored
Executable file
5169
external/glad/glad/glad.h
vendored
Executable file
File diff suppressed because it is too large
Load Diff
48
external/glfw-3.3.8/CMake/GenerateMappings.cmake
vendored
Normal file
48
external/glfw-3.3.8/CMake/GenerateMappings.cmake
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Usage:
|
||||||
|
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
|
||||||
|
|
||||||
|
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
|
||||||
|
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
|
||||||
|
set(template_path "${CMAKE_ARGV3}")
|
||||||
|
set(target_path "${CMAKE_ARGV4}")
|
||||||
|
|
||||||
|
if (NOT EXISTS "${template_path}")
|
||||||
|
message(FATAL_ERROR "Failed to find template file ${template_path}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(DOWNLOAD "${source_url}" "${source_path}"
|
||||||
|
STATUS download_status
|
||||||
|
TLS_VERIFY on)
|
||||||
|
|
||||||
|
list(GET download_status 0 status_code)
|
||||||
|
list(GET download_status 1 status_message)
|
||||||
|
|
||||||
|
if (status_code)
|
||||||
|
message(FATAL_ERROR "Failed to download ${source_url}: ${status_message}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(STRINGS "${source_path}" lines)
|
||||||
|
foreach(line ${lines})
|
||||||
|
if (line MATCHES "^[0-9a-fA-F]")
|
||||||
|
if (line MATCHES "platform:Windows")
|
||||||
|
if (GLFW_WIN32_MAPPINGS)
|
||||||
|
set(GLFW_WIN32_MAPPINGS "${GLFW_WIN32_MAPPINGS}\n")
|
||||||
|
endif()
|
||||||
|
set(GLFW_WIN32_MAPPINGS "${GLFW_WIN32_MAPPINGS}\"${line}\",")
|
||||||
|
elseif (line MATCHES "platform:Mac OS X")
|
||||||
|
if (GLFW_COCOA_MAPPINGS)
|
||||||
|
set(GLFW_COCOA_MAPPINGS "${GLFW_COCOA_MAPPINGS}\n")
|
||||||
|
endif()
|
||||||
|
set(GLFW_COCOA_MAPPINGS "${GLFW_COCOA_MAPPINGS}\"${line}\",")
|
||||||
|
elseif (line MATCHES "platform:Linux")
|
||||||
|
if (GLFW_LINUX_MAPPINGS)
|
||||||
|
set(GLFW_LINUX_MAPPINGS "${GLFW_LINUX_MAPPINGS}\n")
|
||||||
|
endif()
|
||||||
|
set(GLFW_LINUX_MAPPINGS "${GLFW_LINUX_MAPPINGS}\"${line}\",")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
configure_file("${template_path}" "${target_path}" @ONLY NEWLINE_STYLE UNIX)
|
||||||
|
file(REMOVE "${source_path}")
|
||||||
|
|
38
external/glfw-3.3.8/CMake/MacOSXBundleInfo.plist.in
vendored
Normal file
38
external/glfw-3.3.8/CMake/MacOSXBundleInfo.plist.in
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleLongVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||||
|
<key>CSResourcesFileMapped</key>
|
||||||
|
<true/>
|
||||||
|
<key>LSRequiresCarbon</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
13
external/glfw-3.3.8/CMake/i686-w64-mingw32-clang.cmake
vendored
Normal file
13
external/glfw-3.3.8/CMake/i686-w64-mingw32-clang.cmake
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Define the environment for cross-compiling with 32-bit MinGW-w64 Clang
|
||||||
|
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||||
|
SET(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
SET(CMAKE_C_COMPILER "i686-w64-mingw32-clang")
|
||||||
|
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-clang++")
|
||||||
|
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)
|
13
external/glfw-3.3.8/CMake/i686-w64-mingw32.cmake
vendored
Normal file
13
external/glfw-3.3.8/CMake/i686-w64-mingw32.cmake
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Define the environment for cross-compiling with 32-bit MinGW-w64 GCC
|
||||||
|
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)
|
17
external/glfw-3.3.8/CMake/modules/FindEpollShim.cmake
vendored
Normal file
17
external/glfw-3.3.8/CMake/modules/FindEpollShim.cmake
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Find EpollShim
|
||||||
|
# Once done, this will define
|
||||||
|
#
|
||||||
|
# EPOLLSHIM_FOUND - System has EpollShim
|
||||||
|
# EPOLLSHIM_INCLUDE_DIRS - The EpollShim include directories
|
||||||
|
# EPOLLSHIM_LIBRARIES - The libraries needed to use EpollShim
|
||||||
|
|
||||||
|
find_path(EPOLLSHIM_INCLUDE_DIRS NAMES sys/epoll.h sys/timerfd.h HINTS /usr/local/include/libepoll-shim)
|
||||||
|
find_library(EPOLLSHIM_LIBRARIES NAMES epoll-shim libepoll-shim HINTS /usr/local/lib)
|
||||||
|
|
||||||
|
if (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
|
||||||
|
set(EPOLLSHIM_FOUND TRUE)
|
||||||
|
endif (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(EpollShim DEFAULT_MSG EPOLLSHIM_LIBRARIES EPOLLSHIM_INCLUDE_DIRS)
|
||||||
|
mark_as_advanced(EPOLLSHIM_INCLUDE_DIRS EPOLLSHIM_LIBRARIES)
|
18
external/glfw-3.3.8/CMake/modules/FindOSMesa.cmake
vendored
Normal file
18
external/glfw-3.3.8/CMake/modules/FindOSMesa.cmake
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Try to find OSMesa on a Unix system
|
||||||
|
#
|
||||||
|
# This will define:
|
||||||
|
#
|
||||||
|
# OSMESA_LIBRARIES - Link these to use OSMesa
|
||||||
|
# OSMESA_INCLUDE_DIR - Include directory for OSMesa
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
|
||||||
|
find_package (PkgConfig)
|
||||||
|
pkg_check_modules (PKG_OSMESA QUIET osmesa)
|
||||||
|
|
||||||
|
set (OSMESA_INCLUDE_DIR ${PKG_OSMESA_INCLUDE_DIRS})
|
||||||
|
set (OSMESA_LIBRARIES ${PKG_OSMESA_LIBRARIES})
|
||||||
|
|
||||||
|
endif ()
|
26
external/glfw-3.3.8/CMake/modules/FindWaylandProtocols.cmake
vendored
Normal file
26
external/glfw-3.3.8/CMake/modules/FindWaylandProtocols.cmake
vendored
Normal file
@ -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})
|
34
external/glfw-3.3.8/CMake/modules/FindXKBCommon.cmake
vendored
Normal file
34
external/glfw-3.3.8/CMake/modules/FindXKBCommon.cmake
vendored
Normal file
@ -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)
|
||||||
|
|
13
external/glfw-3.3.8/CMake/x86_64-w64-mingw32-clang.cmake
vendored
Normal file
13
external/glfw-3.3.8/CMake/x86_64-w64-mingw32-clang.cmake
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Define the environment for cross-compiling with 64-bit MinGW-w64 Clang
|
||||||
|
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||||
|
SET(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-clang")
|
||||||
|
SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-clang++")
|
||||||
|
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)
|
13
external/glfw-3.3.8/CMake/x86_64-w64-mingw32.cmake
vendored
Normal file
13
external/glfw-3.3.8/CMake/x86_64-w64-mingw32.cmake
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Define the environment for cross-compiling with 64-bit MinGW-w64 GCC
|
||||||
|
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)
|
372
external/glfw-3.3.8/CMakeLists.txt
vendored
Normal file
372
external/glfw-3.3.8/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0...3.20 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(GLFW VERSION 3.3.8 LANGUAGES C)
|
||||||
|
|
||||||
|
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||||
|
|
||||||
|
if (POLICY CMP0054)
|
||||||
|
cmake_policy(SET CMP0054 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (POLICY CMP0069)
|
||||||
|
cmake_policy(SET CMP0069 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (POLICY CMP0077)
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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 "Assume the Vulkan loader is linked with the application" OFF)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
|
cmake_dependent_option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF
|
||||||
|
"UNIX" OFF)
|
||||||
|
cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF
|
||||||
|
"WIN32" OFF)
|
||||||
|
cmake_dependent_option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF
|
||||||
|
"UNIX;NOT APPLE" OFF)
|
||||||
|
cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
|
||||||
|
"MSVC" OFF)
|
||||||
|
|
||||||
|
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)
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
# If you absolutely must do this, remove this line and add the Vulkan
|
||||||
|
# loader static library via the CMAKE_SHARED_LINKER_FLAGS
|
||||||
|
message(FATAL_ERROR "You are trying to link the Vulkan loader static library into the GLFW shared library")
|
||||||
|
endif()
|
||||||
|
set(_GLFW_VULKAN_STATIC 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||||
|
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
if (GLFW_BUILD_DOCS)
|
||||||
|
set(DOXYGEN_SKIP_DOT TRUE)
|
||||||
|
find_package(Doxygen)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Apply Microsoft C runtime library option
|
||||||
|
# This is here because it also applies to tests and examples
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (MSVC)
|
||||||
|
if (MSVC90)
|
||||||
|
# Workaround for VS 2008 not shipping with the DirectX 9 SDK
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||||
|
if (NOT DINPUT_H_FOUND)
|
||||||
|
message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
|
||||||
|
endif()
|
||||||
|
# Workaround for VS 2008 not shipping with stdint.h
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (MSVC AND NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
||||||
|
if (CMAKE_VERSION VERSION_LESS 3.15)
|
||||||
|
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()
|
||||||
|
else()
|
||||||
|
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
|
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()
|
||||||
|
|
||||||
|
# Clear flags again to avoid breaking later tests
|
||||||
|
set(CMAKE_REQUIRED_FLAGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Detect and select backend APIs
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (GLFW_USE_WAYLAND)
|
||||||
|
set(_GLFW_WAYLAND 1)
|
||||||
|
message(STATUS "Using Wayland for window creation")
|
||||||
|
elseif (GLFW_USE_OSMESA)
|
||||||
|
set(_GLFW_OSMESA 1)
|
||||||
|
message(STATUS "Using OSMesa for headless context creation")
|
||||||
|
elseif (WIN32)
|
||||||
|
set(_GLFW_WIN32 1)
|
||||||
|
message(STATUS "Using Win32 for window creation")
|
||||||
|
elseif (APPLE)
|
||||||
|
set(_GLFW_COCOA 1)
|
||||||
|
message(STATUS "Using Cocoa for window creation")
|
||||||
|
elseif (UNIX)
|
||||||
|
set(_GLFW_X11 1)
|
||||||
|
message(STATUS "Using X11 for window creation")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "No supported platform was detected")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Find and add Unix math and time libraries
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (UNIX AND NOT APPLE)
|
||||||
|
find_library(RT_LIBRARY rt)
|
||||||
|
mark_as_advanced(RT_LIBRARY)
|
||||||
|
if (RT_LIBRARY)
|
||||||
|
list(APPEND glfw_LIBRARIES "${RT_LIBRARY}")
|
||||||
|
list(APPEND glfw_PKG_LIBS "-lrt")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_library(MATH_LIBRARY m)
|
||||||
|
mark_as_advanced(MATH_LIBRARY)
|
||||||
|
if (MATH_LIBRARY)
|
||||||
|
list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}")
|
||||||
|
list(APPEND glfw_PKG_LIBS "-lm")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_DL_LIBS)
|
||||||
|
list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
|
||||||
|
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Use Win32 for window creation
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (_GLFW_WIN32)
|
||||||
|
|
||||||
|
list(APPEND glfw_PKG_LIBS "-lgdi32")
|
||||||
|
|
||||||
|
if (GLFW_USE_HYBRID_HPG)
|
||||||
|
set(_GLFW_USE_HYBRID_HPG 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Use X11 for window creation
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (_GLFW_X11)
|
||||||
|
|
||||||
|
find_package(X11 REQUIRED)
|
||||||
|
|
||||||
|
list(APPEND glfw_PKG_DEPS "x11")
|
||||||
|
|
||||||
|
# Set up library and include paths
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
|
||||||
|
list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
|
# Check for XRandR (modern resolution switching and gamma control)
|
||||||
|
if (NOT X11_Xrandr_INCLUDE_PATH)
|
||||||
|
message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for Xinerama (legacy multi-monitor support)
|
||||||
|
if (NOT X11_Xinerama_INCLUDE_PATH)
|
||||||
|
message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for Xkb (X keyboard extension)
|
||||||
|
if (NOT X11_Xkb_INCLUDE_PATH)
|
||||||
|
message(FATAL_ERROR "XKB headers not found; install X11 development package")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for Xcursor (cursor creation from RGBA images)
|
||||||
|
if (NOT X11_Xcursor_INCLUDE_PATH)
|
||||||
|
message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for XInput (modern HID input)
|
||||||
|
if (NOT X11_Xi_INCLUDE_PATH)
|
||||||
|
message(FATAL_ERROR "XInput headers not found; install libxi development package")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
|
||||||
|
"${X11_Xinerama_INCLUDE_PATH}"
|
||||||
|
"${X11_Xkb_INCLUDE_PATH}"
|
||||||
|
"${X11_Xcursor_INCLUDE_PATH}"
|
||||||
|
"${X11_Xi_INCLUDE_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Use Wayland for window creation
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (_GLFW_WAYLAND)
|
||||||
|
find_package(ECM REQUIRED NO_MODULE)
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
|
||||||
|
|
||||||
|
find_package(Wayland REQUIRED Client Cursor Egl)
|
||||||
|
find_package(WaylandScanner REQUIRED)
|
||||||
|
find_package(WaylandProtocols 1.15 REQUIRED)
|
||||||
|
|
||||||
|
list(APPEND glfw_PKG_DEPS "wayland-client")
|
||||||
|
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
|
||||||
|
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
|
find_package(XKBCommon REQUIRED)
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
include(CheckIncludeFiles)
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
|
||||||
|
|
||||||
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
find_package(EpollShim)
|
||||||
|
if (EPOLLSHIM_FOUND)
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${EPOLLSHIM_INCLUDE_DIRS}")
|
||||||
|
list(APPEND glfw_LIBRARIES "${EPOLLSHIM_LIBRARIES}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Use OSMesa for offscreen context creation
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (_GLFW_OSMESA)
|
||||||
|
find_package(OSMesa REQUIRED)
|
||||||
|
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Use Cocoa for window creation and NSOpenGL for context creation
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (_GLFW_COCOA)
|
||||||
|
|
||||||
|
list(APPEND glfw_LIBRARIES
|
||||||
|
"-framework Cocoa"
|
||||||
|
"-framework IOKit"
|
||||||
|
"-framework CoreFoundation")
|
||||||
|
|
||||||
|
set(glfw_PKG_DEPS "")
|
||||||
|
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Add the Vulkan loader as a dependency if necessary
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (GLFW_VULKAN_STATIC)
|
||||||
|
list(APPEND glfw_PKG_DEPS "vulkan")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Export GLFW library dependencies
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
foreach(arg ${glfw_PKG_DEPS})
|
||||||
|
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}")
|
||||||
|
endforeach()
|
||||||
|
foreach(arg ${glfw_PKG_LIBS})
|
||||||
|
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Create generated files
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/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}
|
||||||
|
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)
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Install files other than the library
|
||||||
|
# The library is installed by src/CMakeLists.txt
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if (GLFW_INSTALL)
|
||||||
|
install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
|
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 "${CMAKE_INSTALL_LIBDIR}/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")
|
||||||
|
set_target_properties(uninstall PROPERTIES FOLDER "GLFW3")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
29
external/glfw-3.3.8/cmake_uninstall.cmake.in
vendored
Normal file
29
external/glfw-3.3.8/cmake_uninstall.cmake.in
vendored
Normal file
@ -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()
|
||||||
|
|
230
external/glfw-3.3.8/deps/getopt.c
vendored
Normal file
230
external/glfw-3.3.8/deps/getopt.c
vendored
Normal file
@ -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 <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
57
external/glfw-3.3.8/deps/getopt.h
vendored
Normal file
57
external/glfw-3.3.8/deps/getopt.h
vendored
Normal file
@ -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
|
3840
external/glfw-3.3.8/deps/glad/gl.h
vendored
Normal file
3840
external/glfw-3.3.8/deps/glad/gl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
282
external/glfw-3.3.8/deps/glad/khrplatform.h
vendored
Normal file
282
external/glfw-3.3.8/deps/glad/khrplatform.h
vendored
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
#ifndef __khrplatform_h_
|
||||||
|
#define __khrplatform_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Khronos platform-specific types and definitions.
|
||||||
|
*
|
||||||
|
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||||
|
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||||
|
* The last semantic modification to khrplatform.h was at commit ID:
|
||||||
|
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||||
|
*
|
||||||
|
* Adopters may modify this file to suit their platform. Adopters are
|
||||||
|
* encouraged to submit platform specific modifications to the Khronos
|
||||||
|
* group so that they can be included in future versions of this file.
|
||||||
|
* Please submit changes by filing pull requests or issues on
|
||||||
|
* the EGL Registry repository linked above.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* See the Implementer's Guidelines for information about where this file
|
||||||
|
* should be located on your system and for more details of its use:
|
||||||
|
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||||
|
*
|
||||||
|
* This file should be included as
|
||||||
|
* #include <KHR/khrplatform.h>
|
||||||
|
* by Khronos client API header files that use its types and defines.
|
||||||
|
*
|
||||||
|
* The types in khrplatform.h should only be used to define API-specific types.
|
||||||
|
*
|
||||||
|
* Types defined in khrplatform.h:
|
||||||
|
* khronos_int8_t signed 8 bit
|
||||||
|
* khronos_uint8_t unsigned 8 bit
|
||||||
|
* khronos_int16_t signed 16 bit
|
||||||
|
* khronos_uint16_t unsigned 16 bit
|
||||||
|
* khronos_int32_t signed 32 bit
|
||||||
|
* khronos_uint32_t unsigned 32 bit
|
||||||
|
* khronos_int64_t signed 64 bit
|
||||||
|
* khronos_uint64_t unsigned 64 bit
|
||||||
|
* khronos_intptr_t signed same number of bits as a pointer
|
||||||
|
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||||
|
* khronos_ssize_t signed size
|
||||||
|
* khronos_usize_t unsigned size
|
||||||
|
* khronos_float_t signed 32 bit floating point
|
||||||
|
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||||
|
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||||
|
* nanoseconds
|
||||||
|
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||||
|
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||||
|
* only be used as a base type when a client API's boolean type is
|
||||||
|
* an enum. Client APIs which use an integer or other type for
|
||||||
|
* booleans cannot use this as the base type for their boolean.
|
||||||
|
*
|
||||||
|
* Tokens defined in khrplatform.h:
|
||||||
|
*
|
||||||
|
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||||
|
*
|
||||||
|
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||||
|
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||||
|
*
|
||||||
|
* Calling convention macros defined in this file:
|
||||||
|
* KHRONOS_APICALL
|
||||||
|
* KHRONOS_APIENTRY
|
||||||
|
* KHRONOS_APIATTRIBUTES
|
||||||
|
*
|
||||||
|
* These may be used in function prototypes as:
|
||||||
|
*
|
||||||
|
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||||
|
* int arg1,
|
||||||
|
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
# define KHRONOS_APICALL __declspec(dllimport)
|
||||||
|
#elif defined (__SYMBIAN32__)
|
||||||
|
# define KHRONOS_APICALL IMPORT_C
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIENTRY
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the return type of the function and precedes the function
|
||||||
|
* name in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||||
|
/* Win32 but not WinCE */
|
||||||
|
# define KHRONOS_APIENTRY __stdcall
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIATTRIBUTES
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the closing parenthesis of the function prototype arguments.
|
||||||
|
*/
|
||||||
|
#if defined (__ARMCC_2__)
|
||||||
|
#define KHRONOS_APIATTRIBUTES __softfp
|
||||||
|
#else
|
||||||
|
#define KHRONOS_APIATTRIBUTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* basic type definitions
|
||||||
|
*-----------------------------------------------------------------------*/
|
||||||
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <stdint.h>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__VMS ) || defined(__sgi)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <inttypes.h>
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32
|
||||||
|
*/
|
||||||
|
typedef __int32 khronos_int32_t;
|
||||||
|
typedef unsigned __int32 khronos_uint32_t;
|
||||||
|
typedef __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__sun__) || defined(__digital__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sun or Digital
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#if defined(__arch64__) || defined(_LP64)
|
||||||
|
typedef long int khronos_int64_t;
|
||||||
|
typedef unsigned long int khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef long long int khronos_int64_t;
|
||||||
|
typedef unsigned long long int khronos_uint64_t;
|
||||||
|
#endif /* __arch64__ */
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hypothetical platform with no float or int64 support
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 0
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 0
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic fallback
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that are (so far) the same on all platforms
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||||
|
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||||
|
* to be the only LLP64 architecture in current use.
|
||||||
|
*/
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
typedef unsigned long int khronos_usize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_FLOAT
|
||||||
|
/*
|
||||||
|
* Float type
|
||||||
|
*/
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_INT64
|
||||||
|
/* Time types
|
||||||
|
*
|
||||||
|
* These types can be used to represent a time interval in nanoseconds or
|
||||||
|
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||||
|
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||||
|
* time the system booted). The Unadjusted System Time is an unsigned
|
||||||
|
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||||
|
* may be either signed or unsigned.
|
||||||
|
*/
|
||||||
|
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||||
|
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy value used to pad enum types to 32 bits.
|
||||||
|
*/
|
||||||
|
#ifndef KHRONOS_MAX_ENUM
|
||||||
|
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerated boolean type
|
||||||
|
*
|
||||||
|
* Values other than zero should be considered to be true. Therefore
|
||||||
|
* comparisons should not be made against KHRONOS_TRUE.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
KHRONOS_FALSE = 0,
|
||||||
|
KHRONOS_TRUE = 1,
|
||||||
|
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||||
|
} khronos_boolean_enum_t;
|
||||||
|
|
||||||
|
#endif /* __khrplatform_h_ */
|
84
external/glfw-3.3.8/deps/glad/vk_platform.h
vendored
Normal file
84
external/glfw-3.3.8/deps/glad/vk_platform.h
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* */
|
||||||
|
/* File: vk_platform.h */
|
||||||
|
/* */
|
||||||
|
/*
|
||||||
|
** Copyright 2014-2022 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef VK_PLATFORM_H_
|
||||||
|
#define VK_PLATFORM_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/*
|
||||||
|
***************************************************************************************************
|
||||||
|
* Platform-specific directives and type declarations
|
||||||
|
***************************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Platform-specific calling convention macros.
|
||||||
|
*
|
||||||
|
* Platforms should define these so that Vulkan clients call Vulkan commands
|
||||||
|
* with the same calling conventions that the Vulkan implementation expects.
|
||||||
|
*
|
||||||
|
* VKAPI_ATTR - Placed before the return type in function declarations.
|
||||||
|
* Useful for C++11 and GCC/Clang-style function attribute syntax.
|
||||||
|
* VKAPI_CALL - Placed after the return type in function declarations.
|
||||||
|
* Useful for MSVC-style calling convention syntax.
|
||||||
|
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
|
||||||
|
*
|
||||||
|
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
|
||||||
|
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32)
|
||||||
|
/* On Windows, Vulkan commands use the stdcall convention */
|
||||||
|
#define VKAPI_ATTR
|
||||||
|
#define VKAPI_CALL __stdcall
|
||||||
|
#define VKAPI_PTR VKAPI_CALL
|
||||||
|
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||||
|
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
|
||||||
|
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
|
||||||
|
/* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
|
||||||
|
/* calling convention, i.e. float parameters are passed in registers. This */
|
||||||
|
/* is true even if the rest of the application passes floats on the stack, */
|
||||||
|
/* as it does by default when compiling for the armeabi-v7a NDK ABI. */
|
||||||
|
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
|
||||||
|
#define VKAPI_CALL
|
||||||
|
#define VKAPI_PTR VKAPI_ATTR
|
||||||
|
#else
|
||||||
|
/* On other platforms, use the default calling convention */
|
||||||
|
#define VKAPI_ATTR
|
||||||
|
#define VKAPI_CALL
|
||||||
|
#define VKAPI_PTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(VK_NO_STDDEF_H)
|
||||||
|
#include <stddef.h>
|
||||||
|
#endif /* !defined(VK_NO_STDDEF_H) */
|
||||||
|
|
||||||
|
#if !defined(VK_NO_STDINT_H)
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||||
|
typedef signed __int8 int8_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef signed __int16 int16_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef signed __int32 int32_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
typedef signed __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
#endif /* !defined(VK_NO_STDINT_H) */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif
|
5508
external/glfw-3.3.8/deps/glad/vulkan.h
vendored
Normal file
5508
external/glfw-3.3.8/deps/glad/vulkan.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1791
external/glfw-3.3.8/deps/glad_gl.c
vendored
Normal file
1791
external/glfw-3.3.8/deps/glad_gl.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
733
external/glfw-3.3.8/deps/glad_vulkan.c
vendored
Normal file
733
external/glfw-3.3.8/deps/glad_vulkan.c
vendored
Normal file
@ -0,0 +1,733 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <glad/vulkan.h>
|
||||||
|
|
||||||
|
#ifndef GLAD_IMPL_UTIL_C_
|
||||||
|
#define GLAD_IMPL_UTIL_C_
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
|
||||||
|
#else
|
||||||
|
#define GLAD_IMPL_UTIL_SSCANF sscanf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GLAD_IMPL_UTIL_C_ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int GLAD_VK_VERSION_1_0 = 0;
|
||||||
|
int GLAD_VK_VERSION_1_1 = 0;
|
||||||
|
int GLAD_VK_VERSION_1_2 = 0;
|
||||||
|
int GLAD_VK_VERSION_1_3 = 0;
|
||||||
|
int GLAD_VK_EXT_debug_report = 0;
|
||||||
|
int GLAD_VK_KHR_portability_enumeration = 0;
|
||||||
|
int GLAD_VK_KHR_surface = 0;
|
||||||
|
int GLAD_VK_KHR_swapchain = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR = NULL;
|
||||||
|
PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR = NULL;
|
||||||
|
PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers = NULL;
|
||||||
|
PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets = NULL;
|
||||||
|
PFN_vkAllocateMemory glad_vkAllocateMemory = NULL;
|
||||||
|
PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer = NULL;
|
||||||
|
PFN_vkBindBufferMemory glad_vkBindBufferMemory = NULL;
|
||||||
|
PFN_vkBindBufferMemory2 glad_vkBindBufferMemory2 = NULL;
|
||||||
|
PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
|
||||||
|
PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL;
|
||||||
|
PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
|
||||||
|
PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
|
||||||
|
PFN_vkCmdBeginRenderPass2 glad_vkCmdBeginRenderPass2 = NULL;
|
||||||
|
PFN_vkCmdBeginRendering glad_vkCmdBeginRendering = NULL;
|
||||||
|
PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
|
||||||
|
PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
|
||||||
|
PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
|
||||||
|
PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
|
||||||
|
PFN_vkCmdBindVertexBuffers2 glad_vkCmdBindVertexBuffers2 = NULL;
|
||||||
|
PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
|
||||||
|
PFN_vkCmdBlitImage2 glad_vkCmdBlitImage2 = NULL;
|
||||||
|
PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
|
||||||
|
PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
|
||||||
|
PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
|
||||||
|
PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
|
||||||
|
PFN_vkCmdCopyBuffer2 glad_vkCmdCopyBuffer2 = NULL;
|
||||||
|
PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
|
||||||
|
PFN_vkCmdCopyBufferToImage2 glad_vkCmdCopyBufferToImage2 = NULL;
|
||||||
|
PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
|
||||||
|
PFN_vkCmdCopyImage2 glad_vkCmdCopyImage2 = NULL;
|
||||||
|
PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
|
||||||
|
PFN_vkCmdCopyImageToBuffer2 glad_vkCmdCopyImageToBuffer2 = NULL;
|
||||||
|
PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
|
||||||
|
PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
|
||||||
|
PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL;
|
||||||
|
PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
|
||||||
|
PFN_vkCmdDraw glad_vkCmdDraw = NULL;
|
||||||
|
PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
|
||||||
|
PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
|
||||||
|
PFN_vkCmdDrawIndexedIndirectCount glad_vkCmdDrawIndexedIndirectCount = NULL;
|
||||||
|
PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
|
||||||
|
PFN_vkCmdDrawIndirectCount glad_vkCmdDrawIndirectCount = NULL;
|
||||||
|
PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
|
||||||
|
PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
|
||||||
|
PFN_vkCmdEndRenderPass2 glad_vkCmdEndRenderPass2 = NULL;
|
||||||
|
PFN_vkCmdEndRendering glad_vkCmdEndRendering = NULL;
|
||||||
|
PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
|
||||||
|
PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
|
||||||
|
PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
|
||||||
|
PFN_vkCmdNextSubpass2 glad_vkCmdNextSubpass2 = NULL;
|
||||||
|
PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
|
||||||
|
PFN_vkCmdPipelineBarrier2 glad_vkCmdPipelineBarrier2 = NULL;
|
||||||
|
PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
|
||||||
|
PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
|
||||||
|
PFN_vkCmdResetEvent2 glad_vkCmdResetEvent2 = NULL;
|
||||||
|
PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
|
||||||
|
PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
|
||||||
|
PFN_vkCmdResolveImage2 glad_vkCmdResolveImage2 = NULL;
|
||||||
|
PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
|
||||||
|
PFN_vkCmdSetCullMode glad_vkCmdSetCullMode = NULL;
|
||||||
|
PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
|
||||||
|
PFN_vkCmdSetDepthBiasEnable glad_vkCmdSetDepthBiasEnable = NULL;
|
||||||
|
PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL;
|
||||||
|
PFN_vkCmdSetDepthBoundsTestEnable glad_vkCmdSetDepthBoundsTestEnable = NULL;
|
||||||
|
PFN_vkCmdSetDepthCompareOp glad_vkCmdSetDepthCompareOp = NULL;
|
||||||
|
PFN_vkCmdSetDepthTestEnable glad_vkCmdSetDepthTestEnable = NULL;
|
||||||
|
PFN_vkCmdSetDepthWriteEnable glad_vkCmdSetDepthWriteEnable = NULL;
|
||||||
|
PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL;
|
||||||
|
PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
|
||||||
|
PFN_vkCmdSetEvent2 glad_vkCmdSetEvent2 = NULL;
|
||||||
|
PFN_vkCmdSetFrontFace glad_vkCmdSetFrontFace = NULL;
|
||||||
|
PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL;
|
||||||
|
PFN_vkCmdSetPrimitiveRestartEnable glad_vkCmdSetPrimitiveRestartEnable = NULL;
|
||||||
|
PFN_vkCmdSetPrimitiveTopology glad_vkCmdSetPrimitiveTopology = NULL;
|
||||||
|
PFN_vkCmdSetRasterizerDiscardEnable glad_vkCmdSetRasterizerDiscardEnable = NULL;
|
||||||
|
PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL;
|
||||||
|
PFN_vkCmdSetScissorWithCount glad_vkCmdSetScissorWithCount = NULL;
|
||||||
|
PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
|
||||||
|
PFN_vkCmdSetStencilOp glad_vkCmdSetStencilOp = NULL;
|
||||||
|
PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
|
||||||
|
PFN_vkCmdSetStencilTestEnable glad_vkCmdSetStencilTestEnable = NULL;
|
||||||
|
PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
|
||||||
|
PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
|
||||||
|
PFN_vkCmdSetViewportWithCount glad_vkCmdSetViewportWithCount = NULL;
|
||||||
|
PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
|
||||||
|
PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
|
||||||
|
PFN_vkCmdWaitEvents2 glad_vkCmdWaitEvents2 = NULL;
|
||||||
|
PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
|
||||||
|
PFN_vkCmdWriteTimestamp2 glad_vkCmdWriteTimestamp2 = NULL;
|
||||||
|
PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
|
||||||
|
PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
|
||||||
|
PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
|
||||||
|
PFN_vkCreateComputePipelines glad_vkCreateComputePipelines = NULL;
|
||||||
|
PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT = NULL;
|
||||||
|
PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool = NULL;
|
||||||
|
PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout = NULL;
|
||||||
|
PFN_vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate = NULL;
|
||||||
|
PFN_vkCreateDevice glad_vkCreateDevice = NULL;
|
||||||
|
PFN_vkCreateEvent glad_vkCreateEvent = NULL;
|
||||||
|
PFN_vkCreateFence glad_vkCreateFence = NULL;
|
||||||
|
PFN_vkCreateFramebuffer glad_vkCreateFramebuffer = NULL;
|
||||||
|
PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines = NULL;
|
||||||
|
PFN_vkCreateImage glad_vkCreateImage = NULL;
|
||||||
|
PFN_vkCreateImageView glad_vkCreateImageView = NULL;
|
||||||
|
PFN_vkCreateInstance glad_vkCreateInstance = NULL;
|
||||||
|
PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
|
||||||
|
PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
|
||||||
|
PFN_vkCreatePrivateDataSlot glad_vkCreatePrivateDataSlot = NULL;
|
||||||
|
PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
|
||||||
|
PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
|
||||||
|
PFN_vkCreateRenderPass2 glad_vkCreateRenderPass2 = NULL;
|
||||||
|
PFN_vkCreateSampler glad_vkCreateSampler = NULL;
|
||||||
|
PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL;
|
||||||
|
PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
|
||||||
|
PFN_vkCreateShaderModule glad_vkCreateShaderModule = NULL;
|
||||||
|
PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR = NULL;
|
||||||
|
PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT = NULL;
|
||||||
|
PFN_vkDestroyBuffer glad_vkDestroyBuffer = NULL;
|
||||||
|
PFN_vkDestroyBufferView glad_vkDestroyBufferView = NULL;
|
||||||
|
PFN_vkDestroyCommandPool glad_vkDestroyCommandPool = NULL;
|
||||||
|
PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT = NULL;
|
||||||
|
PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool = NULL;
|
||||||
|
PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout = NULL;
|
||||||
|
PFN_vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate = NULL;
|
||||||
|
PFN_vkDestroyDevice glad_vkDestroyDevice = NULL;
|
||||||
|
PFN_vkDestroyEvent glad_vkDestroyEvent = NULL;
|
||||||
|
PFN_vkDestroyFence glad_vkDestroyFence = NULL;
|
||||||
|
PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer = NULL;
|
||||||
|
PFN_vkDestroyImage glad_vkDestroyImage = NULL;
|
||||||
|
PFN_vkDestroyImageView glad_vkDestroyImageView = NULL;
|
||||||
|
PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
|
||||||
|
PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
|
||||||
|
PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
|
||||||
|
PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
|
||||||
|
PFN_vkDestroyPrivateDataSlot glad_vkDestroyPrivateDataSlot = NULL;
|
||||||
|
PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
|
||||||
|
PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
|
||||||
|
PFN_vkDestroySampler glad_vkDestroySampler = NULL;
|
||||||
|
PFN_vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion = NULL;
|
||||||
|
PFN_vkDestroySemaphore glad_vkDestroySemaphore = NULL;
|
||||||
|
PFN_vkDestroyShaderModule glad_vkDestroyShaderModule = NULL;
|
||||||
|
PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR = NULL;
|
||||||
|
PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR = NULL;
|
||||||
|
PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle = NULL;
|
||||||
|
PFN_vkEndCommandBuffer glad_vkEndCommandBuffer = NULL;
|
||||||
|
PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties = NULL;
|
||||||
|
PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties = NULL;
|
||||||
|
PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties = NULL;
|
||||||
|
PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties = NULL;
|
||||||
|
PFN_vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion = NULL;
|
||||||
|
PFN_vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups = NULL;
|
||||||
|
PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices = NULL;
|
||||||
|
PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
|
||||||
|
PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
|
||||||
|
PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
|
||||||
|
PFN_vkFreeMemory glad_vkFreeMemory = NULL;
|
||||||
|
PFN_vkGetBufferDeviceAddress glad_vkGetBufferDeviceAddress = NULL;
|
||||||
|
PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
|
||||||
|
PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL;
|
||||||
|
PFN_vkGetBufferOpaqueCaptureAddress glad_vkGetBufferOpaqueCaptureAddress = NULL;
|
||||||
|
PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL;
|
||||||
|
PFN_vkGetDeviceBufferMemoryRequirements glad_vkGetDeviceBufferMemoryRequirements = NULL;
|
||||||
|
PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL;
|
||||||
|
PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
|
||||||
|
PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
|
||||||
|
PFN_vkGetDeviceImageMemoryRequirements glad_vkGetDeviceImageMemoryRequirements = NULL;
|
||||||
|
PFN_vkGetDeviceImageSparseMemoryRequirements glad_vkGetDeviceImageSparseMemoryRequirements = NULL;
|
||||||
|
PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
|
||||||
|
PFN_vkGetDeviceMemoryOpaqueCaptureAddress glad_vkGetDeviceMemoryOpaqueCaptureAddress = NULL;
|
||||||
|
PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
|
||||||
|
PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
|
||||||
|
PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL;
|
||||||
|
PFN_vkGetEventStatus glad_vkGetEventStatus = NULL;
|
||||||
|
PFN_vkGetFenceStatus glad_vkGetFenceStatus = NULL;
|
||||||
|
PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements = NULL;
|
||||||
|
PFN_vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2 = NULL;
|
||||||
|
PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements = NULL;
|
||||||
|
PFN_vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2 = NULL;
|
||||||
|
PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout = NULL;
|
||||||
|
PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
|
||||||
|
PFN_vkGetPhysicalDeviceToolProperties glad_vkGetPhysicalDeviceToolProperties = NULL;
|
||||||
|
PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
|
||||||
|
PFN_vkGetPrivateData glad_vkGetPrivateData = NULL;
|
||||||
|
PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
|
||||||
|
PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
|
||||||
|
PFN_vkGetSemaphoreCounterValue glad_vkGetSemaphoreCounterValue = NULL;
|
||||||
|
PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
|
||||||
|
PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
|
||||||
|
PFN_vkMapMemory glad_vkMapMemory = NULL;
|
||||||
|
PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
|
||||||
|
PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
|
||||||
|
PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
|
||||||
|
PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
|
||||||
|
PFN_vkQueueSubmit2 glad_vkQueueSubmit2 = NULL;
|
||||||
|
PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
|
||||||
|
PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
|
||||||
|
PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
|
||||||
|
PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
|
||||||
|
PFN_vkResetEvent glad_vkResetEvent = NULL;
|
||||||
|
PFN_vkResetFences glad_vkResetFences = NULL;
|
||||||
|
PFN_vkResetQueryPool glad_vkResetQueryPool = NULL;
|
||||||
|
PFN_vkSetEvent glad_vkSetEvent = NULL;
|
||||||
|
PFN_vkSetPrivateData glad_vkSetPrivateData = NULL;
|
||||||
|
PFN_vkSignalSemaphore glad_vkSignalSemaphore = NULL;
|
||||||
|
PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL;
|
||||||
|
PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
|
||||||
|
PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL;
|
||||||
|
PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
|
||||||
|
PFN_vkWaitForFences glad_vkWaitForFences = NULL;
|
||||||
|
PFN_vkWaitSemaphores glad_vkWaitSemaphores = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_VERSION_1_0) return;
|
||||||
|
glad_vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load(userptr, "vkAllocateCommandBuffers");
|
||||||
|
glad_vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load(userptr, "vkAllocateDescriptorSets");
|
||||||
|
glad_vkAllocateMemory = (PFN_vkAllocateMemory) load(userptr, "vkAllocateMemory");
|
||||||
|
glad_vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load(userptr, "vkBeginCommandBuffer");
|
||||||
|
glad_vkBindBufferMemory = (PFN_vkBindBufferMemory) load(userptr, "vkBindBufferMemory");
|
||||||
|
glad_vkBindImageMemory = (PFN_vkBindImageMemory) load(userptr, "vkBindImageMemory");
|
||||||
|
glad_vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load(userptr, "vkCmdBeginQuery");
|
||||||
|
glad_vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load(userptr, "vkCmdBeginRenderPass");
|
||||||
|
glad_vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load(userptr, "vkCmdBindDescriptorSets");
|
||||||
|
glad_vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load(userptr, "vkCmdBindIndexBuffer");
|
||||||
|
glad_vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load(userptr, "vkCmdBindPipeline");
|
||||||
|
glad_vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load(userptr, "vkCmdBindVertexBuffers");
|
||||||
|
glad_vkCmdBlitImage = (PFN_vkCmdBlitImage) load(userptr, "vkCmdBlitImage");
|
||||||
|
glad_vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load(userptr, "vkCmdClearAttachments");
|
||||||
|
glad_vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load(userptr, "vkCmdClearColorImage");
|
||||||
|
glad_vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load(userptr, "vkCmdClearDepthStencilImage");
|
||||||
|
glad_vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load(userptr, "vkCmdCopyBuffer");
|
||||||
|
glad_vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load(userptr, "vkCmdCopyBufferToImage");
|
||||||
|
glad_vkCmdCopyImage = (PFN_vkCmdCopyImage) load(userptr, "vkCmdCopyImage");
|
||||||
|
glad_vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load(userptr, "vkCmdCopyImageToBuffer");
|
||||||
|
glad_vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load(userptr, "vkCmdCopyQueryPoolResults");
|
||||||
|
glad_vkCmdDispatch = (PFN_vkCmdDispatch) load(userptr, "vkCmdDispatch");
|
||||||
|
glad_vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load(userptr, "vkCmdDispatchIndirect");
|
||||||
|
glad_vkCmdDraw = (PFN_vkCmdDraw) load(userptr, "vkCmdDraw");
|
||||||
|
glad_vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load(userptr, "vkCmdDrawIndexed");
|
||||||
|
glad_vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load(userptr, "vkCmdDrawIndexedIndirect");
|
||||||
|
glad_vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load(userptr, "vkCmdDrawIndirect");
|
||||||
|
glad_vkCmdEndQuery = (PFN_vkCmdEndQuery) load(userptr, "vkCmdEndQuery");
|
||||||
|
glad_vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load(userptr, "vkCmdEndRenderPass");
|
||||||
|
glad_vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load(userptr, "vkCmdExecuteCommands");
|
||||||
|
glad_vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load(userptr, "vkCmdFillBuffer");
|
||||||
|
glad_vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load(userptr, "vkCmdNextSubpass");
|
||||||
|
glad_vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load(userptr, "vkCmdPipelineBarrier");
|
||||||
|
glad_vkCmdPushConstants = (PFN_vkCmdPushConstants) load(userptr, "vkCmdPushConstants");
|
||||||
|
glad_vkCmdResetEvent = (PFN_vkCmdResetEvent) load(userptr, "vkCmdResetEvent");
|
||||||
|
glad_vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load(userptr, "vkCmdResetQueryPool");
|
||||||
|
glad_vkCmdResolveImage = (PFN_vkCmdResolveImage) load(userptr, "vkCmdResolveImage");
|
||||||
|
glad_vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load(userptr, "vkCmdSetBlendConstants");
|
||||||
|
glad_vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load(userptr, "vkCmdSetDepthBias");
|
||||||
|
glad_vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load(userptr, "vkCmdSetDepthBounds");
|
||||||
|
glad_vkCmdSetEvent = (PFN_vkCmdSetEvent) load(userptr, "vkCmdSetEvent");
|
||||||
|
glad_vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load(userptr, "vkCmdSetLineWidth");
|
||||||
|
glad_vkCmdSetScissor = (PFN_vkCmdSetScissor) load(userptr, "vkCmdSetScissor");
|
||||||
|
glad_vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load(userptr, "vkCmdSetStencilCompareMask");
|
||||||
|
glad_vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load(userptr, "vkCmdSetStencilReference");
|
||||||
|
glad_vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load(userptr, "vkCmdSetStencilWriteMask");
|
||||||
|
glad_vkCmdSetViewport = (PFN_vkCmdSetViewport) load(userptr, "vkCmdSetViewport");
|
||||||
|
glad_vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load(userptr, "vkCmdUpdateBuffer");
|
||||||
|
glad_vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load(userptr, "vkCmdWaitEvents");
|
||||||
|
glad_vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load(userptr, "vkCmdWriteTimestamp");
|
||||||
|
glad_vkCreateBuffer = (PFN_vkCreateBuffer) load(userptr, "vkCreateBuffer");
|
||||||
|
glad_vkCreateBufferView = (PFN_vkCreateBufferView) load(userptr, "vkCreateBufferView");
|
||||||
|
glad_vkCreateCommandPool = (PFN_vkCreateCommandPool) load(userptr, "vkCreateCommandPool");
|
||||||
|
glad_vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load(userptr, "vkCreateComputePipelines");
|
||||||
|
glad_vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load(userptr, "vkCreateDescriptorPool");
|
||||||
|
glad_vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load(userptr, "vkCreateDescriptorSetLayout");
|
||||||
|
glad_vkCreateDevice = (PFN_vkCreateDevice) load(userptr, "vkCreateDevice");
|
||||||
|
glad_vkCreateEvent = (PFN_vkCreateEvent) load(userptr, "vkCreateEvent");
|
||||||
|
glad_vkCreateFence = (PFN_vkCreateFence) load(userptr, "vkCreateFence");
|
||||||
|
glad_vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load(userptr, "vkCreateFramebuffer");
|
||||||
|
glad_vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load(userptr, "vkCreateGraphicsPipelines");
|
||||||
|
glad_vkCreateImage = (PFN_vkCreateImage) load(userptr, "vkCreateImage");
|
||||||
|
glad_vkCreateImageView = (PFN_vkCreateImageView) load(userptr, "vkCreateImageView");
|
||||||
|
glad_vkCreateInstance = (PFN_vkCreateInstance) load(userptr, "vkCreateInstance");
|
||||||
|
glad_vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load(userptr, "vkCreatePipelineCache");
|
||||||
|
glad_vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load(userptr, "vkCreatePipelineLayout");
|
||||||
|
glad_vkCreateQueryPool = (PFN_vkCreateQueryPool) load(userptr, "vkCreateQueryPool");
|
||||||
|
glad_vkCreateRenderPass = (PFN_vkCreateRenderPass) load(userptr, "vkCreateRenderPass");
|
||||||
|
glad_vkCreateSampler = (PFN_vkCreateSampler) load(userptr, "vkCreateSampler");
|
||||||
|
glad_vkCreateSemaphore = (PFN_vkCreateSemaphore) load(userptr, "vkCreateSemaphore");
|
||||||
|
glad_vkCreateShaderModule = (PFN_vkCreateShaderModule) load(userptr, "vkCreateShaderModule");
|
||||||
|
glad_vkDestroyBuffer = (PFN_vkDestroyBuffer) load(userptr, "vkDestroyBuffer");
|
||||||
|
glad_vkDestroyBufferView = (PFN_vkDestroyBufferView) load(userptr, "vkDestroyBufferView");
|
||||||
|
glad_vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load(userptr, "vkDestroyCommandPool");
|
||||||
|
glad_vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load(userptr, "vkDestroyDescriptorPool");
|
||||||
|
glad_vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load(userptr, "vkDestroyDescriptorSetLayout");
|
||||||
|
glad_vkDestroyDevice = (PFN_vkDestroyDevice) load(userptr, "vkDestroyDevice");
|
||||||
|
glad_vkDestroyEvent = (PFN_vkDestroyEvent) load(userptr, "vkDestroyEvent");
|
||||||
|
glad_vkDestroyFence = (PFN_vkDestroyFence) load(userptr, "vkDestroyFence");
|
||||||
|
glad_vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load(userptr, "vkDestroyFramebuffer");
|
||||||
|
glad_vkDestroyImage = (PFN_vkDestroyImage) load(userptr, "vkDestroyImage");
|
||||||
|
glad_vkDestroyImageView = (PFN_vkDestroyImageView) load(userptr, "vkDestroyImageView");
|
||||||
|
glad_vkDestroyInstance = (PFN_vkDestroyInstance) load(userptr, "vkDestroyInstance");
|
||||||
|
glad_vkDestroyPipeline = (PFN_vkDestroyPipeline) load(userptr, "vkDestroyPipeline");
|
||||||
|
glad_vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load(userptr, "vkDestroyPipelineCache");
|
||||||
|
glad_vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load(userptr, "vkDestroyPipelineLayout");
|
||||||
|
glad_vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load(userptr, "vkDestroyQueryPool");
|
||||||
|
glad_vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load(userptr, "vkDestroyRenderPass");
|
||||||
|
glad_vkDestroySampler = (PFN_vkDestroySampler) load(userptr, "vkDestroySampler");
|
||||||
|
glad_vkDestroySemaphore = (PFN_vkDestroySemaphore) load(userptr, "vkDestroySemaphore");
|
||||||
|
glad_vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load(userptr, "vkDestroyShaderModule");
|
||||||
|
glad_vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load(userptr, "vkDeviceWaitIdle");
|
||||||
|
glad_vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load(userptr, "vkEndCommandBuffer");
|
||||||
|
glad_vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load(userptr, "vkEnumerateDeviceExtensionProperties");
|
||||||
|
glad_vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load(userptr, "vkEnumerateDeviceLayerProperties");
|
||||||
|
glad_vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load(userptr, "vkEnumerateInstanceExtensionProperties");
|
||||||
|
glad_vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load(userptr, "vkEnumerateInstanceLayerProperties");
|
||||||
|
glad_vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load(userptr, "vkEnumeratePhysicalDevices");
|
||||||
|
glad_vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load(userptr, "vkFlushMappedMemoryRanges");
|
||||||
|
glad_vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load(userptr, "vkFreeCommandBuffers");
|
||||||
|
glad_vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load(userptr, "vkFreeDescriptorSets");
|
||||||
|
glad_vkFreeMemory = (PFN_vkFreeMemory) load(userptr, "vkFreeMemory");
|
||||||
|
glad_vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load(userptr, "vkGetBufferMemoryRequirements");
|
||||||
|
glad_vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load(userptr, "vkGetDeviceMemoryCommitment");
|
||||||
|
glad_vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load(userptr, "vkGetDeviceProcAddr");
|
||||||
|
glad_vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load(userptr, "vkGetDeviceQueue");
|
||||||
|
glad_vkGetEventStatus = (PFN_vkGetEventStatus) load(userptr, "vkGetEventStatus");
|
||||||
|
glad_vkGetFenceStatus = (PFN_vkGetFenceStatus) load(userptr, "vkGetFenceStatus");
|
||||||
|
glad_vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load(userptr, "vkGetImageMemoryRequirements");
|
||||||
|
glad_vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load(userptr, "vkGetImageSparseMemoryRequirements");
|
||||||
|
glad_vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load(userptr, "vkGetImageSubresourceLayout");
|
||||||
|
glad_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load(userptr, "vkGetInstanceProcAddr");
|
||||||
|
glad_vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load(userptr, "vkGetPhysicalDeviceFeatures");
|
||||||
|
glad_vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load(userptr, "vkGetPhysicalDeviceFormatProperties");
|
||||||
|
glad_vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load(userptr, "vkGetPhysicalDeviceImageFormatProperties");
|
||||||
|
glad_vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load(userptr, "vkGetPhysicalDeviceMemoryProperties");
|
||||||
|
glad_vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load(userptr, "vkGetPhysicalDeviceProperties");
|
||||||
|
glad_vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties");
|
||||||
|
glad_vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties");
|
||||||
|
glad_vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load(userptr, "vkGetPipelineCacheData");
|
||||||
|
glad_vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load(userptr, "vkGetQueryPoolResults");
|
||||||
|
glad_vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load(userptr, "vkGetRenderAreaGranularity");
|
||||||
|
glad_vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load(userptr, "vkInvalidateMappedMemoryRanges");
|
||||||
|
glad_vkMapMemory = (PFN_vkMapMemory) load(userptr, "vkMapMemory");
|
||||||
|
glad_vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load(userptr, "vkMergePipelineCaches");
|
||||||
|
glad_vkQueueBindSparse = (PFN_vkQueueBindSparse) load(userptr, "vkQueueBindSparse");
|
||||||
|
glad_vkQueueSubmit = (PFN_vkQueueSubmit) load(userptr, "vkQueueSubmit");
|
||||||
|
glad_vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load(userptr, "vkQueueWaitIdle");
|
||||||
|
glad_vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load(userptr, "vkResetCommandBuffer");
|
||||||
|
glad_vkResetCommandPool = (PFN_vkResetCommandPool) load(userptr, "vkResetCommandPool");
|
||||||
|
glad_vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load(userptr, "vkResetDescriptorPool");
|
||||||
|
glad_vkResetEvent = (PFN_vkResetEvent) load(userptr, "vkResetEvent");
|
||||||
|
glad_vkResetFences = (PFN_vkResetFences) load(userptr, "vkResetFences");
|
||||||
|
glad_vkSetEvent = (PFN_vkSetEvent) load(userptr, "vkSetEvent");
|
||||||
|
glad_vkUnmapMemory = (PFN_vkUnmapMemory) load(userptr, "vkUnmapMemory");
|
||||||
|
glad_vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load(userptr, "vkUpdateDescriptorSets");
|
||||||
|
glad_vkWaitForFences = (PFN_vkWaitForFences) load(userptr, "vkWaitForFences");
|
||||||
|
}
|
||||||
|
static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_VERSION_1_1) return;
|
||||||
|
glad_vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load(userptr, "vkBindBufferMemory2");
|
||||||
|
glad_vkBindImageMemory2 = (PFN_vkBindImageMemory2) load(userptr, "vkBindImageMemory2");
|
||||||
|
glad_vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load(userptr, "vkCmdDispatchBase");
|
||||||
|
glad_vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load(userptr, "vkCmdSetDeviceMask");
|
||||||
|
glad_vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load(userptr, "vkCreateDescriptorUpdateTemplate");
|
||||||
|
glad_vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load(userptr, "vkCreateSamplerYcbcrConversion");
|
||||||
|
glad_vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load(userptr, "vkDestroyDescriptorUpdateTemplate");
|
||||||
|
glad_vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load(userptr, "vkDestroySamplerYcbcrConversion");
|
||||||
|
glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion");
|
||||||
|
glad_vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load(userptr, "vkEnumeratePhysicalDeviceGroups");
|
||||||
|
glad_vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load(userptr, "vkGetBufferMemoryRequirements2");
|
||||||
|
glad_vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load(userptr, "vkGetDescriptorSetLayoutSupport");
|
||||||
|
glad_vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load(userptr, "vkGetDeviceGroupPeerMemoryFeatures");
|
||||||
|
glad_vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load(userptr, "vkGetDeviceQueue2");
|
||||||
|
glad_vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load(userptr, "vkGetImageMemoryRequirements2");
|
||||||
|
glad_vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load(userptr, "vkGetImageSparseMemoryRequirements2");
|
||||||
|
glad_vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load(userptr, "vkGetPhysicalDeviceExternalBufferProperties");
|
||||||
|
glad_vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load(userptr, "vkGetPhysicalDeviceExternalFenceProperties");
|
||||||
|
glad_vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load(userptr, "vkGetPhysicalDeviceExternalSemaphoreProperties");
|
||||||
|
glad_vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load(userptr, "vkGetPhysicalDeviceFeatures2");
|
||||||
|
glad_vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load(userptr, "vkGetPhysicalDeviceFormatProperties2");
|
||||||
|
glad_vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceImageFormatProperties2");
|
||||||
|
glad_vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load(userptr, "vkGetPhysicalDeviceMemoryProperties2");
|
||||||
|
glad_vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load(userptr, "vkGetPhysicalDeviceProperties2");
|
||||||
|
glad_vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load(userptr, "vkGetPhysicalDeviceQueueFamilyProperties2");
|
||||||
|
glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load(userptr, "vkGetPhysicalDeviceSparseImageFormatProperties2");
|
||||||
|
glad_vkTrimCommandPool = (PFN_vkTrimCommandPool) load(userptr, "vkTrimCommandPool");
|
||||||
|
glad_vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load(userptr, "vkUpdateDescriptorSetWithTemplate");
|
||||||
|
}
|
||||||
|
static void glad_vk_load_VK_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_VERSION_1_2) return;
|
||||||
|
glad_vkCmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2) load(userptr, "vkCmdBeginRenderPass2");
|
||||||
|
glad_vkCmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount) load(userptr, "vkCmdDrawIndexedIndirectCount");
|
||||||
|
glad_vkCmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount) load(userptr, "vkCmdDrawIndirectCount");
|
||||||
|
glad_vkCmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2) load(userptr, "vkCmdEndRenderPass2");
|
||||||
|
glad_vkCmdNextSubpass2 = (PFN_vkCmdNextSubpass2) load(userptr, "vkCmdNextSubpass2");
|
||||||
|
glad_vkCreateRenderPass2 = (PFN_vkCreateRenderPass2) load(userptr, "vkCreateRenderPass2");
|
||||||
|
glad_vkGetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress) load(userptr, "vkGetBufferDeviceAddress");
|
||||||
|
glad_vkGetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress) load(userptr, "vkGetBufferOpaqueCaptureAddress");
|
||||||
|
glad_vkGetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress) load(userptr, "vkGetDeviceMemoryOpaqueCaptureAddress");
|
||||||
|
glad_vkGetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue) load(userptr, "vkGetSemaphoreCounterValue");
|
||||||
|
glad_vkResetQueryPool = (PFN_vkResetQueryPool) load(userptr, "vkResetQueryPool");
|
||||||
|
glad_vkSignalSemaphore = (PFN_vkSignalSemaphore) load(userptr, "vkSignalSemaphore");
|
||||||
|
glad_vkWaitSemaphores = (PFN_vkWaitSemaphores) load(userptr, "vkWaitSemaphores");
|
||||||
|
}
|
||||||
|
static void glad_vk_load_VK_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_VERSION_1_3) return;
|
||||||
|
glad_vkCmdBeginRendering = (PFN_vkCmdBeginRendering) load(userptr, "vkCmdBeginRendering");
|
||||||
|
glad_vkCmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2) load(userptr, "vkCmdBindVertexBuffers2");
|
||||||
|
glad_vkCmdBlitImage2 = (PFN_vkCmdBlitImage2) load(userptr, "vkCmdBlitImage2");
|
||||||
|
glad_vkCmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2) load(userptr, "vkCmdCopyBuffer2");
|
||||||
|
glad_vkCmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2) load(userptr, "vkCmdCopyBufferToImage2");
|
||||||
|
glad_vkCmdCopyImage2 = (PFN_vkCmdCopyImage2) load(userptr, "vkCmdCopyImage2");
|
||||||
|
glad_vkCmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2) load(userptr, "vkCmdCopyImageToBuffer2");
|
||||||
|
glad_vkCmdEndRendering = (PFN_vkCmdEndRendering) load(userptr, "vkCmdEndRendering");
|
||||||
|
glad_vkCmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2) load(userptr, "vkCmdPipelineBarrier2");
|
||||||
|
glad_vkCmdResetEvent2 = (PFN_vkCmdResetEvent2) load(userptr, "vkCmdResetEvent2");
|
||||||
|
glad_vkCmdResolveImage2 = (PFN_vkCmdResolveImage2) load(userptr, "vkCmdResolveImage2");
|
||||||
|
glad_vkCmdSetCullMode = (PFN_vkCmdSetCullMode) load(userptr, "vkCmdSetCullMode");
|
||||||
|
glad_vkCmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable) load(userptr, "vkCmdSetDepthBiasEnable");
|
||||||
|
glad_vkCmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable) load(userptr, "vkCmdSetDepthBoundsTestEnable");
|
||||||
|
glad_vkCmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp) load(userptr, "vkCmdSetDepthCompareOp");
|
||||||
|
glad_vkCmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable) load(userptr, "vkCmdSetDepthTestEnable");
|
||||||
|
glad_vkCmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable) load(userptr, "vkCmdSetDepthWriteEnable");
|
||||||
|
glad_vkCmdSetEvent2 = (PFN_vkCmdSetEvent2) load(userptr, "vkCmdSetEvent2");
|
||||||
|
glad_vkCmdSetFrontFace = (PFN_vkCmdSetFrontFace) load(userptr, "vkCmdSetFrontFace");
|
||||||
|
glad_vkCmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable) load(userptr, "vkCmdSetPrimitiveRestartEnable");
|
||||||
|
glad_vkCmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology) load(userptr, "vkCmdSetPrimitiveTopology");
|
||||||
|
glad_vkCmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable) load(userptr, "vkCmdSetRasterizerDiscardEnable");
|
||||||
|
glad_vkCmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount) load(userptr, "vkCmdSetScissorWithCount");
|
||||||
|
glad_vkCmdSetStencilOp = (PFN_vkCmdSetStencilOp) load(userptr, "vkCmdSetStencilOp");
|
||||||
|
glad_vkCmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable) load(userptr, "vkCmdSetStencilTestEnable");
|
||||||
|
glad_vkCmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount) load(userptr, "vkCmdSetViewportWithCount");
|
||||||
|
glad_vkCmdWaitEvents2 = (PFN_vkCmdWaitEvents2) load(userptr, "vkCmdWaitEvents2");
|
||||||
|
glad_vkCmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2) load(userptr, "vkCmdWriteTimestamp2");
|
||||||
|
glad_vkCreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot) load(userptr, "vkCreatePrivateDataSlot");
|
||||||
|
glad_vkDestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot) load(userptr, "vkDestroyPrivateDataSlot");
|
||||||
|
glad_vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements) load(userptr, "vkGetDeviceBufferMemoryRequirements");
|
||||||
|
glad_vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements) load(userptr, "vkGetDeviceImageMemoryRequirements");
|
||||||
|
glad_vkGetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements) load(userptr, "vkGetDeviceImageSparseMemoryRequirements");
|
||||||
|
glad_vkGetPhysicalDeviceToolProperties = (PFN_vkGetPhysicalDeviceToolProperties) load(userptr, "vkGetPhysicalDeviceToolProperties");
|
||||||
|
glad_vkGetPrivateData = (PFN_vkGetPrivateData) load(userptr, "vkGetPrivateData");
|
||||||
|
glad_vkQueueSubmit2 = (PFN_vkQueueSubmit2) load(userptr, "vkQueueSubmit2");
|
||||||
|
glad_vkSetPrivateData = (PFN_vkSetPrivateData) load(userptr, "vkSetPrivateData");
|
||||||
|
}
|
||||||
|
static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_EXT_debug_report) return;
|
||||||
|
glad_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load(userptr, "vkCreateDebugReportCallbackEXT");
|
||||||
|
glad_vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load(userptr, "vkDebugReportMessageEXT");
|
||||||
|
glad_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load(userptr, "vkDestroyDebugReportCallbackEXT");
|
||||||
|
}
|
||||||
|
static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_KHR_surface) return;
|
||||||
|
glad_vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load(userptr, "vkDestroySurfaceKHR");
|
||||||
|
glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load(userptr, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
|
||||||
|
glad_vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load(userptr, "vkGetPhysicalDeviceSurfaceFormatsKHR");
|
||||||
|
glad_vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load(userptr, "vkGetPhysicalDeviceSurfacePresentModesKHR");
|
||||||
|
glad_vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load(userptr, "vkGetPhysicalDeviceSurfaceSupportKHR");
|
||||||
|
}
|
||||||
|
static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) {
|
||||||
|
if(!GLAD_VK_KHR_swapchain) return;
|
||||||
|
glad_vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load(userptr, "vkAcquireNextImage2KHR");
|
||||||
|
glad_vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load(userptr, "vkAcquireNextImageKHR");
|
||||||
|
glad_vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load(userptr, "vkCreateSwapchainKHR");
|
||||||
|
glad_vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load(userptr, "vkDestroySwapchainKHR");
|
||||||
|
glad_vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load(userptr, "vkGetDeviceGroupPresentCapabilitiesKHR");
|
||||||
|
glad_vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load(userptr, "vkGetDeviceGroupSurfacePresentModesKHR");
|
||||||
|
glad_vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load(userptr, "vkGetPhysicalDevicePresentRectanglesKHR");
|
||||||
|
glad_vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load(userptr, "vkGetSwapchainImagesKHR");
|
||||||
|
glad_vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load(userptr, "vkQueuePresentKHR");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *out_extension_count, char ***out_extensions) {
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t instance_extension_count = 0;
|
||||||
|
uint32_t device_extension_count = 0;
|
||||||
|
uint32_t max_extension_count = 0;
|
||||||
|
uint32_t total_extension_count = 0;
|
||||||
|
char **extensions = NULL;
|
||||||
|
VkExtensionProperties *ext_properties = NULL;
|
||||||
|
VkResult result;
|
||||||
|
|
||||||
|
if (glad_vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && glad_vkEnumerateDeviceExtensionProperties == NULL)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (physical_device != NULL) {
|
||||||
|
result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_extension_count = instance_extension_count + device_extension_count;
|
||||||
|
if (total_extension_count <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_extension_count = instance_extension_count > device_extension_count
|
||||||
|
? instance_extension_count : device_extension_count;
|
||||||
|
|
||||||
|
ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties));
|
||||||
|
if (ext_properties == NULL) {
|
||||||
|
goto glad_vk_get_extensions_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = glad_vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
goto glad_vk_get_extensions_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions = (char**) calloc(total_extension_count, sizeof(char*));
|
||||||
|
if (extensions == NULL) {
|
||||||
|
goto glad_vk_get_extensions_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < instance_extension_count; ++i) {
|
||||||
|
VkExtensionProperties ext = ext_properties[i];
|
||||||
|
|
||||||
|
size_t extension_name_length = strlen(ext.extensionName) + 1;
|
||||||
|
extensions[i] = (char*) malloc(extension_name_length * sizeof(char));
|
||||||
|
if (extensions[i] == NULL) {
|
||||||
|
goto glad_vk_get_extensions_error;
|
||||||
|
}
|
||||||
|
memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (physical_device != NULL) {
|
||||||
|
result = glad_vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
goto glad_vk_get_extensions_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < device_extension_count; ++i) {
|
||||||
|
VkExtensionProperties ext = ext_properties[i];
|
||||||
|
|
||||||
|
size_t extension_name_length = strlen(ext.extensionName) + 1;
|
||||||
|
extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char));
|
||||||
|
if (extensions[instance_extension_count + i] == NULL) {
|
||||||
|
goto glad_vk_get_extensions_error;
|
||||||
|
}
|
||||||
|
memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free((void*) ext_properties);
|
||||||
|
|
||||||
|
*out_extension_count = total_extension_count;
|
||||||
|
*out_extensions = extensions;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
glad_vk_get_extensions_error:
|
||||||
|
free((void*) ext_properties);
|
||||||
|
if (extensions != NULL) {
|
||||||
|
for (i = 0; i < total_extension_count; ++i) {
|
||||||
|
free((void*) extensions[i]);
|
||||||
|
}
|
||||||
|
free(extensions);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) {
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < extension_count ; ++i) {
|
||||||
|
free((void*) (extensions[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
free((void*) extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int glad_vk_has_extension(const char *name, uint32_t extension_count, char **extensions) {
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < extension_count; ++i) {
|
||||||
|
if(extensions[i] != NULL && strcmp(name, extensions[i]) == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLADapiproc glad_vk_get_proc_from_userptr(void *userptr, const char* name) {
|
||||||
|
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) {
|
||||||
|
uint32_t extension_count = 0;
|
||||||
|
char **extensions = NULL;
|
||||||
|
if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0;
|
||||||
|
|
||||||
|
GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions);
|
||||||
|
GLAD_VK_KHR_portability_enumeration = glad_vk_has_extension("VK_KHR_portability_enumeration", extension_count, extensions);
|
||||||
|
GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions);
|
||||||
|
GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
|
||||||
|
|
||||||
|
(void) glad_vk_has_extension;
|
||||||
|
|
||||||
|
glad_vk_free_extensions(extension_count, extensions);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
|
||||||
|
int major = 1;
|
||||||
|
int minor = 0;
|
||||||
|
|
||||||
|
#ifdef VK_VERSION_1_1
|
||||||
|
if (glad_vkEnumerateInstanceVersion != NULL) {
|
||||||
|
uint32_t version;
|
||||||
|
VkResult result;
|
||||||
|
|
||||||
|
result = glad_vkEnumerateInstanceVersion(&version);
|
||||||
|
if (result == VK_SUCCESS) {
|
||||||
|
major = (int) VK_VERSION_MAJOR(version);
|
||||||
|
minor = (int) VK_VERSION_MINOR(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (physical_device != NULL && glad_vkGetPhysicalDeviceProperties != NULL) {
|
||||||
|
VkPhysicalDeviceProperties properties;
|
||||||
|
glad_vkGetPhysicalDeviceProperties(physical_device, &properties);
|
||||||
|
|
||||||
|
major = (int) VK_VERSION_MAJOR(properties.apiVersion);
|
||||||
|
minor = (int) VK_VERSION_MINOR(properties.apiVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
|
||||||
|
GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
|
||||||
|
GLAD_VK_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
|
||||||
|
GLAD_VK_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1;
|
||||||
|
|
||||||
|
return GLAD_MAKE_VERSION(major, minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr) {
|
||||||
|
int version;
|
||||||
|
|
||||||
|
#ifdef VK_VERSION_1_1
|
||||||
|
glad_vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load(userptr, "vkEnumerateInstanceVersion");
|
||||||
|
#endif
|
||||||
|
version = glad_vk_find_core_vulkan( physical_device);
|
||||||
|
if (!version) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glad_vk_load_VK_VERSION_1_0(load, userptr);
|
||||||
|
glad_vk_load_VK_VERSION_1_1(load, userptr);
|
||||||
|
glad_vk_load_VK_VERSION_1_2(load, userptr);
|
||||||
|
glad_vk_load_VK_VERSION_1_3(load, userptr);
|
||||||
|
|
||||||
|
if (!glad_vk_find_extensions_vulkan( physical_device)) return 0;
|
||||||
|
glad_vk_load_VK_EXT_debug_report(load, userptr);
|
||||||
|
glad_vk_load_VK_KHR_surface(load, userptr);
|
||||||
|
glad_vk_load_VK_KHR_swapchain(load, userptr);
|
||||||
|
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) {
|
||||||
|
return gladLoadVulkanUserPtr( physical_device, glad_vk_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
574
external/glfw-3.3.8/deps/linmath.h
vendored
Normal file
574
external/glfw-3.3.8/deps/linmath.h
vendored
Normal file
@ -0,0 +1,574 @@
|
|||||||
|
#ifndef LINMATH_H
|
||||||
|
#define LINMATH_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#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<n; ++i) \
|
||||||
|
r[i] = a[i] + b[i]; \
|
||||||
|
} \
|
||||||
|
static inline void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
for(i=0; i<n; ++i) \
|
||||||
|
r[i] = a[i] - b[i]; \
|
||||||
|
} \
|
||||||
|
static inline void vec##n##_scale(vec##n r, vec##n const v, float const s) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
for(i=0; i<n; ++i) \
|
||||||
|
r[i] = v[i] * s; \
|
||||||
|
} \
|
||||||
|
static inline float vec##n##_mul_inner(vec##n const a, vec##n const b) \
|
||||||
|
{ \
|
||||||
|
float p = 0.; \
|
||||||
|
int i; \
|
||||||
|
for(i=0; i<n; ++i) \
|
||||||
|
p += b[i]*a[i]; \
|
||||||
|
return p; \
|
||||||
|
} \
|
||||||
|
static inline float vec##n##_len(vec##n const v) \
|
||||||
|
{ \
|
||||||
|
return (float) sqrt(vec##n##_mul_inner(v,v)); \
|
||||||
|
} \
|
||||||
|
static inline void vec##n##_norm(vec##n r, vec##n const v) \
|
||||||
|
{ \
|
||||||
|
float k = 1.f / vec##n##_len(v); \
|
||||||
|
vec##n##_scale(r, v, k); \
|
||||||
|
}
|
||||||
|
|
||||||
|
LINMATH_H_DEFINE_VEC(2)
|
||||||
|
LINMATH_H_DEFINE_VEC(3)
|
||||||
|
LINMATH_H_DEFINE_VEC(4)
|
||||||
|
|
||||||
|
static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
|
||||||
|
{
|
||||||
|
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||||
|
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||||
|
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
|
||||||
|
{
|
||||||
|
float p = 2.f*vec3_mul_inner(v, n);
|
||||||
|
int i;
|
||||||
|
for(i=0;i<3;++i)
|
||||||
|
r[i] = v[i] - p*n[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
|
||||||
|
{
|
||||||
|
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||||
|
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||||
|
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||||
|
r[3] = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vec4_reflect(vec4 r, vec4 v, vec4 n)
|
||||||
|
{
|
||||||
|
float p = 2.f*vec4_mul_inner(v, n);
|
||||||
|
int i;
|
||||||
|
for(i=0;i<4;++i)
|
||||||
|
r[i] = v[i] - p*n[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef vec4 mat4x4[4];
|
||||||
|
static inline void mat4x4_identity(mat4x4 M)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
for(j=0; j<4; ++j)
|
||||||
|
M[i][j] = i==j ? 1.f : 0.f;
|
||||||
|
}
|
||||||
|
static inline void mat4x4_dup(mat4x4 M, mat4x4 N)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
for(j=0; j<4; ++j)
|
||||||
|
M[i][j] = N[i][j];
|
||||||
|
}
|
||||||
|
static inline void mat4x4_row(vec4 r, mat4x4 M, int i)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
for(k=0; k<4; ++k)
|
||||||
|
r[k] = M[k][i];
|
||||||
|
}
|
||||||
|
static inline void mat4x4_col(vec4 r, mat4x4 M, int i)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
for(k=0; k<4; ++k)
|
||||||
|
r[k] = M[i][k];
|
||||||
|
}
|
||||||
|
static inline void mat4x4_transpose(mat4x4 M, mat4x4 N)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for(j=0; j<4; ++j)
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
M[i][j] = N[j][i];
|
||||||
|
}
|
||||||
|
static inline void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
vec4_add(M[i], a[i], b[i]);
|
||||||
|
}
|
||||||
|
static inline void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
vec4_sub(M[i], a[i], b[i]);
|
||||||
|
}
|
||||||
|
static inline void mat4x4_scale(mat4x4 M, mat4x4 a, float k)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
vec4_scale(M[i], a[i], k);
|
||||||
|
}
|
||||||
|
static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
vec4_scale(M[0], a[0], x);
|
||||||
|
vec4_scale(M[1], a[1], y);
|
||||||
|
vec4_scale(M[2], a[2], z);
|
||||||
|
for(i = 0; i < 4; ++i) {
|
||||||
|
M[3][i] = a[3][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||||
|
{
|
||||||
|
mat4x4 temp;
|
||||||
|
int k, r, c;
|
||||||
|
for(c=0; c<4; ++c) for(r=0; r<4; ++r) {
|
||||||
|
temp[c][r] = 0.f;
|
||||||
|
for(k=0; k<4; ++k)
|
||||||
|
temp[c][r] += a[k][r] * b[c][k];
|
||||||
|
}
|
||||||
|
mat4x4_dup(M, temp);
|
||||||
|
}
|
||||||
|
static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for(j=0; j<4; ++j) {
|
||||||
|
r[j] = 0.f;
|
||||||
|
for(i=0; i<4; ++i)
|
||||||
|
r[j] += M[i][j] * v[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline void mat4x4_translate(mat4x4 T, float x, float y, float z)
|
||||||
|
{
|
||||||
|
mat4x4_identity(T);
|
||||||
|
T[3][0] = x;
|
||||||
|
T[3][1] = y;
|
||||||
|
T[3][2] = z;
|
||||||
|
}
|
||||||
|
static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
|
||||||
|
{
|
||||||
|
vec4 t = {x, y, z, 0};
|
||||||
|
vec4 r;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
mat4x4_row(r, M, i);
|
||||||
|
M[3][i] += vec4_mul_inner(r, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
|
||||||
|
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
|
||||||
|
}
|
||||||
|
static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle)
|
||||||
|
{
|
||||||
|
float s = sinf(angle);
|
||||||
|
float c = cosf(angle);
|
||||||
|
vec3 u = {x, y, z};
|
||||||
|
|
||||||
|
if(vec3_len(u) > 1e-4) {
|
||||||
|
mat4x4 T, C, S = {{0}};
|
||||||
|
|
||||||
|
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
|
117
external/glfw-3.3.8/deps/mingw/_mingw_dxhelper.h
vendored
Normal file
117
external/glfw-3.3.8/deps/mingw/_mingw_dxhelper.h
vendored
Normal file
@ -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 */
|
||||||
|
|
2467
external/glfw-3.3.8/deps/mingw/dinput.h
vendored
Normal file
2467
external/glfw-3.3.8/deps/mingw/dinput.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
239
external/glfw-3.3.8/deps/mingw/xinput.h
vendored
Normal file
239
external/glfw-3.3.8/deps/mingw/xinput.h
vendored
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
* The Wine project - Xinput Joystick Library
|
||||||
|
* Copyright 2008 Andrew Fenn
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WINE_XINPUT_H
|
||||||
|
#define __WINE_XINPUT_H
|
||||||
|
|
||||||
|
#include <windef.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitmasks for the joysticks buttons, determines what has
|
||||||
|
* been pressed on the joystick, these need to be mapped
|
||||||
|
* to whatever device you're using instead of an xbox 360
|
||||||
|
* joystick
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
|
||||||
|
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
|
||||||
|
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
|
||||||
|
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
|
||||||
|
#define XINPUT_GAMEPAD_START 0x0010
|
||||||
|
#define XINPUT_GAMEPAD_BACK 0x0020
|
||||||
|
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
|
||||||
|
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
|
||||||
|
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
|
||||||
|
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
|
||||||
|
#define XINPUT_GAMEPAD_A 0x1000
|
||||||
|
#define XINPUT_GAMEPAD_B 0x2000
|
||||||
|
#define XINPUT_GAMEPAD_X 0x4000
|
||||||
|
#define XINPUT_GAMEPAD_Y 0x8000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the flags used to determine if the user is pushing
|
||||||
|
* down on a button, not holding a button, etc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
|
||||||
|
#define XINPUT_KEYSTROKE_KEYUP 0x0002
|
||||||
|
#define XINPUT_KEYSTROKE_REPEAT 0x0004
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the codes which are returned by XInputGetKeystroke
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VK_PAD_A 0x5800
|
||||||
|
#define VK_PAD_B 0x5801
|
||||||
|
#define VK_PAD_X 0x5802
|
||||||
|
#define VK_PAD_Y 0x5803
|
||||||
|
#define VK_PAD_RSHOULDER 0x5804
|
||||||
|
#define VK_PAD_LSHOULDER 0x5805
|
||||||
|
#define VK_PAD_LTRIGGER 0x5806
|
||||||
|
#define VK_PAD_RTRIGGER 0x5807
|
||||||
|
#define VK_PAD_DPAD_UP 0x5810
|
||||||
|
#define VK_PAD_DPAD_DOWN 0x5811
|
||||||
|
#define VK_PAD_DPAD_LEFT 0x5812
|
||||||
|
#define VK_PAD_DPAD_RIGHT 0x5813
|
||||||
|
#define VK_PAD_START 0x5814
|
||||||
|
#define VK_PAD_BACK 0x5815
|
||||||
|
#define VK_PAD_LTHUMB_PRESS 0x5816
|
||||||
|
#define VK_PAD_RTHUMB_PRESS 0x5817
|
||||||
|
#define VK_PAD_LTHUMB_UP 0x5820
|
||||||
|
#define VK_PAD_LTHUMB_DOWN 0x5821
|
||||||
|
#define VK_PAD_LTHUMB_RIGHT 0x5822
|
||||||
|
#define VK_PAD_LTHUMB_LEFT 0x5823
|
||||||
|
#define VK_PAD_LTHUMB_UPLEFT 0x5824
|
||||||
|
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
|
||||||
|
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
|
||||||
|
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
|
||||||
|
#define VK_PAD_RTHUMB_UP 0x5830
|
||||||
|
#define VK_PAD_RTHUMB_DOWN 0x5831
|
||||||
|
#define VK_PAD_RTHUMB_RIGHT 0x5832
|
||||||
|
#define VK_PAD_RTHUMB_LEFT 0x5833
|
||||||
|
#define VK_PAD_RTHUMB_UPLEFT 0x5834
|
||||||
|
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
|
||||||
|
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
|
||||||
|
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deadzones are for analogue joystick controls on the joypad
|
||||||
|
* which determine when input should be assumed to be in the
|
||||||
|
* middle of the pad. This is a threshold to stop a joypad
|
||||||
|
* controlling the game when the player isn't touching the
|
||||||
|
* controls.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
|
||||||
|
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
|
||||||
|
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines what type of abilities the type of joystick has
|
||||||
|
* DEVTYPE_GAMEPAD is available for all joysticks, however
|
||||||
|
* there may be more specific identifiers for other joysticks
|
||||||
|
* which are being used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XINPUT_DEVTYPE_GAMEPAD 0x01
|
||||||
|
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
|
||||||
|
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
|
||||||
|
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
|
||||||
|
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
|
||||||
|
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
|
||||||
|
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
|
||||||
|
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are used with the XInputGetCapabilities function to
|
||||||
|
* determine the abilities to the joystick which has been
|
||||||
|
* plugged in.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
|
||||||
|
#define XINPUT_FLAG_GAMEPAD 0x00000001
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the status of the battery if one is used in the
|
||||||
|
* attached joystick. The first two define if the joystick
|
||||||
|
* supports a battery. Disconnected means that the joystick
|
||||||
|
* isn't connected. Wired shows that the joystick is a wired
|
||||||
|
* joystick.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BATTERY_DEVTYPE_GAMEPAD 0x00
|
||||||
|
#define BATTERY_DEVTYPE_HEADSET 0x01
|
||||||
|
#define BATTERY_TYPE_DISCONNECTED 0x00
|
||||||
|
#define BATTERY_TYPE_WIRED 0x01
|
||||||
|
#define BATTERY_TYPE_ALKALINE 0x02
|
||||||
|
#define BATTERY_TYPE_NIMH 0x03
|
||||||
|
#define BATTERY_TYPE_UNKNOWN 0xFF
|
||||||
|
#define BATTERY_LEVEL_EMPTY 0x00
|
||||||
|
#define BATTERY_LEVEL_LOW 0x01
|
||||||
|
#define BATTERY_LEVEL_MEDIUM 0x02
|
||||||
|
#define BATTERY_LEVEL_FULL 0x03
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How many joysticks can be used with this library. Games that
|
||||||
|
* use the xinput library will not go over this number.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XUSER_MAX_COUNT 4
|
||||||
|
#define XUSER_INDEX_ANY 0x000000FF
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the structure of an xbox 360 joystick.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _XINPUT_GAMEPAD {
|
||||||
|
WORD wButtons;
|
||||||
|
BYTE bLeftTrigger;
|
||||||
|
BYTE bRightTrigger;
|
||||||
|
SHORT sThumbLX;
|
||||||
|
SHORT sThumbLY;
|
||||||
|
SHORT sThumbRX;
|
||||||
|
SHORT sThumbRY;
|
||||||
|
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||||
|
|
||||||
|
typedef struct _XINPUT_STATE {
|
||||||
|
DWORD dwPacketNumber;
|
||||||
|
XINPUT_GAMEPAD Gamepad;
|
||||||
|
} XINPUT_STATE, *PXINPUT_STATE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the structure of how much vibration is set on both the
|
||||||
|
* right and left motors in a joystick. If you're not using a 360
|
||||||
|
* joystick you will have to map these to your device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _XINPUT_VIBRATION {
|
||||||
|
WORD wLeftMotorSpeed;
|
||||||
|
WORD wRightMotorSpeed;
|
||||||
|
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the structure for what kind of abilities the joystick has
|
||||||
|
* such abilities are things such as if the joystick has the ability
|
||||||
|
* to send and receive audio, if the joystick is in fact a driving
|
||||||
|
* wheel or perhaps if the joystick is some kind of dance pad or
|
||||||
|
* guitar.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _XINPUT_CAPABILITIES {
|
||||||
|
BYTE Type;
|
||||||
|
BYTE SubType;
|
||||||
|
WORD Flags;
|
||||||
|
XINPUT_GAMEPAD Gamepad;
|
||||||
|
XINPUT_VIBRATION Vibration;
|
||||||
|
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the structure for a joystick input event which is
|
||||||
|
* retrieved using the function XInputGetKeystroke
|
||||||
|
*/
|
||||||
|
typedef struct _XINPUT_KEYSTROKE {
|
||||||
|
WORD VirtualKey;
|
||||||
|
WCHAR Unicode;
|
||||||
|
WORD Flags;
|
||||||
|
BYTE UserIndex;
|
||||||
|
BYTE HidCode;
|
||||||
|
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
|
||||||
|
|
||||||
|
typedef struct _XINPUT_BATTERY_INFORMATION
|
||||||
|
{
|
||||||
|
BYTE BatteryType;
|
||||||
|
BYTE BatteryLevel;
|
||||||
|
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void WINAPI XInputEnable(WINBOOL);
|
||||||
|
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
|
||||||
|
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
|
||||||
|
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
|
||||||
|
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||||
|
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
|
||||||
|
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __WINE_XINPUT_H */
|
25539
external/glfw-3.3.8/deps/nuklear.h
vendored
Normal file
25539
external/glfw-3.3.8/deps/nuklear.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
381
external/glfw-3.3.8/deps/nuklear_glfw_gl2.h
vendored
Normal file
381
external/glfw-3.3.8/deps/nuklear_glfw_gl2.h
vendored
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
/*
|
||||||
|
* Nuklear - v1.32.0 - public domain
|
||||||
|
* no warrenty implied; use at your own risk.
|
||||||
|
* authored from 2015-2017 by Micha Mettke
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* ==============================================================
|
||||||
|
*
|
||||||
|
* API
|
||||||
|
*
|
||||||
|
* ===============================================================
|
||||||
|
*/
|
||||||
|
#ifndef NK_GLFW_GL2_H_
|
||||||
|
#define NK_GLFW_GL2_H_
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
enum nk_glfw_init_state{
|
||||||
|
NK_GLFW3_DEFAULT = 0,
|
||||||
|
NK_GLFW3_INSTALL_CALLBACKS
|
||||||
|
};
|
||||||
|
NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||||
|
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||||
|
NK_API void nk_glfw3_font_stash_end(void);
|
||||||
|
|
||||||
|
NK_API void nk_glfw3_new_frame(void);
|
||||||
|
NK_API void nk_glfw3_render(enum nk_anti_aliasing);
|
||||||
|
NK_API void nk_glfw3_shutdown(void);
|
||||||
|
|
||||||
|
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||||
|
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================
|
||||||
|
*
|
||||||
|
* IMPLEMENTATION
|
||||||
|
*
|
||||||
|
* ===============================================================
|
||||||
|
*/
|
||||||
|
#ifdef NK_GLFW_GL2_IMPLEMENTATION
|
||||||
|
|
||||||
|
#ifndef NK_GLFW_TEXT_MAX
|
||||||
|
#define NK_GLFW_TEXT_MAX 256
|
||||||
|
#endif
|
||||||
|
#ifndef NK_GLFW_DOUBLE_CLICK_LO
|
||||||
|
#define NK_GLFW_DOUBLE_CLICK_LO 0.02
|
||||||
|
#endif
|
||||||
|
#ifndef NK_GLFW_DOUBLE_CLICK_HI
|
||||||
|
#define NK_GLFW_DOUBLE_CLICK_HI 0.2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct nk_glfw_device {
|
||||||
|
struct nk_buffer cmds;
|
||||||
|
struct nk_draw_null_texture null;
|
||||||
|
GLuint font_tex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nk_glfw_vertex {
|
||||||
|
float position[2];
|
||||||
|
float uv[2];
|
||||||
|
nk_byte col[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct nk_glfw {
|
||||||
|
GLFWwindow *win;
|
||||||
|
int width, height;
|
||||||
|
int display_width, display_height;
|
||||||
|
struct nk_glfw_device ogl;
|
||||||
|
struct nk_context ctx;
|
||||||
|
struct nk_font_atlas atlas;
|
||||||
|
struct nk_vec2 fb_scale;
|
||||||
|
unsigned int text[NK_GLFW_TEXT_MAX];
|
||||||
|
int text_len;
|
||||||
|
struct nk_vec2 scroll;
|
||||||
|
double last_button_click;
|
||||||
|
int is_double_click_down;
|
||||||
|
struct nk_vec2 double_click_pos;
|
||||||
|
} glfw;
|
||||||
|
|
||||||
|
NK_INTERN void
|
||||||
|
nk_glfw3_device_upload_atlas(const void *image, int width, int height)
|
||||||
|
{
|
||||||
|
struct nk_glfw_device *dev = &glfw.ogl;
|
||||||
|
glGenTextures(1, &dev->font_tex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, dev->font_tex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_glfw3_render(enum nk_anti_aliasing AA)
|
||||||
|
{
|
||||||
|
/* setup global state */
|
||||||
|
struct nk_glfw_device *dev = &glfw.ogl;
|
||||||
|
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
/* setup viewport/project */
|
||||||
|
glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
{
|
||||||
|
GLsizei vs = sizeof(struct nk_glfw_vertex);
|
||||||
|
size_t vp = offsetof(struct nk_glfw_vertex, position);
|
||||||
|
size_t vt = offsetof(struct nk_glfw_vertex, uv);
|
||||||
|
size_t vc = offsetof(struct nk_glfw_vertex, col);
|
||||||
|
|
||||||
|
/* convert from command queue into draw list and draw to screen */
|
||||||
|
const struct nk_draw_command *cmd;
|
||||||
|
const nk_draw_index *offset = NULL;
|
||||||
|
struct nk_buffer vbuf, ebuf;
|
||||||
|
|
||||||
|
/* fill convert configuration */
|
||||||
|
struct nk_convert_config config;
|
||||||
|
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||||
|
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
|
||||||
|
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
|
||||||
|
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
|
||||||
|
{NK_VERTEX_LAYOUT_END}
|
||||||
|
};
|
||||||
|
NK_MEMSET(&config, 0, sizeof(config));
|
||||||
|
config.vertex_layout = vertex_layout;
|
||||||
|
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||||
|
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||||
|
config.null = dev->null;
|
||||||
|
config.circle_segment_count = 22;
|
||||||
|
config.curve_segment_count = 22;
|
||||||
|
config.arc_segment_count = 22;
|
||||||
|
config.global_alpha = 1.0f;
|
||||||
|
config.shape_AA = AA;
|
||||||
|
config.line_AA = AA;
|
||||||
|
|
||||||
|
/* convert shapes into vertexes */
|
||||||
|
nk_buffer_init_default(&vbuf);
|
||||||
|
nk_buffer_init_default(&ebuf);
|
||||||
|
nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||||
|
|
||||||
|
/* setup vertex buffer pointer */
|
||||||
|
{const void *vertices = nk_buffer_memory_const(&vbuf);
|
||||||
|
glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
|
||||||
|
glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
|
||||||
|
|
||||||
|
/* iterate over and execute each draw command */
|
||||||
|
offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
|
||||||
|
nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
|
||||||
|
{
|
||||||
|
if (!cmd->elem_count) continue;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||||
|
glScissor(
|
||||||
|
(GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
|
||||||
|
(GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
|
||||||
|
(GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
|
||||||
|
(GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
|
||||||
|
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||||
|
offset += cmd->elem_count;
|
||||||
|
}
|
||||||
|
nk_clear(&glfw.ctx);
|
||||||
|
nk_buffer_free(&vbuf);
|
||||||
|
nk_buffer_free(&ebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default OpenGL state */
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPopMatrix();
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
|
||||||
|
{
|
||||||
|
(void)win;
|
||||||
|
if (glfw.text_len < NK_GLFW_TEXT_MAX)
|
||||||
|
glfw.text[glfw.text_len++] = codepoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
||||||
|
{
|
||||||
|
(void)win; (void)xoff;
|
||||||
|
glfw.scroll.x += (float)xoff;
|
||||||
|
glfw.scroll.y += (float)yoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
double x, y;
|
||||||
|
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||||
|
glfwGetCursorPos(window, &x, &y);
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
double dt = glfwGetTime() - glfw.last_button_click;
|
||||||
|
if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
|
||||||
|
glfw.is_double_click_down = nk_true;
|
||||||
|
glfw.double_click_pos = nk_vec2((float)x, (float)y);
|
||||||
|
}
|
||||||
|
glfw.last_button_click = glfwGetTime();
|
||||||
|
} else glfw.is_double_click_down = nk_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_INTERN void
|
||||||
|
nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||||
|
{
|
||||||
|
const char *text = glfwGetClipboardString(glfw.win);
|
||||||
|
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||||
|
(void)usr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_INTERN void
|
||||||
|
nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
|
||||||
|
{
|
||||||
|
char *str = 0;
|
||||||
|
(void)usr;
|
||||||
|
if (!len) return;
|
||||||
|
str = (char*)malloc((size_t)len+1);
|
||||||
|
if (!str) return;
|
||||||
|
NK_MEMCPY(str, text, (size_t)len);
|
||||||
|
str[len] = '\0';
|
||||||
|
glfwSetClipboardString(glfw.win, str);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API struct nk_context*
|
||||||
|
nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
|
||||||
|
{
|
||||||
|
glfw.win = win;
|
||||||
|
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
||||||
|
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
||||||
|
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
||||||
|
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
||||||
|
}
|
||||||
|
nk_init_default(&glfw.ctx, 0);
|
||||||
|
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
|
||||||
|
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
|
||||||
|
glfw.ctx.clip.userdata = nk_handle_ptr(0);
|
||||||
|
nk_buffer_init_default(&glfw.ogl.cmds);
|
||||||
|
|
||||||
|
glfw.is_double_click_down = nk_false;
|
||||||
|
glfw.double_click_pos = nk_vec2(0, 0);
|
||||||
|
|
||||||
|
return &glfw.ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
|
||||||
|
{
|
||||||
|
nk_font_atlas_init_default(&glfw.atlas);
|
||||||
|
nk_font_atlas_begin(&glfw.atlas);
|
||||||
|
*atlas = &glfw.atlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_glfw3_font_stash_end(void)
|
||||||
|
{
|
||||||
|
const void *image; int w, h;
|
||||||
|
image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||||
|
nk_glfw3_device_upload_atlas(image, w, h);
|
||||||
|
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
|
||||||
|
if (glfw.atlas.default_font)
|
||||||
|
nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API void
|
||||||
|
nk_glfw3_new_frame(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
double x, y;
|
||||||
|
struct nk_context *ctx = &glfw.ctx;
|
||||||
|
struct GLFWwindow *win = glfw.win;
|
||||||
|
|
||||||
|
glfwGetWindowSize(win, &glfw.width, &glfw.height);
|
||||||
|
glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
|
||||||
|
glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width;
|
||||||
|
glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height;
|
||||||
|
|
||||||
|
nk_input_begin(ctx);
|
||||||
|
for (i = 0; i < glfw.text_len; ++i)
|
||||||
|
nk_input_unicode(ctx, glfw.text[i]);
|
||||||
|
|
||||||
|
/* optional grabbing behavior */
|
||||||
|
if (ctx->input.mouse.grab)
|
||||||
|
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||||
|
else if (ctx->input.mouse.ungrab)
|
||||||
|
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
|
||||||
|
nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
|
||||||
|
glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
|
||||||
|
|
||||||
|
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
||||||
|
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
||||||
|
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
|
||||||
|
} else {
|
||||||
|
nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||||
|
nk_input_key(ctx, NK_KEY_COPY, 0);
|
||||||
|
nk_input_key(ctx, NK_KEY_PASTE, 0);
|
||||||
|
nk_input_key(ctx, NK_KEY_CUT, 0);
|
||||||
|
nk_input_key(ctx, NK_KEY_SHIFT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwGetCursorPos(win, &x, &y);
|
||||||
|
nk_input_motion(ctx, (int)x, (int)y);
|
||||||
|
if (ctx->input.mouse.grabbed) {
|
||||||
|
glfwSetCursorPos(glfw.win, (double)ctx->input.mouse.prev.x, (double)ctx->input.mouse.prev.y);
|
||||||
|
ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
|
||||||
|
ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
|
||||||
|
nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
|
||||||
|
nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
|
||||||
|
nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down);
|
||||||
|
nk_input_scroll(ctx, glfw.scroll);
|
||||||
|
nk_input_end(&glfw.ctx);
|
||||||
|
glfw.text_len = 0;
|
||||||
|
glfw.scroll = nk_vec2(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NK_API
|
||||||
|
void nk_glfw3_shutdown(void)
|
||||||
|
{
|
||||||
|
struct nk_glfw_device *dev = &glfw.ogl;
|
||||||
|
nk_font_atlas_clear(&glfw.atlas);
|
||||||
|
nk_free(&glfw.ctx);
|
||||||
|
glDeleteTextures(1, &dev->font_tex);
|
||||||
|
nk_buffer_free(&dev->cmds);
|
||||||
|
NK_MEMSET(&glfw, 0, sizeof(glfw));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1724
external/glfw-3.3.8/deps/stb_image_write.h
vendored
Normal file
1724
external/glfw-3.3.8/deps/stb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
594
external/glfw-3.3.8/deps/tinycthread.c
vendored
Normal file
594
external/glfw-3.3.8/deps/tinycthread.c
vendored
Normal file
@ -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 Löwy <elmindreda@glfw.org>
|
||||||
|
*
|
||||||
|
* Added casts from time_t to DWORD to avoid warnings on VC++.
|
||||||
|
* Fixed time retrieval on POSIX systems.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tinycthread.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Platform specific includes */
|
||||||
|
#if defined(_TTHREAD_POSIX_)
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#elif defined(_TTHREAD_WIN32_)
|
||||||
|
#include <process.h>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#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_
|
||||||
|
|
443
external/glfw-3.3.8/deps/tinycthread.h
vendored
Normal file
443
external/glfw-3.3.8/deps/tinycthread.h
vendored
Normal file
@ -0,0 +1,443 @@
|
|||||||
|
/* -*- 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 <time.h>
|
||||||
|
|
||||||
|
/* Platform specific includes */
|
||||||
|
#if defined(_TTHREAD_POSIX_)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#elif defined(_TTHREAD_WIN32_)
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define __UNDEF_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#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
|
||||||
|
#ifndef CLOCK_REALTIME
|
||||||
|
#define CLOCK_REALTIME 0
|
||||||
|
#endif
|
||||||
|
#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_ */
|
||||||
|
|
247
external/glfw-3.3.8/deps/vs2008/stdint.h
vendored
Normal file
247
external/glfw-3.3.8/deps/vs2008/stdint.h
vendored
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||||
|
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006-2008 Alexander Chemeris
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. The name of the author may be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _MSC_VER // [
|
||||||
|
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||||
|
#endif // _MSC_VER ]
|
||||||
|
|
||||||
|
#ifndef _MSC_STDINT_H_ // [
|
||||||
|
#define _MSC_STDINT_H_
|
||||||
|
|
||||||
|
#if _MSC_VER > 1000
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||||
|
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||||
|
// or compiler give many errors like this:
|
||||||
|
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
# include <wchar.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||||
|
#ifndef _W64
|
||||||
|
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||||
|
# define _W64 __w64
|
||||||
|
# else
|
||||||
|
# define _W64
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.1 Integer types
|
||||||
|
|
||||||
|
// 7.18.1.1 Exact-width integer types
|
||||||
|
|
||||||
|
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||||
|
// realize that, e.g. char has the same size as __int8
|
||||||
|
// so we give up on __intX for them.
|
||||||
|
#if (_MSC_VER < 1300)
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
typedef signed int int32_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#else
|
||||||
|
typedef signed __int8 int8_t;
|
||||||
|
typedef signed __int16 int16_t;
|
||||||
|
typedef signed __int32 int32_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
#endif
|
||||||
|
typedef signed __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.1.2 Minimum-width integer types
|
||||||
|
typedef int8_t int_least8_t;
|
||||||
|
typedef int16_t int_least16_t;
|
||||||
|
typedef int32_t int_least32_t;
|
||||||
|
typedef int64_t int_least64_t;
|
||||||
|
typedef uint8_t uint_least8_t;
|
||||||
|
typedef uint16_t uint_least16_t;
|
||||||
|
typedef uint32_t uint_least32_t;
|
||||||
|
typedef uint64_t uint_least64_t;
|
||||||
|
|
||||||
|
// 7.18.1.3 Fastest minimum-width integer types
|
||||||
|
typedef int8_t int_fast8_t;
|
||||||
|
typedef int16_t int_fast16_t;
|
||||||
|
typedef int32_t int_fast32_t;
|
||||||
|
typedef int64_t int_fast64_t;
|
||||||
|
typedef uint8_t uint_fast8_t;
|
||||||
|
typedef uint16_t uint_fast16_t;
|
||||||
|
typedef uint32_t uint_fast32_t;
|
||||||
|
typedef uint64_t uint_fast64_t;
|
||||||
|
|
||||||
|
// 7.18.1.4 Integer types capable of holding object pointers
|
||||||
|
#ifdef _WIN64 // [
|
||||||
|
typedef signed __int64 intptr_t;
|
||||||
|
typedef unsigned __int64 uintptr_t;
|
||||||
|
#else // _WIN64 ][
|
||||||
|
typedef _W64 signed int intptr_t;
|
||||||
|
typedef _W64 unsigned int uintptr_t;
|
||||||
|
#endif // _WIN64 ]
|
||||||
|
|
||||||
|
// 7.18.1.5 Greatest-width integer types
|
||||||
|
typedef int64_t intmax_t;
|
||||||
|
typedef uint64_t uintmax_t;
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.2 Limits of specified-width integer types
|
||||||
|
|
||||||
|
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||||
|
|
||||||
|
// 7.18.2.1 Limits of exact-width integer types
|
||||||
|
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||||
|
#define INT8_MAX _I8_MAX
|
||||||
|
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||||
|
#define INT16_MAX _I16_MAX
|
||||||
|
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||||
|
#define INT32_MAX _I32_MAX
|
||||||
|
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||||
|
#define INT64_MAX _I64_MAX
|
||||||
|
#define UINT8_MAX _UI8_MAX
|
||||||
|
#define UINT16_MAX _UI16_MAX
|
||||||
|
#define UINT32_MAX _UI32_MAX
|
||||||
|
#define UINT64_MAX _UI64_MAX
|
||||||
|
|
||||||
|
// 7.18.2.2 Limits of minimum-width integer types
|
||||||
|
#define INT_LEAST8_MIN INT8_MIN
|
||||||
|
#define INT_LEAST8_MAX INT8_MAX
|
||||||
|
#define INT_LEAST16_MIN INT16_MIN
|
||||||
|
#define INT_LEAST16_MAX INT16_MAX
|
||||||
|
#define INT_LEAST32_MIN INT32_MIN
|
||||||
|
#define INT_LEAST32_MAX INT32_MAX
|
||||||
|
#define INT_LEAST64_MIN INT64_MIN
|
||||||
|
#define INT_LEAST64_MAX INT64_MAX
|
||||||
|
#define UINT_LEAST8_MAX UINT8_MAX
|
||||||
|
#define UINT_LEAST16_MAX UINT16_MAX
|
||||||
|
#define UINT_LEAST32_MAX UINT32_MAX
|
||||||
|
#define UINT_LEAST64_MAX UINT64_MAX
|
||||||
|
|
||||||
|
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||||
|
#define INT_FAST8_MIN INT8_MIN
|
||||||
|
#define INT_FAST8_MAX INT8_MAX
|
||||||
|
#define INT_FAST16_MIN INT16_MIN
|
||||||
|
#define INT_FAST16_MAX INT16_MAX
|
||||||
|
#define INT_FAST32_MIN INT32_MIN
|
||||||
|
#define INT_FAST32_MAX INT32_MAX
|
||||||
|
#define INT_FAST64_MIN INT64_MIN
|
||||||
|
#define INT_FAST64_MAX INT64_MAX
|
||||||
|
#define UINT_FAST8_MAX UINT8_MAX
|
||||||
|
#define UINT_FAST16_MAX UINT16_MAX
|
||||||
|
#define UINT_FAST32_MAX UINT32_MAX
|
||||||
|
#define UINT_FAST64_MAX UINT64_MAX
|
||||||
|
|
||||||
|
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||||
|
#ifdef _WIN64 // [
|
||||||
|
# define INTPTR_MIN INT64_MIN
|
||||||
|
# define INTPTR_MAX INT64_MAX
|
||||||
|
# define UINTPTR_MAX UINT64_MAX
|
||||||
|
#else // _WIN64 ][
|
||||||
|
# define INTPTR_MIN INT32_MIN
|
||||||
|
# define INTPTR_MAX INT32_MAX
|
||||||
|
# define UINTPTR_MAX UINT32_MAX
|
||||||
|
#endif // _WIN64 ]
|
||||||
|
|
||||||
|
// 7.18.2.5 Limits of greatest-width integer types
|
||||||
|
#define INTMAX_MIN INT64_MIN
|
||||||
|
#define INTMAX_MAX INT64_MAX
|
||||||
|
#define UINTMAX_MAX UINT64_MAX
|
||||||
|
|
||||||
|
// 7.18.3 Limits of other integer types
|
||||||
|
|
||||||
|
#ifdef _WIN64 // [
|
||||||
|
# define PTRDIFF_MIN _I64_MIN
|
||||||
|
# define PTRDIFF_MAX _I64_MAX
|
||||||
|
#else // _WIN64 ][
|
||||||
|
# define PTRDIFF_MIN _I32_MIN
|
||||||
|
# define PTRDIFF_MAX _I32_MAX
|
||||||
|
#endif // _WIN64 ]
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_MIN INT_MIN
|
||||||
|
#define SIG_ATOMIC_MAX INT_MAX
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX // [
|
||||||
|
# ifdef _WIN64 // [
|
||||||
|
# define SIZE_MAX _UI64_MAX
|
||||||
|
# else // _WIN64 ][
|
||||||
|
# define SIZE_MAX _UI32_MAX
|
||||||
|
# endif // _WIN64 ]
|
||||||
|
#endif // SIZE_MAX ]
|
||||||
|
|
||||||
|
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||||
|
#ifndef WCHAR_MIN // [
|
||||||
|
# define WCHAR_MIN 0
|
||||||
|
#endif // WCHAR_MIN ]
|
||||||
|
#ifndef WCHAR_MAX // [
|
||||||
|
# define WCHAR_MAX _UI16_MAX
|
||||||
|
#endif // WCHAR_MAX ]
|
||||||
|
|
||||||
|
#define WINT_MIN 0
|
||||||
|
#define WINT_MAX _UI16_MAX
|
||||||
|
|
||||||
|
#endif // __STDC_LIMIT_MACROS ]
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.4 Limits of other integer types
|
||||||
|
|
||||||
|
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||||
|
|
||||||
|
// 7.18.4.1 Macros for minimum-width integer constants
|
||||||
|
|
||||||
|
#define INT8_C(val) val##i8
|
||||||
|
#define INT16_C(val) val##i16
|
||||||
|
#define INT32_C(val) val##i32
|
||||||
|
#define INT64_C(val) val##i64
|
||||||
|
|
||||||
|
#define UINT8_C(val) val##ui8
|
||||||
|
#define UINT16_C(val) val##ui16
|
||||||
|
#define UINT32_C(val) val##ui32
|
||||||
|
#define UINT64_C(val) val##ui64
|
||||||
|
|
||||||
|
// 7.18.4.2 Macros for greatest-width integer constants
|
||||||
|
#define INTMAX_C INT64_C
|
||||||
|
#define UINTMAX_C UINT64_C
|
||||||
|
|
||||||
|
#endif // __STDC_CONSTANT_MACROS ]
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _MSC_STDINT_H_ ]
|
5912
external/glfw-3.3.8/include/GLFW/glfw3.h
vendored
Normal file
5912
external/glfw-3.3.8/include/GLFW/glfw3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
628
external/glfw-3.3.8/include/GLFW/glfw3native.h
vendored
Normal file
628
external/glfw-3.3.8/include/GLFW/glfw3native.h
vendored
Normal file
@ -0,0 +1,628 @@
|
|||||||
|
/*************************************************************************
|
||||||
|
* GLFW 3.3 - www.glfw.org
|
||||||
|
* A library for OpenGL, window and input
|
||||||
|
*------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would
|
||||||
|
* be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
* be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#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
|
||||||
|
* @brief Functions related to accessing native handles.
|
||||||
|
*
|
||||||
|
* **By using the native access functions you assert that you know what you're
|
||||||
|
* doing and how to fix problems caused by using them. If you don't, you
|
||||||
|
* shouldn't be using them.**
|
||||||
|
*
|
||||||
|
* Before the inclusion of @ref glfw3native.h, you may define zero or more
|
||||||
|
* window system API macro and zero or more context creation API macros.
|
||||||
|
*
|
||||||
|
* The chosen backends must match those the library was compiled for. Failure
|
||||||
|
* 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`
|
||||||
|
*
|
||||||
|
* The available context API macros are:
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||||
|
* * `GLFW_EXPOSE_NATIVE_OSMESA`
|
||||||
|
*
|
||||||
|
* These macros select which of the native access functions that are declared
|
||||||
|
* and which platform-specific headers to include. It is then up your (by
|
||||||
|
* definition platform-specific) code to handle which of these should be
|
||||||
|
* defined.
|
||||||
|
*
|
||||||
|
* If you do not want the platform-specific headers to be included, define
|
||||||
|
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* #define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
|
* #define GLFW_EXPOSE_NATIVE_WGL
|
||||||
|
* #define GLFW_NATIVE_INCLUDE_NONE
|
||||||
|
* #include <GLFW/glfw3native.h>
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* System headers and types
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
|
/* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||||
|
* example to allow applications to correctly declare a GL_KHR_debug callback)
|
||||||
|
* but windows.h assumes no one will define APIENTRY before it does
|
||||||
|
*/
|
||||||
|
#if defined(GLFW_APIENTRY_DEFINED)
|
||||||
|
#undef APIENTRY
|
||||||
|
#undef GLFW_APIENTRY_DEFINED
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||||
|
#if defined(__OBJC__)
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#else
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#include <objc/objc.h>
|
||||||
|
#endif
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
|
/* WGL is declared by windows.h */
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||||
|
/* NSGL is declared by Cocoa.h */
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
|
||||||
|
* default it also acts as an OpenGL header
|
||||||
|
* However, glx.h will include gl.h, which will define it unconditionally
|
||||||
|
*/
|
||||||
|
#if defined(GLFW_GLAPIENTRY_DEFINED)
|
||||||
|
#undef GLAPIENTRY
|
||||||
|
#undef GLFW_GLAPIENTRY_DEFINED
|
||||||
|
#endif
|
||||||
|
#include <GL/glx.h>
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#endif
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||||
|
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
|
||||||
|
* default it also acts as an OpenGL header
|
||||||
|
* However, osmesa.h will include gl.h, which will define it unconditionally
|
||||||
|
*/
|
||||||
|
#if defined(GLFW_GLAPIENTRY_DEFINED)
|
||||||
|
#undef GLAPIENTRY
|
||||||
|
#undef GLFW_GLAPIENTRY_DEFINED
|
||||||
|
#endif
|
||||||
|
#include <GL/osmesa.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @remark The `HDC` associated with the window can be queried with the
|
||||||
|
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
|
||||||
|
* function.
|
||||||
|
* @code
|
||||||
|
* HDC dc = GetDC(glfwGetWin32Window(window));
|
||||||
|
* @endcode
|
||||||
|
* This DC is private and does not need to be released.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @remark The `HDC` associated with the window can be queried with the
|
||||||
|
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
|
||||||
|
* function.
|
||||||
|
* @code
|
||||||
|
* HDC dc = GetDC(glfwGetWin32Window(window));
|
||||||
|
* @endcode
|
||||||
|
* This DC is private and does not need to be released.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
/*! @brief Sets the current primary selection to the specified string.
|
||||||
|
*
|
||||||
|
* @param[in] string A UTF-8 encoded string.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The specified string is copied before this function
|
||||||
|
* returns.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref clipboard
|
||||||
|
* @sa glfwGetX11SelectionString
|
||||||
|
* @sa glfwSetClipboardString
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||||
|
|
||||||
|
/*! @brief Returns the contents of the current primary selection as a string.
|
||||||
|
*
|
||||||
|
* If the selection is empty or if its contents cannot be converted, `NULL`
|
||||||
|
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
||||||
|
*
|
||||||
|
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
||||||
|
* if an [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
|
* GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||||
|
* should not free it yourself. It is valid until the next call to @ref
|
||||||
|
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
||||||
|
* library is terminated.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref clipboard
|
||||||
|
* @sa glfwSetX11SelectionString
|
||||||
|
* @sa glfwGetClipboardString
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
|
/*! @brief Returns the `GLXContext` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @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_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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @remark Because EGL is initialized on demand, this function will return
|
||||||
|
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.0.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||||
|
/*! @brief Retrieves the color buffer associated with the specified window.
|
||||||
|
*
|
||||||
|
* @param[in] window The window whose color buffer to retrieve.
|
||||||
|
* @param[out] width Where to store the width of the color buffer, or `NULL`.
|
||||||
|
* @param[out] height Where to store the height of the color buffer, or `NULL`.
|
||||||
|
* @param[out] format Where to store the OSMesa pixel format of the color
|
||||||
|
* buffer, or `NULL`.
|
||||||
|
* @param[out] buffer Where to store the address of the color buffer, or
|
||||||
|
* `NULL`.
|
||||||
|
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
|
||||||
|
|
||||||
|
/*! @brief Retrieves the depth buffer associated with the specified window.
|
||||||
|
*
|
||||||
|
* @param[in] window The window whose depth buffer to retrieve.
|
||||||
|
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
|
||||||
|
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
|
||||||
|
* @param[out] bytesPerValue Where to store the number of bytes per depth
|
||||||
|
* buffer element, or `NULL`.
|
||||||
|
* @param[out] buffer Where to store the address of the depth buffer, or
|
||||||
|
* `NULL`.
|
||||||
|
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
|
||||||
|
|
||||||
|
/*! @brief Returns the `OSMesaContext` of the specified window.
|
||||||
|
*
|
||||||
|
* @return The `OSMesaContext` of the specified window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
|
||||||
|
* GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
|
* synchronized.
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _glfw3_native_h_ */
|
||||||
|
|
195
external/glfw-3.3.8/src/CMakeLists.txt
vendored
Normal file
195
external/glfw-3.3.8/src/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
|
||||||
|
set(common_HEADERS internal.h mappings.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)
|
||||||
|
|
||||||
|
add_custom_target(update_mappings
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -P "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" mappings.h.in mappings.h
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
COMMENT "Updating gamepad mappings from upstream repository"
|
||||||
|
SOURCES mappings.h.in "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake"
|
||||||
|
VERBATIM)
|
||||||
|
|
||||||
|
set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3")
|
||||||
|
|
||||||
|
if (_GLFW_COCOA)
|
||||||
|
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
||||||
|
posix_thread.h nsgl_context.h egl_context.h osmesa_context.h)
|
||||||
|
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
|
||||||
|
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
|
||||||
|
nsgl_context.m egl_context.c osmesa_context.c)
|
||||||
|
elseif (_GLFW_WIN32)
|
||||||
|
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
|
||||||
|
wgl_context.h egl_context.h osmesa_context.h)
|
||||||
|
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
|
||||||
|
win32_monitor.c win32_time.c win32_thread.c win32_window.c
|
||||||
|
wgl_context.c egl_context.c osmesa_context.c)
|
||||||
|
elseif (_GLFW_X11)
|
||||||
|
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h
|
||||||
|
posix_thread.h glx_context.h egl_context.h osmesa_context.h)
|
||||||
|
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
|
||||||
|
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
|
||||||
|
egl_context.c osmesa_context.c)
|
||||||
|
elseif (_GLFW_WAYLAND)
|
||||||
|
set(glfw_HEADERS ${common_HEADERS} wl_platform.h
|
||||||
|
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
|
||||||
|
osmesa_context.h)
|
||||||
|
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
|
||||||
|
posix_time.c posix_thread.c xkb_unicode.c
|
||||||
|
egl_context.c osmesa_context.c)
|
||||||
|
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
|
||||||
|
BASENAME xdg-shell)
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
|
||||||
|
BASENAME xdg-decoration)
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
|
||||||
|
BASENAME viewporter)
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
|
||||||
|
BASENAME relative-pointer-unstable-v1)
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
|
||||||
|
BASENAME pointer-constraints-unstable-v1)
|
||||||
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
|
PROTOCOL
|
||||||
|
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
|
||||||
|
BASENAME idle-inhibit-unstable-v1)
|
||||||
|
elseif (_GLFW_OSMESA)
|
||||||
|
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
|
||||||
|
posix_time.h posix_thread.h osmesa_context.h)
|
||||||
|
set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c
|
||||||
|
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (_GLFW_X11 OR _GLFW_WAYLAND)
|
||||||
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
|
||||||
|
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
|
||||||
|
else()
|
||||||
|
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
|
||||||
|
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Workaround for CMake not knowing about .m files before version 3.16
|
||||||
|
if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE)
|
||||||
|
set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
|
||||||
|
cocoa_window.m nsgl_context.m PROPERTIES
|
||||||
|
LANGUAGE C)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
||||||
|
set_target_properties(glfw PROPERTIES
|
||||||
|
OUTPUT_NAME ${GLFW_LIB_NAME}
|
||||||
|
VERSION ${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}
|
||||||
|
SOVERSION ${GLFW_VERSION_MAJOR}
|
||||||
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
FOLDER "GLFW3")
|
||||||
|
|
||||||
|
if (CMAKE_VERSION VERSION_EQUAL "3.1.0" OR
|
||||||
|
CMAKE_VERSION VERSION_GREATER "3.1.0")
|
||||||
|
|
||||||
|
set_target_properties(glfw PROPERTIES C_STANDARD 99)
|
||||||
|
else()
|
||||||
|
# Remove this fallback when removing support for CMake version less than 3.1
|
||||||
|
target_compile_options(glfw PRIVATE
|
||||||
|
"$<$<C_COMPILER_ID:AppleClang>:-std=c99>"
|
||||||
|
"$<$<C_COMPILER_ID:Clang>:-std=c99>"
|
||||||
|
"$<$<C_COMPILER_ID:GNU>:-std=c99>")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H)
|
||||||
|
target_include_directories(glfw PUBLIC
|
||||||
|
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
||||||
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||||
|
target_include_directories(glfw PRIVATE
|
||||||
|
"${GLFW_SOURCE_DIR}/src"
|
||||||
|
"${GLFW_BINARY_DIR}/src"
|
||||||
|
${glfw_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
|
||||||
|
|
||||||
|
# Make GCC warn about declarations that VS 2010 and 2012 won't accept for all
|
||||||
|
# source files that VS will build (Clang ignores this because we set -std=c99)
|
||||||
|
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set_source_files_properties(context.c init.c input.c monitor.c vulkan.c
|
||||||
|
window.c win32_init.c win32_joystick.c
|
||||||
|
win32_monitor.c win32_time.c win32_thread.c
|
||||||
|
win32_window.c wgl_context.c egl_context.c
|
||||||
|
osmesa_context.c PROPERTIES
|
||||||
|
COMPILE_FLAGS -Wdeclaration-after-statement)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Enable a reasonable set of warnings
|
||||||
|
# NOTE: The order matters here, Clang-CL matches both MSVC and Clang
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_options(glfw PRIVATE "/W3")
|
||||||
|
elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
|
||||||
|
CMAKE_C_COMPILER_ID STREQUAL "Clang" OR
|
||||||
|
CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||||
|
|
||||||
|
target_compile_options(glfw PRIVATE "-Wall")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (_GLFW_WIN32)
|
||||||
|
target_compile_definitions(glfw PRIVATE UNICODE _UNICODE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
if (MINGW)
|
||||||
|
target_compile_definitions(glfw PRIVATE WINVER=0x0501)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
if (WIN32)
|
||||||
|
if (MINGW)
|
||||||
|
# Remove the dependency on the shared version of libgcc
|
||||||
|
# NOTE: MinGW-w64 has the correct default but MinGW needs this
|
||||||
|
target_link_libraries(glfw PRIVATE "-static-libgcc")
|
||||||
|
|
||||||
|
# Remove the lib prefix on the DLL (but not the import library)
|
||||||
|
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()
|
||||||
|
|
||||||
|
target_compile_definitions(glfw INTERFACE GLFW_DLL)
|
||||||
|
elseif (APPLE)
|
||||||
|
# Add -fno-common to work around a bug in Apple's GCC
|
||||||
|
target_compile_options(glfw PRIVATE "-fno-common")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
# Hide symbols not explicitly tagged for export from the shared library
|
||||||
|
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
|
||||||
|
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (GLFW_INSTALL)
|
||||||
|
install(TARGETS glfw
|
||||||
|
EXPORT glfwTargets
|
||||||
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||||
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
endif()
|
||||||
|
|
633
external/glfw-3.3.8/src/cocoa_init.m
vendored
Normal file
633
external/glfw-3.3.8/src/cocoa_init.m
vendored
Normal file
@ -0,0 +1,633 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 macOS - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include <sys/param.h> // For MAXPATHLEN
|
||||||
|
|
||||||
|
// Needed for _NSGetProgname
|
||||||
|
#include <crt_externs.h>
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the menu bar (manually)
|
||||||
|
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
|
||||||
|
// could go away at any moment, lots of stuff that really should be
|
||||||
|
// localize(d|able), etc. Add a nib to save us this horror.
|
||||||
|
//
|
||||||
|
static void createMenuBar(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
NSString* appName = nil;
|
||||||
|
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
|
||||||
|
NSString* nameKeys[] =
|
||||||
|
{
|
||||||
|
@"CFBundleDisplayName",
|
||||||
|
@"CFBundleName",
|
||||||
|
@"CFBundleExecutable",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try to figure out what the calling application is called
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
|
||||||
|
{
|
||||||
|
id name = bundleInfo[nameKeys[i]];
|
||||||
|
if (name &&
|
||||||
|
[name isKindOfClass:[NSString class]] &&
|
||||||
|
![name isEqualToString:@""])
|
||||||
|
{
|
||||||
|
appName = name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!appName)
|
||||||
|
{
|
||||||
|
char** progname = _NSGetProgname();
|
||||||
|
if (progname && *progname)
|
||||||
|
appName = @(*progname);
|
||||||
|
else
|
||||||
|
appName = @"GLFW Application";
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMenu* bar = [[NSMenu alloc] init];
|
||||||
|
[NSApp setMainMenu:bar];
|
||||||
|
|
||||||
|
NSMenuItem* appMenuItem =
|
||||||
|
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
|
||||||
|
NSMenu* appMenu = [[NSMenu alloc] init];
|
||||||
|
[appMenuItem setSubmenu:appMenu];
|
||||||
|
|
||||||
|
[appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
|
||||||
|
action:@selector(orderFrontStandardAboutPanel:)
|
||||||
|
keyEquivalent:@""];
|
||||||
|
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
NSMenu* servicesMenu = [[NSMenu alloc] init];
|
||||||
|
[NSApp setServicesMenu:servicesMenu];
|
||||||
|
[[appMenu addItemWithTitle:@"Services"
|
||||||
|
action:NULL
|
||||||
|
keyEquivalent:@""] setSubmenu:servicesMenu];
|
||||||
|
[servicesMenu release];
|
||||||
|
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
|
||||||
|
action:@selector(hide:)
|
||||||
|
keyEquivalent:@"h"];
|
||||||
|
[[appMenu addItemWithTitle:@"Hide Others"
|
||||||
|
action:@selector(hideOtherApplications:)
|
||||||
|
keyEquivalent:@"h"]
|
||||||
|
setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
|
||||||
|
[appMenu addItemWithTitle:@"Show All"
|
||||||
|
action:@selector(unhideAllApplications:)
|
||||||
|
keyEquivalent:@""];
|
||||||
|
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
|
||||||
|
action:@selector(terminate:)
|
||||||
|
keyEquivalent:@"q"];
|
||||||
|
|
||||||
|
NSMenuItem* windowMenuItem =
|
||||||
|
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
|
||||||
|
[bar release];
|
||||||
|
NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||||
|
[NSApp setWindowsMenu:windowMenu];
|
||||||
|
[windowMenuItem setSubmenu:windowMenu];
|
||||||
|
|
||||||
|
[windowMenu addItemWithTitle:@"Minimize"
|
||||||
|
action:@selector(performMiniaturize:)
|
||||||
|
keyEquivalent:@"m"];
|
||||||
|
[windowMenu addItemWithTitle:@"Zoom"
|
||||||
|
action:@selector(performZoom:)
|
||||||
|
keyEquivalent:@""];
|
||||||
|
[windowMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
[windowMenu addItemWithTitle:@"Bring All to Front"
|
||||||
|
action:@selector(arrangeInFront:)
|
||||||
|
keyEquivalent:@""];
|
||||||
|
|
||||||
|
// TODO: Make this appear at the bottom of the menu (for consistency)
|
||||||
|
[windowMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
[[windowMenu addItemWithTitle:@"Enter Full Screen"
|
||||||
|
action:@selector(toggleFullScreen:)
|
||||||
|
keyEquivalent:@"f"]
|
||||||
|
setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
|
||||||
|
|
||||||
|
// Prior to Snow Leopard, we need to use this oddly-named semi-private API
|
||||||
|
// to get the application menu working properly.
|
||||||
|
SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:");
|
||||||
|
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create key code translation tables
|
||||||
|
//
|
||||||
|
static void createKeyTables(void)
|
||||||
|
{
|
||||||
|
int scancode;
|
||||||
|
|
||||||
|
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
|
||||||
|
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
|
||||||
|
|
||||||
|
_glfw.ns.keycodes[0x1D] = GLFW_KEY_0;
|
||||||
|
_glfw.ns.keycodes[0x12] = GLFW_KEY_1;
|
||||||
|
_glfw.ns.keycodes[0x13] = GLFW_KEY_2;
|
||||||
|
_glfw.ns.keycodes[0x14] = GLFW_KEY_3;
|
||||||
|
_glfw.ns.keycodes[0x15] = GLFW_KEY_4;
|
||||||
|
_glfw.ns.keycodes[0x17] = GLFW_KEY_5;
|
||||||
|
_glfw.ns.keycodes[0x16] = GLFW_KEY_6;
|
||||||
|
_glfw.ns.keycodes[0x1A] = GLFW_KEY_7;
|
||||||
|
_glfw.ns.keycodes[0x1C] = GLFW_KEY_8;
|
||||||
|
_glfw.ns.keycodes[0x19] = GLFW_KEY_9;
|
||||||
|
_glfw.ns.keycodes[0x00] = GLFW_KEY_A;
|
||||||
|
_glfw.ns.keycodes[0x0B] = GLFW_KEY_B;
|
||||||
|
_glfw.ns.keycodes[0x08] = GLFW_KEY_C;
|
||||||
|
_glfw.ns.keycodes[0x02] = GLFW_KEY_D;
|
||||||
|
_glfw.ns.keycodes[0x0E] = GLFW_KEY_E;
|
||||||
|
_glfw.ns.keycodes[0x03] = GLFW_KEY_F;
|
||||||
|
_glfw.ns.keycodes[0x05] = GLFW_KEY_G;
|
||||||
|
_glfw.ns.keycodes[0x04] = GLFW_KEY_H;
|
||||||
|
_glfw.ns.keycodes[0x22] = GLFW_KEY_I;
|
||||||
|
_glfw.ns.keycodes[0x26] = GLFW_KEY_J;
|
||||||
|
_glfw.ns.keycodes[0x28] = GLFW_KEY_K;
|
||||||
|
_glfw.ns.keycodes[0x25] = GLFW_KEY_L;
|
||||||
|
_glfw.ns.keycodes[0x2E] = GLFW_KEY_M;
|
||||||
|
_glfw.ns.keycodes[0x2D] = GLFW_KEY_N;
|
||||||
|
_glfw.ns.keycodes[0x1F] = GLFW_KEY_O;
|
||||||
|
_glfw.ns.keycodes[0x23] = GLFW_KEY_P;
|
||||||
|
_glfw.ns.keycodes[0x0C] = GLFW_KEY_Q;
|
||||||
|
_glfw.ns.keycodes[0x0F] = GLFW_KEY_R;
|
||||||
|
_glfw.ns.keycodes[0x01] = GLFW_KEY_S;
|
||||||
|
_glfw.ns.keycodes[0x11] = GLFW_KEY_T;
|
||||||
|
_glfw.ns.keycodes[0x20] = GLFW_KEY_U;
|
||||||
|
_glfw.ns.keycodes[0x09] = GLFW_KEY_V;
|
||||||
|
_glfw.ns.keycodes[0x0D] = GLFW_KEY_W;
|
||||||
|
_glfw.ns.keycodes[0x07] = GLFW_KEY_X;
|
||||||
|
_glfw.ns.keycodes[0x10] = GLFW_KEY_Y;
|
||||||
|
_glfw.ns.keycodes[0x06] = GLFW_KEY_Z;
|
||||||
|
|
||||||
|
_glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE;
|
||||||
|
_glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH;
|
||||||
|
_glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA;
|
||||||
|
_glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL;
|
||||||
|
_glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT;
|
||||||
|
_glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET;
|
||||||
|
_glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS;
|
||||||
|
_glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD;
|
||||||
|
_glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET;
|
||||||
|
_glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON;
|
||||||
|
_glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH;
|
||||||
|
_glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1;
|
||||||
|
|
||||||
|
_glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE;
|
||||||
|
_glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK;
|
||||||
|
_glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE;
|
||||||
|
_glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN;
|
||||||
|
_glfw.ns.keycodes[0x77] = GLFW_KEY_END;
|
||||||
|
_glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER;
|
||||||
|
_glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE;
|
||||||
|
_glfw.ns.keycodes[0x7A] = GLFW_KEY_F1;
|
||||||
|
_glfw.ns.keycodes[0x78] = GLFW_KEY_F2;
|
||||||
|
_glfw.ns.keycodes[0x63] = GLFW_KEY_F3;
|
||||||
|
_glfw.ns.keycodes[0x76] = GLFW_KEY_F4;
|
||||||
|
_glfw.ns.keycodes[0x60] = GLFW_KEY_F5;
|
||||||
|
_glfw.ns.keycodes[0x61] = GLFW_KEY_F6;
|
||||||
|
_glfw.ns.keycodes[0x62] = GLFW_KEY_F7;
|
||||||
|
_glfw.ns.keycodes[0x64] = GLFW_KEY_F8;
|
||||||
|
_glfw.ns.keycodes[0x65] = GLFW_KEY_F9;
|
||||||
|
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
|
||||||
|
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
|
||||||
|
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
|
||||||
|
_glfw.ns.keycodes[0x69] = GLFW_KEY_F13;
|
||||||
|
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
|
||||||
|
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
|
||||||
|
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
|
||||||
|
_glfw.ns.keycodes[0x40] = GLFW_KEY_F17;
|
||||||
|
_glfw.ns.keycodes[0x4F] = GLFW_KEY_F18;
|
||||||
|
_glfw.ns.keycodes[0x50] = GLFW_KEY_F19;
|
||||||
|
_glfw.ns.keycodes[0x5A] = GLFW_KEY_F20;
|
||||||
|
_glfw.ns.keycodes[0x73] = GLFW_KEY_HOME;
|
||||||
|
_glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT;
|
||||||
|
_glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT;
|
||||||
|
_glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT;
|
||||||
|
_glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL;
|
||||||
|
_glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT;
|
||||||
|
_glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER;
|
||||||
|
_glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU;
|
||||||
|
_glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK;
|
||||||
|
_glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN;
|
||||||
|
_glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP;
|
||||||
|
_glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT;
|
||||||
|
_glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT;
|
||||||
|
_glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
_glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT;
|
||||||
|
_glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER;
|
||||||
|
_glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE;
|
||||||
|
_glfw.ns.keycodes[0x30] = GLFW_KEY_TAB;
|
||||||
|
_glfw.ns.keycodes[0x7E] = GLFW_KEY_UP;
|
||||||
|
|
||||||
|
_glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0;
|
||||||
|
_glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1;
|
||||||
|
_glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2;
|
||||||
|
_glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3;
|
||||||
|
_glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4;
|
||||||
|
_glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5;
|
||||||
|
_glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6;
|
||||||
|
_glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7;
|
||||||
|
_glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8;
|
||||||
|
_glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9;
|
||||||
|
_glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD;
|
||||||
|
_glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL;
|
||||||
|
_glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE;
|
||||||
|
_glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER;
|
||||||
|
_glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL;
|
||||||
|
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
|
||||||
|
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
|
||||||
|
|
||||||
|
for (scancode = 0; scancode < 256; scancode++)
|
||||||
|
{
|
||||||
|
// Store the reverse translation for faster key name lookup
|
||||||
|
if (_glfw.ns.keycodes[scancode] >= 0)
|
||||||
|
_glfw.ns.scancodes[_glfw.ns.keycodes[scancode]] = scancode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve Unicode data for the current keyboard layout
|
||||||
|
//
|
||||||
|
static GLFWbool updateUnicodeDataNS(void)
|
||||||
|
{
|
||||||
|
if (_glfw.ns.inputSource)
|
||||||
|
{
|
||||||
|
CFRelease(_glfw.ns.inputSource);
|
||||||
|
_glfw.ns.inputSource = NULL;
|
||||||
|
_glfw.ns.unicodeData = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
|
||||||
|
if (!_glfw.ns.inputSource)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to retrieve keyboard layout input source");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.ns.unicodeData =
|
||||||
|
TISGetInputSourceProperty(_glfw.ns.inputSource,
|
||||||
|
kTISPropertyUnicodeKeyLayoutData);
|
||||||
|
if (!_glfw.ns.unicodeData)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to retrieve keyboard layout Unicode data");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load HIToolbox.framework and the TIS symbols we need from it
|
||||||
|
//
|
||||||
|
static GLFWbool initializeTIS(void)
|
||||||
|
{
|
||||||
|
// This works only because Cocoa has already loaded it properly
|
||||||
|
_glfw.ns.tis.bundle =
|
||||||
|
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
|
||||||
|
if (!_glfw.ns.tis.bundle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to load HIToolbox.framework");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFStringRef* kPropertyUnicodeKeyLayoutData =
|
||||||
|
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
|
||||||
|
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
|
||||||
|
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
|
||||||
|
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||||
|
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
|
||||||
|
_glfw.ns.tis.GetInputSourceProperty =
|
||||||
|
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||||
|
CFSTR("TISGetInputSourceProperty"));
|
||||||
|
_glfw.ns.tis.GetKbdType =
|
||||||
|
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||||
|
CFSTR("LMGetKbdType"));
|
||||||
|
|
||||||
|
if (!kPropertyUnicodeKeyLayoutData ||
|
||||||
|
!TISCopyCurrentKeyboardLayoutInputSource ||
|
||||||
|
!TISGetInputSourceProperty ||
|
||||||
|
!LMGetKbdType)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to load TIS API symbols");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
|
||||||
|
*kPropertyUnicodeKeyLayoutData;
|
||||||
|
|
||||||
|
return updateUnicodeDataNS();
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface GLFWHelper : NSObject
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GLFWHelper
|
||||||
|
|
||||||
|
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
|
||||||
|
{
|
||||||
|
updateUnicodeDataNS();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)doNothing:(id)object
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@end // GLFWHelper
|
||||||
|
|
||||||
|
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GLFWApplicationDelegate
|
||||||
|
|
||||||
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||||
|
{
|
||||||
|
_GLFWwindow* window;
|
||||||
|
|
||||||
|
for (window = _glfw.windowListHead; window; window = window->next)
|
||||||
|
_glfwInputWindowCloseRequest(window);
|
||||||
|
|
||||||
|
return NSTerminateCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
||||||
|
{
|
||||||
|
_GLFWwindow* window;
|
||||||
|
|
||||||
|
for (window = _glfw.windowListHead; window; window = window->next)
|
||||||
|
{
|
||||||
|
if (window->context.client != GLFW_NO_API)
|
||||||
|
[window->context.nsgl.object update];
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPollMonitorsNS();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationWillFinishLaunching:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
if (_glfw.hints.init.ns.menubar)
|
||||||
|
{
|
||||||
|
// Menu bar setup must go between sharedApplication and finishLaunching
|
||||||
|
// in order to properly emulate the behavior of NSApplicationMain
|
||||||
|
|
||||||
|
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
|
||||||
|
{
|
||||||
|
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
|
||||||
|
owner:NSApp
|
||||||
|
topLevelObjects:&_glfw.ns.nibObjects];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
createMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
_glfw.ns.finishedLaunching = GLFW_TRUE;
|
||||||
|
_glfwPlatformPostEmptyEvent();
|
||||||
|
|
||||||
|
// In case we are unbundled, make us a proper UI application
|
||||||
|
if (_glfw.hints.init.ns.menubar)
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
|
[NSApp stop:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationDidHide:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
_glfwRestoreVideoModeNS(_glfw.monitors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end // GLFWApplicationDelegate
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void* _glfwLoadLocalVulkanLoaderNS(void)
|
||||||
|
{
|
||||||
|
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||||
|
if (!bundle)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
|
||||||
|
if (!frameworksUrl)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
|
||||||
|
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
|
||||||
|
if (!loaderUrl)
|
||||||
|
{
|
||||||
|
CFRelease(frameworksUrl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
void* handle = NULL;
|
||||||
|
|
||||||
|
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
|
||||||
|
handle = _glfw_dlopen(path);
|
||||||
|
|
||||||
|
CFRelease(loaderUrl);
|
||||||
|
CFRelease(frameworksUrl);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformInit(void)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
_glfw.ns.helper = [[GLFWHelper alloc] init];
|
||||||
|
|
||||||
|
[NSThread detachNewThreadSelector:@selector(doNothing:)
|
||||||
|
toTarget:_glfw.ns.helper
|
||||||
|
withObject:nil];
|
||||||
|
|
||||||
|
if (NSApp)
|
||||||
|
_glfw.ns.finishedLaunching = GLFW_TRUE;
|
||||||
|
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
|
_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];
|
||||||
|
|
||||||
|
NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
|
||||||
|
{
|
||||||
|
if ([event modifierFlags] & NSEventModifierFlagCommand)
|
||||||
|
[[NSApp keyWindow] sendEvent:event];
|
||||||
|
|
||||||
|
return event;
|
||||||
|
};
|
||||||
|
|
||||||
|
_glfw.ns.keyUpMonitor =
|
||||||
|
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
|
||||||
|
handler:block];
|
||||||
|
|
||||||
|
if (_glfw.hints.init.ns.chdir)
|
||||||
|
changeToResourcesDirectory();
|
||||||
|
|
||||||
|
// Press and Hold prevents some keys from emitting repeated characters
|
||||||
|
NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
|
||||||
|
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
addObserver:_glfw.ns.helper
|
||||||
|
selector:@selector(selectedKeyboardInputSourceChanged:)
|
||||||
|
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||||
|
object:nil];
|
||||||
|
|
||||||
|
createKeyTables();
|
||||||
|
|
||||||
|
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||||
|
if (!_glfw.ns.eventSource)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
|
||||||
|
|
||||||
|
if (!initializeTIS())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
_glfwInitTimerNS();
|
||||||
|
_glfwInitJoysticksNS();
|
||||||
|
|
||||||
|
_glfwPollMonitorsNS();
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformTerminate(void)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
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.helper)
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
removeObserver:_glfw.ns.helper
|
||||||
|
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||||
|
object:nil];
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
removeObserver:_glfw.ns.helper];
|
||||||
|
[_glfw.ns.helper release];
|
||||||
|
_glfw.ns.helper = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.ns.keyUpMonitor)
|
||||||
|
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
|
||||||
|
|
||||||
|
free(_glfw.ns.clipboardString);
|
||||||
|
|
||||||
|
_glfwTerminateNSGL();
|
||||||
|
_glfwTerminateEGL();
|
||||||
|
_glfwTerminateOSMesa();
|
||||||
|
_glfwTerminateJoysticksNS();
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
|
{
|
||||||
|
return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa"
|
||||||
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
|
" dynamic"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
51
external/glfw-3.3.8/src/cocoa_joystick.h
vendored
Normal file
51
external/glfw-3.3.8/src/cocoa_joystick.h
vendored
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Cocoa - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/IOCFPlugIn.h>
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
#include <IOKit/hid/IOHIDKeys.h>
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyJoystick; }
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
|
||||||
|
#define GLFW_BUILD_COCOA_MAPPINGS
|
||||||
|
|
||||||
|
// Cocoa-specific per-joystick data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWjoystickNS
|
||||||
|
{
|
||||||
|
IOHIDDeviceRef device;
|
||||||
|
CFMutableArrayRef axes;
|
||||||
|
CFMutableArrayRef buttons;
|
||||||
|
CFMutableArrayRef hats;
|
||||||
|
} _GLFWjoystickNS;
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwInitJoysticksNS(void);
|
||||||
|
void _glfwTerminateJoysticksNS(void);
|
||||||
|
|
488
external/glfw-3.3.8/src/cocoa_joystick.m
vendored
Normal file
488
external/glfw-3.3.8/src/cocoa_joystick.m
vendored
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Cocoa - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/mach_error.h>
|
||||||
|
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Joystick element information
|
||||||
|
//
|
||||||
|
typedef struct _GLFWjoyelementNS
|
||||||
|
{
|
||||||
|
IOHIDElementRef native;
|
||||||
|
uint32_t usage;
|
||||||
|
int index;
|
||||||
|
long minimum;
|
||||||
|
long maximum;
|
||||||
|
|
||||||
|
} _GLFWjoyelementNS;
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the value of the specified element of the specified joystick
|
||||||
|
//
|
||||||
|
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
|
||||||
|
{
|
||||||
|
IOHIDValueRef valueRef;
|
||||||
|
long value = 0;
|
||||||
|
|
||||||
|
if (js->ns.device)
|
||||||
|
{
|
||||||
|
if (IOHIDDeviceGetValue(js->ns.device,
|
||||||
|
element->native,
|
||||||
|
&valueRef) == kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
value = IOHIDValueGetIntegerValue(valueRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison function for matching the SDL element order
|
||||||
|
//
|
||||||
|
static CFComparisonResult compareElements(const void* fp,
|
||||||
|
const void* sp,
|
||||||
|
void* user)
|
||||||
|
{
|
||||||
|
const _GLFWjoyelementNS* fe = fp;
|
||||||
|
const _GLFWjoyelementNS* se = sp;
|
||||||
|
if (fe->usage < se->usage)
|
||||||
|
return kCFCompareLessThan;
|
||||||
|
if (fe->usage > se->usage)
|
||||||
|
return kCFCompareGreaterThan;
|
||||||
|
if (fe->index < se->index)
|
||||||
|
return kCFCompareLessThan;
|
||||||
|
if (fe->index > se->index)
|
||||||
|
return kCFCompareGreaterThan;
|
||||||
|
return kCFCompareEqualTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the specified joystick
|
||||||
|
//
|
||||||
|
static void closeJoystick(_GLFWjoystick* js)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||||
|
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||||
|
CFRelease(js->ns.axes);
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||||
|
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
||||||
|
CFRelease(js->ns.buttons);
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||||
|
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
|
||||||
|
CFRelease(js->ns.hats);
|
||||||
|
|
||||||
|
_glfwFreeJoystick(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback for user-initiated joystick addition
|
||||||
|
//
|
||||||
|
static void matchCallback(void* context,
|
||||||
|
IOReturn result,
|
||||||
|
void* sender,
|
||||||
|
IOHIDDeviceRef device)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
char name[256];
|
||||||
|
char guid[33];
|
||||||
|
CFIndex i;
|
||||||
|
CFTypeRef property;
|
||||||
|
uint32_t vendor = 0, product = 0, version = 0;
|
||||||
|
_GLFWjoystick* js;
|
||||||
|
CFMutableArrayRef axes, buttons, hats;
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (_glfw.joysticks[jid].ns.device == device)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axes = CFArrayCreateMutable(NULL, 0, NULL);
|
||||||
|
buttons = CFArrayCreateMutable(NULL, 0, NULL);
|
||||||
|
hats = CFArrayCreateMutable(NULL, 0, NULL);
|
||||||
|
|
||||||
|
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
||||||
|
if (property)
|
||||||
|
{
|
||||||
|
CFStringGetCString(property,
|
||||||
|
name,
|
||||||
|
sizeof(name),
|
||||||
|
kCFStringEncodingUTF8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strncpy(name, "Unknown", sizeof(name));
|
||||||
|
|
||||||
|
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
|
||||||
|
if (property)
|
||||||
|
CFNumberGetValue(property, kCFNumberSInt32Type, &vendor);
|
||||||
|
|
||||||
|
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
|
||||||
|
if (property)
|
||||||
|
CFNumberGetValue(property, kCFNumberSInt32Type, &product);
|
||||||
|
|
||||||
|
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey));
|
||||||
|
if (property)
|
||||||
|
CFNumberGetValue(property, kCFNumberSInt32Type, &version);
|
||||||
|
|
||||||
|
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||||
|
if (vendor && product)
|
||||||
|
{
|
||||||
|
sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
|
||||||
|
(uint8_t) vendor, (uint8_t) (vendor >> 8),
|
||||||
|
(uint8_t) product, (uint8_t) (product >> 8),
|
||||||
|
(uint8_t) version, (uint8_t) (version >> 8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||||
|
name[0], name[1], name[2], name[3],
|
||||||
|
name[4], name[5], name[6], name[7],
|
||||||
|
name[8], name[9], name[10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFArrayRef elements =
|
||||||
|
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(elements); i++)
|
||||||
|
{
|
||||||
|
IOHIDElementRef native = (IOHIDElementRef)
|
||||||
|
CFArrayGetValueAtIndex(elements, i);
|
||||||
|
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const IOHIDElementType type = IOHIDElementGetType(native);
|
||||||
|
if ((type != kIOHIDElementTypeInput_Axis) &&
|
||||||
|
(type != kIOHIDElementTypeInput_Button) &&
|
||||||
|
(type != kIOHIDElementTypeInput_Misc))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFMutableArrayRef target = NULL;
|
||||||
|
|
||||||
|
const uint32_t usage = IOHIDElementGetUsage(native);
|
||||||
|
const uint32_t page = IOHIDElementGetUsagePage(native);
|
||||||
|
if (page == kHIDPage_GenericDesktop)
|
||||||
|
{
|
||||||
|
switch (usage)
|
||||||
|
{
|
||||||
|
case kHIDUsage_GD_X:
|
||||||
|
case kHIDUsage_GD_Y:
|
||||||
|
case kHIDUsage_GD_Z:
|
||||||
|
case kHIDUsage_GD_Rx:
|
||||||
|
case kHIDUsage_GD_Ry:
|
||||||
|
case kHIDUsage_GD_Rz:
|
||||||
|
case kHIDUsage_GD_Slider:
|
||||||
|
case kHIDUsage_GD_Dial:
|
||||||
|
case kHIDUsage_GD_Wheel:
|
||||||
|
target = axes;
|
||||||
|
break;
|
||||||
|
case kHIDUsage_GD_Hatswitch:
|
||||||
|
target = hats;
|
||||||
|
break;
|
||||||
|
case kHIDUsage_GD_DPadUp:
|
||||||
|
case kHIDUsage_GD_DPadRight:
|
||||||
|
case kHIDUsage_GD_DPadDown:
|
||||||
|
case kHIDUsage_GD_DPadLeft:
|
||||||
|
case kHIDUsage_GD_SystemMainMenu:
|
||||||
|
case kHIDUsage_GD_Select:
|
||||||
|
case kHIDUsage_GD_Start:
|
||||||
|
target = buttons;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (page == kHIDPage_Simulation)
|
||||||
|
{
|
||||||
|
switch (usage)
|
||||||
|
{
|
||||||
|
case kHIDUsage_Sim_Accelerator:
|
||||||
|
case kHIDUsage_Sim_Brake:
|
||||||
|
case kHIDUsage_Sim_Throttle:
|
||||||
|
case kHIDUsage_Sim_Rudder:
|
||||||
|
case kHIDUsage_Sim_Steering:
|
||||||
|
target = axes;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
|
||||||
|
target = buttons;
|
||||||
|
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
|
||||||
|
element->native = native;
|
||||||
|
element->usage = usage;
|
||||||
|
element->index = (int) CFArrayGetCount(target);
|
||||||
|
element->minimum = IOHIDElementGetLogicalMin(native);
|
||||||
|
element->maximum = IOHIDElementGetLogicalMax(native);
|
||||||
|
CFArrayAppendValue(target, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(elements);
|
||||||
|
|
||||||
|
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
|
||||||
|
compareElements, NULL);
|
||||||
|
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
|
||||||
|
compareElements, NULL);
|
||||||
|
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
|
||||||
|
compareElements, NULL);
|
||||||
|
|
||||||
|
js = _glfwAllocJoystick(name, guid,
|
||||||
|
(int) CFArrayGetCount(axes),
|
||||||
|
(int) CFArrayGetCount(buttons),
|
||||||
|
(int) CFArrayGetCount(hats));
|
||||||
|
|
||||||
|
js->ns.device = device;
|
||||||
|
js->ns.axes = axes;
|
||||||
|
js->ns.buttons = buttons;
|
||||||
|
js->ns.hats = hats;
|
||||||
|
|
||||||
|
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback for user-initiated joystick removal
|
||||||
|
//
|
||||||
|
static void removeCallback(void* context,
|
||||||
|
IOReturn result,
|
||||||
|
void* sender,
|
||||||
|
IOHIDDeviceRef device)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
|
||||||
|
{
|
||||||
|
closeJoystick(&_glfw.joysticks[jid]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize joystick interface
|
||||||
|
//
|
||||||
|
void _glfwInitJoysticksNS(void)
|
||||||
|
{
|
||||||
|
CFMutableArrayRef matching;
|
||||||
|
const long usages[] =
|
||||||
|
{
|
||||||
|
kHIDUsage_GD_Joystick,
|
||||||
|
kHIDUsage_GD_GamePad,
|
||||||
|
kHIDUsage_GD_MultiAxisController
|
||||||
|
};
|
||||||
|
|
||||||
|
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
|
||||||
|
kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
|
matching = CFArrayCreateMutable(kCFAllocatorDefault,
|
||||||
|
0,
|
||||||
|
&kCFTypeArrayCallBacks);
|
||||||
|
if (!matching)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||||
|
{
|
||||||
|
const long page = kHIDPage_GenericDesktop;
|
||||||
|
|
||||||
|
CFMutableDictionaryRef dict =
|
||||||
|
CFDictionaryCreateMutable(kCFAllocatorDefault,
|
||||||
|
0,
|
||||||
|
&kCFTypeDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
if (!dict)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
|
||||||
|
kCFNumberLongType,
|
||||||
|
&page);
|
||||||
|
CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
|
||||||
|
kCFNumberLongType,
|
||||||
|
&usages[i]);
|
||||||
|
if (pageRef && usageRef)
|
||||||
|
{
|
||||||
|
CFDictionarySetValue(dict,
|
||||||
|
CFSTR(kIOHIDDeviceUsagePageKey),
|
||||||
|
pageRef);
|
||||||
|
CFDictionarySetValue(dict,
|
||||||
|
CFSTR(kIOHIDDeviceUsageKey),
|
||||||
|
usageRef);
|
||||||
|
CFArrayAppendValue(matching, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageRef)
|
||||||
|
CFRelease(pageRef);
|
||||||
|
if (usageRef)
|
||||||
|
CFRelease(usageRef);
|
||||||
|
|
||||||
|
CFRelease(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching);
|
||||||
|
CFRelease(matching);
|
||||||
|
|
||||||
|
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
|
||||||
|
&matchCallback, NULL);
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
|
||||||
|
&removeCallback, NULL);
|
||||||
|
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
|
||||||
|
CFRunLoopGetMain(),
|
||||||
|
kCFRunLoopDefaultMode);
|
||||||
|
IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
|
// Execute the run loop once in order to register any initially-attached
|
||||||
|
// joysticks
|
||||||
|
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close all opened joystick handles
|
||||||
|
//
|
||||||
|
void _glfwTerminateJoysticksNS(void)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (_glfw.joysticks[jid].connected)
|
||||||
|
closeJoystick(&_glfw.joysticks[jid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(_glfw.ns.hidManager);
|
||||||
|
_glfw.ns.hidManager = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
|
{
|
||||||
|
if (mode & _GLFW_POLL_AXES)
|
||||||
|
{
|
||||||
|
CFIndex i;
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
|
||||||
|
CFArrayGetValueAtIndex(js->ns.axes, i);
|
||||||
|
|
||||||
|
const long raw = getElementValue(js, axis);
|
||||||
|
// Perform auto calibration
|
||||||
|
if (raw < axis->minimum)
|
||||||
|
axis->minimum = raw;
|
||||||
|
if (raw > axis->maximum)
|
||||||
|
axis->maximum = raw;
|
||||||
|
|
||||||
|
const long size = axis->maximum - axis->minimum;
|
||||||
|
if (size == 0)
|
||||||
|
_glfwInputJoystickAxis(js, (int) i, 0.f);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const float value = (2.f * (raw - axis->minimum) / size) - 1.f;
|
||||||
|
_glfwInputJoystickAxis(js, (int) i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & _GLFW_POLL_BUTTONS)
|
||||||
|
{
|
||||||
|
CFIndex i;
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
||||||
|
CFArrayGetValueAtIndex(js->ns.buttons, i);
|
||||||
|
const char value = getElementValue(js, button) - button->minimum;
|
||||||
|
const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
|
||||||
|
_glfwInputJoystickButton(js, (int) i, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||||
|
{
|
||||||
|
const int states[9] =
|
||||||
|
{
|
||||||
|
GLFW_HAT_UP,
|
||||||
|
GLFW_HAT_RIGHT_UP,
|
||||||
|
GLFW_HAT_RIGHT,
|
||||||
|
GLFW_HAT_RIGHT_DOWN,
|
||||||
|
GLFW_HAT_DOWN,
|
||||||
|
GLFW_HAT_LEFT_DOWN,
|
||||||
|
GLFW_HAT_LEFT,
|
||||||
|
GLFW_HAT_LEFT_UP,
|
||||||
|
GLFW_HAT_CENTERED
|
||||||
|
};
|
||||||
|
|
||||||
|
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
|
||||||
|
CFArrayGetValueAtIndex(js->ns.hats, i);
|
||||||
|
long state = getElementValue(js, hat) - hat->minimum;
|
||||||
|
if (state < 0 || state > 8)
|
||||||
|
state = 8;
|
||||||
|
|
||||||
|
_glfwInputJoystickHat(js, (int) i, states[state]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return js->connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||||
|
{
|
||||||
|
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
|
||||||
|
(strncmp(guid + 20, "000000000000", 12) == 0))
|
||||||
|
{
|
||||||
|
char original[33];
|
||||||
|
strncpy(original, guid, sizeof(original) - 1);
|
||||||
|
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||||
|
original, original + 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
627
external/glfw-3.3.8/src/cocoa_monitor.m
vendored
Normal file
627
external/glfw-3.3.8/src/cocoa_monitor.m
vendored
Normal file
@ -0,0 +1,627 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 macOS - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Get the name of the specified display, or NULL
|
||||||
|
//
|
||||||
|
static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
|
||||||
|
{
|
||||||
|
// IOKit doesn't work on Apple Silicon anymore
|
||||||
|
// Luckily, 10.15 introduced -[NSScreen localizedName].
|
||||||
|
// Use it if available, and fall back to IOKit otherwise.
|
||||||
|
if (screen)
|
||||||
|
{
|
||||||
|
if ([screen respondsToSelector:@selector(localizedName)])
|
||||||
|
{
|
||||||
|
NSString* name = [screen valueForKey:@"localizedName"];
|
||||||
|
if (name)
|
||||||
|
return _glfw_strdup([name UTF8String]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io_iterator_t it;
|
||||||
|
io_service_t service;
|
||||||
|
CFDictionaryRef info;
|
||||||
|
|
||||||
|
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
|
||||||
|
IOServiceMatching("IODisplayConnect"),
|
||||||
|
&it) != 0)
|
||||||
|
{
|
||||||
|
// This may happen if a desktop Mac is running headless
|
||||||
|
return _glfw_strdup("Display");
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
|
{
|
||||||
|
info = IODisplayCreateInfoDictionary(service,
|
||||||
|
kIODisplayOnlyPreferredName);
|
||||||
|
|
||||||
|
CFNumberRef vendorIDRef =
|
||||||
|
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
|
||||||
|
CFNumberRef productIDRef =
|
||||||
|
CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
|
||||||
|
if (!vendorIDRef || !productIDRef)
|
||||||
|
{
|
||||||
|
CFRelease(info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int vendorID, productID;
|
||||||
|
CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID);
|
||||||
|
CFNumberGetValue(productIDRef, kCFNumberIntType, &productID);
|
||||||
|
|
||||||
|
if (CGDisplayVendorNumber(displayID) == vendorID &&
|
||||||
|
CGDisplayModelNumber(displayID) == productID)
|
||||||
|
{
|
||||||
|
// Info dictionary is used and freed below
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOObjectRelease(it);
|
||||||
|
|
||||||
|
if (!service)
|
||||||
|
return _glfw_strdup("Display");
|
||||||
|
|
||||||
|
CFDictionaryRef names =
|
||||||
|
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
|
||||||
|
|
||||||
|
CFStringRef nameRef;
|
||||||
|
|
||||||
|
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
|
||||||
|
(const void**) &nameRef))
|
||||||
|
{
|
||||||
|
// This may happen if a desktop Mac is running headless
|
||||||
|
CFRelease(info);
|
||||||
|
return _glfw_strdup("Display");
|
||||||
|
}
|
||||||
|
|
||||||
|
const CFIndex size =
|
||||||
|
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
|
||||||
|
kCFStringEncodingUTF8);
|
||||||
|
char* name = calloc(size + 1, 1);
|
||||||
|
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
|
||||||
|
|
||||||
|
CFRelease(info);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the display mode should be included in enumeration
|
||||||
|
//
|
||||||
|
static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
||||||
|
{
|
||||||
|
uint32_t flags = CGDisplayModeGetIOFlags(mode);
|
||||||
|
|
||||||
|
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
if (flags & kDisplayModeInterlacedFlag)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
if (flags & kDisplayModeStretchedFlag)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
||||||
|
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
|
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
|
||||||
|
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
|
||||||
|
{
|
||||||
|
CFRelease(format);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(format);
|
||||||
|
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert Core Graphics display mode to GLFW video mode
|
||||||
|
//
|
||||||
|
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
||||||
|
double fallbackRefreshRate)
|
||||||
|
{
|
||||||
|
GLFWvidmode result;
|
||||||
|
result.width = (int) CGDisplayModeGetWidth(mode);
|
||||||
|
result.height = (int) CGDisplayModeGetHeight(mode);
|
||||||
|
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
|
||||||
|
|
||||||
|
if (result.refreshRate == 0)
|
||||||
|
result.refreshRate = (int) round(fallbackRefreshRate);
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
||||||
|
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
|
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
|
||||||
|
{
|
||||||
|
result.redBits = 5;
|
||||||
|
result.greenBits = 5;
|
||||||
|
result.blueBits = 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
||||||
|
{
|
||||||
|
result.redBits = 8;
|
||||||
|
result.greenBits = 8;
|
||||||
|
result.blueBits = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
||||||
|
CFRelease(format);
|
||||||
|
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts reservation for display fading
|
||||||
|
//
|
||||||
|
static CGDisplayFadeReservationToken beginFadeReservation(void)
|
||||||
|
{
|
||||||
|
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
|
||||||
|
|
||||||
|
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
|
||||||
|
{
|
||||||
|
CGDisplayFade(token, 0.3,
|
||||||
|
kCGDisplayBlendNormal,
|
||||||
|
kCGDisplayBlendSolidColor,
|
||||||
|
0.0, 0.0, 0.0,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ends reservation for display fading
|
||||||
|
//
|
||||||
|
static void endFadeReservation(CGDisplayFadeReservationToken token)
|
||||||
|
{
|
||||||
|
if (token != kCGDisplayFadeReservationInvalidToken)
|
||||||
|
{
|
||||||
|
CGDisplayFade(token, 0.5,
|
||||||
|
kCGDisplayBlendSolidColor,
|
||||||
|
kCGDisplayBlendNormal,
|
||||||
|
0.0, 0.0, 0.0,
|
||||||
|
FALSE);
|
||||||
|
CGReleaseDisplayFadeReservation(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the display refresh rate queried from the I/O registry
|
||||||
|
//
|
||||||
|
static double getFallbackRefreshRate(CGDirectDisplayID displayID)
|
||||||
|
{
|
||||||
|
double refreshRate = 60.0;
|
||||||
|
|
||||||
|
io_iterator_t it;
|
||||||
|
io_service_t service;
|
||||||
|
|
||||||
|
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
|
||||||
|
IOServiceMatching("IOFramebuffer"),
|
||||||
|
&it) != 0)
|
||||||
|
{
|
||||||
|
return refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
|
{
|
||||||
|
const CFNumberRef indexRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFramebufferOpenGLIndex"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
if (!indexRef)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t index = 0;
|
||||||
|
CFNumberGetValue(indexRef, kCFNumberIntType, &index);
|
||||||
|
CFRelease(indexRef);
|
||||||
|
|
||||||
|
if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CFNumberRef clockRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFBCurrentPixelClock"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
const CFNumberRef countRef =
|
||||||
|
IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR("IOFBCurrentPixelCount"),
|
||||||
|
kCFAllocatorDefault,
|
||||||
|
kNilOptions);
|
||||||
|
|
||||||
|
uint32_t clock = 0, count = 0;
|
||||||
|
|
||||||
|
if (clockRef)
|
||||||
|
{
|
||||||
|
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
|
||||||
|
CFRelease(clockRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countRef)
|
||||||
|
{
|
||||||
|
CFNumberGetValue(countRef, kCFNumberIntType, &count);
|
||||||
|
CFRelease(countRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock > 0 && count > 0)
|
||||||
|
refreshRate = clock / (double) count;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOObjectRelease(it);
|
||||||
|
return refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsNS(void)
|
||||||
|
{
|
||||||
|
uint32_t displayCount;
|
||||||
|
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||||
|
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||||
|
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
_glfw.monitors[i]->ns.screen = nil;
|
||||||
|
|
||||||
|
_GLFWmonitor** disconnected = NULL;
|
||||||
|
uint32_t disconnectedCount = _glfw.monitorCount;
|
||||||
|
if (disconnectedCount)
|
||||||
|
{
|
||||||
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
|
memcpy(disconnected,
|
||||||
|
_glfw.monitors,
|
||||||
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < displayCount; i++)
|
||||||
|
{
|
||||||
|
if (CGDisplayIsAsleep(displays[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||||
|
NSScreen* screen = nil;
|
||||||
|
|
||||||
|
for (screen in [NSScreen screens])
|
||||||
|
{
|
||||||
|
NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
|
||||||
|
|
||||||
|
// HACK: Compare unit numbers instead of display IDs to work around
|
||||||
|
// display replacement on machines with automatic graphics
|
||||||
|
// switching
|
||||||
|
if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: Compare unit numbers instead of display IDs to work around
|
||||||
|
// display replacement on machines with automatic graphics
|
||||||
|
// switching
|
||||||
|
uint32_t j;
|
||||||
|
for (j = 0; j < disconnectedCount; j++)
|
||||||
|
{
|
||||||
|
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
||||||
|
{
|
||||||
|
disconnected[j]->ns.screen = screen;
|
||||||
|
disconnected[j] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < disconnectedCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||||
|
char* name = getMonitorName(displays[i], screen);
|
||||||
|
if (!name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||||
|
monitor->ns.displayID = displays[i];
|
||||||
|
monitor->ns.unitNumber = unitNumber;
|
||||||
|
monitor->ns.screen = screen;
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
|
||||||
|
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
|
||||||
|
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
|
||||||
|
CGDisplayModeRelease(mode);
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i])
|
||||||
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(disconnected);
|
||||||
|
free(displays);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the current video mode
|
||||||
|
//
|
||||||
|
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
|
{
|
||||||
|
GLFWvidmode current;
|
||||||
|
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||||
|
|
||||||
|
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||||
|
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||||
|
const CFIndex count = CFArrayGetCount(modes);
|
||||||
|
CGDisplayModeRef native = NULL;
|
||||||
|
|
||||||
|
for (CFIndex i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||||
|
if (!modeIsGood(dm))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const GLFWvidmode mode =
|
||||||
|
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the previously saved (original) video mode
|
||||||
|
//
|
||||||
|
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
if (monitor->ns.previousMode)
|
||||||
|
{
|
||||||
|
CGDisplayFadeReservationToken token = beginFadeReservation();
|
||||||
|
CGDisplaySetDisplayMode(monitor->ns.displayID,
|
||||||
|
monitor->ns.previousMode, NULL);
|
||||||
|
endFadeReservation(token);
|
||||||
|
|
||||||
|
CGDisplayModeRelease(monitor->ns.previousMode);
|
||||||
|
monitor->ns.previousMode = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = (int) bounds.origin.x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = (int) bounds.origin.y;
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
if (!monitor->ns.screen)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Cannot query content scale without screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
const NSRect points = [monitor->ns.screen frame];
|
||||||
|
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
|
||||||
|
|
||||||
|
if (xscale)
|
||||||
|
*xscale = (float) (pixels.size.width / points.size.width);
|
||||||
|
if (yscale)
|
||||||
|
*yscale = (float) (pixels.size.height / points.size.height);
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||||
|
int* xpos, int* ypos,
|
||||||
|
int* width, int* height)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
if (!monitor->ns.screen)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Cannot query workarea without screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
const NSRect frameRect = [monitor->ns.screen visibleFrame];
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = frameRect.origin.x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1);
|
||||||
|
if (width)
|
||||||
|
*width = frameRect.size.width;
|
||||||
|
if (height)
|
||||||
|
*height = frameRect.size.height;
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||||
|
const CFIndex found = CFArrayGetCount(modes);
|
||||||
|
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
|
||||||
|
|
||||||
|
for (CFIndex i = 0; i < found; i++)
|
||||||
|
{
|
||||||
|
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||||
|
if (!modeIsGood(dm))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const GLFWvidmode mode =
|
||||||
|
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
|
||||||
|
CFIndex j;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(modes);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||||
|
*mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
|
||||||
|
CGDisplayModeRelease(native);
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
uint32_t 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 (uint32_t 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);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
|
||||||
|
|
||||||
|
for (unsigned int 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);
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW native API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
|
||||||
|
return monitor->ns.displayID;
|
||||||
|
}
|
||||||
|
|
220
external/glfw-3.3.8/src/cocoa_platform.h
vendored
Normal file
220
external/glfw-3.3.8/src/cocoa_platform.h
vendored
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 macOS - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
// NOTE: All of NSGL was deprecated in the 10.14 SDK
|
||||||
|
// This disables the pointless warnings for every symbol we use
|
||||||
|
#ifndef GL_SILENCE_DEPRECATION
|
||||||
|
#define GL_SILENCE_DEPRECATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OBJC__)
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#else
|
||||||
|
typedef void* id;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||||
|
// SDK versions where one is unavailable or deprecated.
|
||||||
|
// We use the newer names in code and replace them with the older names if
|
||||||
|
// the base SDK does not provide the newer names.
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||||
|
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||||
|
#define NSEventMaskAny NSAnyEventMask
|
||||||
|
#define NSEventMaskKeyUp NSKeyUpMask
|
||||||
|
#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
|
||||||
|
#define NSEventModifierFlagCommand NSCommandKeyMask
|
||||||
|
#define NSEventModifierFlagControl NSControlKeyMask
|
||||||
|
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
|
||||||
|
#define NSEventModifierFlagOption NSAlternateKeyMask
|
||||||
|
#define NSEventModifierFlagShift NSShiftKeyMask
|
||||||
|
#define NSEventTypeApplicationDefined NSApplicationDefined
|
||||||
|
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
|
||||||
|
#define NSWindowStyleMaskClosable NSClosableWindowMask
|
||||||
|
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
|
||||||
|
#define NSWindowStyleMaskResizable NSResizableWindowMask
|
||||||
|
#define NSWindowStyleMaskTitled NSTitledWindowMask
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Many Cocoa dynamically linked constants have been renamed and we need
|
||||||
|
// to build across SDK versions where one is unavailable or deprecated.
|
||||||
|
// We use the newer names in code and replace them with the older names if
|
||||||
|
// the deployment target is older than the newer names.
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
|
||||||
|
#define NSPasteboardTypeURL NSURLPboardType
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||||
|
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
|
||||||
|
|
||||||
|
typedef struct VkMacOSSurfaceCreateInfoMVK
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkMacOSSurfaceCreateFlagsMVK flags;
|
||||||
|
const void* pView;
|
||||||
|
} VkMacOSSurfaceCreateInfoMVK;
|
||||||
|
|
||||||
|
typedef struct VkMetalSurfaceCreateInfoEXT
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkMetalSurfaceCreateFlagsEXT flags;
|
||||||
|
const void* pLayer;
|
||||||
|
} VkMetalSurfaceCreateInfoEXT;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
|
||||||
|
#include "posix_thread.h"
|
||||||
|
#include "cocoa_joystick.h"
|
||||||
|
#include "nsgl_context.h"
|
||||||
|
#include "egl_context.h"
|
||||||
|
#include "osmesa_context.h"
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
|
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.layer)
|
||||||
|
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
|
||||||
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
|
||||||
|
|
||||||
|
// HIToolbox.framework pointer typedefs
|
||||||
|
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
|
||||||
|
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
|
||||||
|
#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource
|
||||||
|
typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef);
|
||||||
|
#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty
|
||||||
|
typedef UInt8 (*PFN_LMGetKbdType)(void);
|
||||||
|
#define LMGetKbdType _glfw.ns.tis.GetKbdType
|
||||||
|
|
||||||
|
|
||||||
|
// Cocoa-specific per-window data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWwindowNS
|
||||||
|
{
|
||||||
|
id object;
|
||||||
|
id delegate;
|
||||||
|
id view;
|
||||||
|
id layer;
|
||||||
|
|
||||||
|
GLFWbool maximized;
|
||||||
|
GLFWbool occluded;
|
||||||
|
GLFWbool retina;
|
||||||
|
|
||||||
|
// Cached window properties to filter out duplicate events
|
||||||
|
int width, height;
|
||||||
|
int fbWidth, fbHeight;
|
||||||
|
float xscale, yscale;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
GLFWbool finishedLaunching;
|
||||||
|
GLFWbool cursorHidden;
|
||||||
|
TISInputSourceRef inputSource;
|
||||||
|
IOHIDManagerRef hidManager;
|
||||||
|
id unicodeData;
|
||||||
|
id helper;
|
||||||
|
id keyUpMonitor;
|
||||||
|
id nibObjects;
|
||||||
|
|
||||||
|
char keynames[GLFW_KEY_LAST + 1][17];
|
||||||
|
short int keycodes[256];
|
||||||
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
char* clipboardString;
|
||||||
|
CGPoint cascadePoint;
|
||||||
|
// Where to place the cursor when re-enabled
|
||||||
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
|
// The window whose disabled cursor mode is active
|
||||||
|
_GLFWwindow* disabledCursorWindow;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
CFBundleRef bundle;
|
||||||
|
PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
|
||||||
|
PFN_TISGetInputSourceProperty GetInputSourceProperty;
|
||||||
|
PFN_LMGetKbdType GetKbdType;
|
||||||
|
CFStringRef kPropertyUnicodeKeyLayoutData;
|
||||||
|
} tis;
|
||||||
|
} _GLFWlibraryNS;
|
||||||
|
|
||||||
|
// Cocoa-specific per-monitor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmonitorNS
|
||||||
|
{
|
||||||
|
CGDirectDisplayID displayID;
|
||||||
|
CGDisplayModeRef previousMode;
|
||||||
|
uint32_t unitNumber;
|
||||||
|
id screen;
|
||||||
|
double fallbackRefreshRate;
|
||||||
|
} _GLFWmonitorNS;
|
||||||
|
|
||||||
|
// Cocoa-specific per-cursor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcursorNS
|
||||||
|
{
|
||||||
|
id object;
|
||||||
|
} _GLFWcursorNS;
|
||||||
|
|
||||||
|
// Cocoa-specific global timer data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWtimerNS
|
||||||
|
{
|
||||||
|
uint64_t frequency;
|
||||||
|
} _GLFWtimerNS;
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwInitTimerNS(void);
|
||||||
|
|
||||||
|
void _glfwPollMonitorsNS(void);
|
||||||
|
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
|
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
float _glfwTransformYNS(float y);
|
||||||
|
|
||||||
|
void* _glfwLoadLocalVulkanLoaderNS(void);
|
||||||
|
|
62
external/glfw-3.3.8/src/cocoa_time.c
vendored
Normal file
62
external/glfw-3.3.8/src/cocoa_time.c
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 macOS - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialise timer
|
||||||
|
//
|
||||||
|
void _glfwInitTimerNS(void)
|
||||||
|
{
|
||||||
|
mach_timebase_info_data_t info;
|
||||||
|
mach_timebase_info(&info);
|
||||||
|
|
||||||
|
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerValue(void)
|
||||||
|
{
|
||||||
|
return mach_absolute_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||||
|
{
|
||||||
|
return _glfw.timer.ns.frequency;
|
||||||
|
}
|
||||||
|
|
1934
external/glfw-3.3.8/src/cocoa_window.m
vendored
Normal file
1934
external/glfw-3.3.8/src/cocoa_window.m
vendored
Normal file
File diff suppressed because it is too large
Load Diff
758
external/glfw-3.3.8/src/context.c
vendored
Normal file
758
external/glfw-3.3.8/src/context.c
vendored
Normal file
@ -0,0 +1,758 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Checks whether the desired context attributes are valid
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
if (ctxconfig->share)
|
||||||
|
{
|
||||||
|
if (ctxconfig->client == GLFW_NO_API ||
|
||||||
|
ctxconfig->share->context.client == GLFW_NO_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
|
||||||
|
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
|
||||||
|
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
"Invalid context creation API 0x%08X",
|
||||||
|
ctxconfig->source);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->client != GLFW_NO_API &&
|
||||||
|
ctxconfig->client != GLFW_OPENGL_API &&
|
||||||
|
ctxconfig->client != GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
"Invalid client API 0x%08X",
|
||||||
|
ctxconfig->client);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
|
||||||
|
(ctxconfig->major == 1 && ctxconfig->minor > 5) ||
|
||||||
|
(ctxconfig->major == 2 && ctxconfig->minor > 1) ||
|
||||||
|
(ctxconfig->major == 3 && ctxconfig->minor > 3))
|
||||||
|
{
|
||||||
|
// OpenGL 1.0 is the smallest valid version
|
||||||
|
// OpenGL 1.x series ended with version 1.5
|
||||||
|
// OpenGL 2.x series ended with version 2.1
|
||||||
|
// OpenGL 3.x series ended with version 3.3
|
||||||
|
// For now, let everything else through
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Invalid OpenGL version %i.%i",
|
||||||
|
ctxconfig->major, ctxconfig->minor);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->profile)
|
||||||
|
{
|
||||||
|
if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE &&
|
||||||
|
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
"Invalid OpenGL profile 0x%08X",
|
||||||
|
ctxconfig->profile);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->major <= 2 ||
|
||||||
|
(ctxconfig->major == 3 && ctxconfig->minor < 2))
|
||||||
|
{
|
||||||
|
// Desktop OpenGL context profiles are only defined for version 3.2
|
||||||
|
// and above
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Context profiles are only defined for OpenGL version 3.2 and above");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->forward && ctxconfig->major <= 2)
|
||||||
|
{
|
||||||
|
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Forward-compatibility is only defined for OpenGL version 3.0 and above");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
|
||||||
|
(ctxconfig->major == 1 && ctxconfig->minor > 1) ||
|
||||||
|
(ctxconfig->major == 2 && ctxconfig->minor > 0))
|
||||||
|
{
|
||||||
|
// OpenGL ES 1.0 is the smallest valid version
|
||||||
|
// OpenGL ES 1.x series ended with version 1.1
|
||||||
|
// OpenGL ES 2.x series ended with version 2.0
|
||||||
|
// For now, let everything else through
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Invalid OpenGL ES version %i.%i",
|
||||||
|
ctxconfig->major, ctxconfig->minor);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->robustness)
|
||||||
|
{
|
||||||
|
if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
|
||||||
|
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
"Invalid context robustness mode 0x%08X",
|
||||||
|
ctxconfig->robustness);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->release)
|
||||||
|
{
|
||||||
|
if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
|
||||||
|
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
"Invalid context release behavior 0x%08X",
|
||||||
|
ctxconfig->release);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chooses the framebuffer config that best matches the desired one
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count number of missing buffers
|
||||||
|
{
|
||||||
|
missing = 0;
|
||||||
|
|
||||||
|
if (desired->alphaBits > 0 && current->alphaBits == 0)
|
||||||
|
missing++;
|
||||||
|
|
||||||
|
if (desired->depthBits > 0 && current->depthBits == 0)
|
||||||
|
missing++;
|
||||||
|
|
||||||
|
if (desired->stencilBits > 0 && current->stencilBits == 0)
|
||||||
|
missing++;
|
||||||
|
|
||||||
|
if (desired->auxBuffers > 0 &&
|
||||||
|
current->auxBuffers < desired->auxBuffers)
|
||||||
|
{
|
||||||
|
missing += desired->auxBuffers - current->auxBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->samples > 0 && current->samples == 0)
|
||||||
|
{
|
||||||
|
// Technically, several multisampling buffers could be
|
||||||
|
// involved, but that's a lower level implementation detail and
|
||||||
|
// not important to us here, so we count them as one
|
||||||
|
missing++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->transparent != current->transparent)
|
||||||
|
missing++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These polynomials make many small channel size differences matter
|
||||||
|
// less than one large channel size difference
|
||||||
|
|
||||||
|
// Calculate color channel size difference value
|
||||||
|
{
|
||||||
|
colorDiff = 0;
|
||||||
|
|
||||||
|
if (desired->redBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
colorDiff += (desired->redBits - current->redBits) *
|
||||||
|
(desired->redBits - current->redBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->greenBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
colorDiff += (desired->greenBits - current->greenBits) *
|
||||||
|
(desired->greenBits - current->greenBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->blueBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
colorDiff += (desired->blueBits - current->blueBits) *
|
||||||
|
(desired->blueBits - current->blueBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate non-color channel size difference value
|
||||||
|
{
|
||||||
|
extraDiff = 0;
|
||||||
|
|
||||||
|
if (desired->alphaBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->alphaBits - current->alphaBits) *
|
||||||
|
(desired->alphaBits - current->alphaBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->depthBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->depthBits - current->depthBits) *
|
||||||
|
(desired->depthBits - current->depthBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->stencilBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->stencilBits - current->stencilBits) *
|
||||||
|
(desired->stencilBits - current->stencilBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->accumRedBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->accumRedBits - current->accumRedBits) *
|
||||||
|
(desired->accumRedBits - current->accumRedBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->accumGreenBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
|
||||||
|
(desired->accumGreenBits - current->accumGreenBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->accumBlueBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
|
||||||
|
(desired->accumBlueBits - current->accumBlueBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->accumAlphaBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
|
||||||
|
(desired->accumAlphaBits - current->accumAlphaBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->samples != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
extraDiff += (desired->samples - current->samples) *
|
||||||
|
(desired->samples - current->samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired->sRGB && !current->sRGB)
|
||||||
|
extraDiff++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out if the current one is better than the best one found so far
|
||||||
|
// Least number of missing buffers is the most important heuristic,
|
||||||
|
// then color buffer size match and lastly size match for other buffers
|
||||||
|
|
||||||
|
if (missing < leastMissing)
|
||||||
|
closest = current;
|
||||||
|
else if (missing == leastMissing)
|
||||||
|
{
|
||||||
|
if ((colorDiff < leastColorDiff) ||
|
||||||
|
(colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
|
||||||
|
{
|
||||||
|
closest = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current == closest)
|
||||||
|
{
|
||||||
|
leastMissing = missing;
|
||||||
|
leastColorDiff = colorDiff;
|
||||||
|
leastExtraDiff = extraDiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the attributes of the current context
|
||||||
|
//
|
||||||
|
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
_GLFWwindow* previous;
|
||||||
|
const char* version;
|
||||||
|
const char* prefixes[] =
|
||||||
|
{
|
||||||
|
"OpenGL ES-CM ",
|
||||||
|
"OpenGL ES-CL ",
|
||||||
|
"OpenGL ES ",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
window->context.source = ctxconfig->source;
|
||||||
|
window->context.client = GLFW_OPENGL_API;
|
||||||
|
|
||||||
|
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) window);
|
||||||
|
|
||||||
|
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");
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
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");
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (window->doublebuffer)
|
||||||
|
window->context.swapBuffers(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches an extension string for the specified extension
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
|
||||||
|
if (window && window->context.client == GLFW_NO_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
|
||||||
|
"Cannot make current with a window that has no OpenGL or OpenGL ES context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previous)
|
||||||
|
{
|
||||||
|
if (!window || window->context.source != previous->context.source)
|
||||||
|
previous->context.makeCurrent(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
window->context.makeCurrent(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
if (window->context.client == GLFW_NO_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
|
||||||
|
"Cannot swap buffers of a window that has no OpenGL or OpenGL ES context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.swapBuffers(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSwapInterval(int interval)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
|
||||||
|
"Cannot set swap interval without a current OpenGL or OpenGL ES context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.swapInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window;
|
||||||
|
assert(extension != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
|
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
|
||||||
|
"Cannot query extension without a current OpenGL or OpenGL ES context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*extension == '\0')
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.major >= 3)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
GLint count;
|
||||||
|
|
||||||
|
// Check if extension is in the modern OpenGL extensions string list
|
||||||
|
|
||||||
|
window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
const char* en = (const char*)
|
||||||
|
window->context.GetStringi(GL_EXTENSIONS, i);
|
||||||
|
if (!en)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Extension string retrieval is broken");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(en, extension) == 0)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check if extension is in the old style OpenGL extensions string
|
||||||
|
|
||||||
|
const char* extensions = (const char*)
|
||||||
|
window->context.GetString(GL_EXTENSIONS);
|
||||||
|
if (!extensions)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Extension string retrieval is broken");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfwStringInExtensionString(extension, extensions))
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if extension is in the platform-specific string
|
||||||
|
return window->context.extensionSupported(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window;
|
||||||
|
assert(procname != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
|
||||||
|
"Cannot query entry point without a current OpenGL or OpenGL ES context");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window->context.getProcAddress(procname);
|
||||||
|
}
|
||||||
|
|
809
external/glfw-3.3.8/src/egl_context.c
vendored
Normal file
809
external/glfw-3.3.8/src/egl_context.c
vendored
Normal file
@ -0,0 +1,809 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 EGL - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Return a description of the specified EGL error
|
||||||
|
//
|
||||||
|
static const char* getEGLErrorString(EGLint error)
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case EGL_SUCCESS:
|
||||||
|
return "Success";
|
||||||
|
case EGL_NOT_INITIALIZED:
|
||||||
|
return "EGL is not or could not be initialized";
|
||||||
|
case EGL_BAD_ACCESS:
|
||||||
|
return "EGL cannot access a requested resource";
|
||||||
|
case EGL_BAD_ALLOC:
|
||||||
|
return "EGL failed to allocate resources for the requested operation";
|
||||||
|
case EGL_BAD_ATTRIBUTE:
|
||||||
|
return "An unrecognized attribute or attribute value was passed in the attribute list";
|
||||||
|
case EGL_BAD_CONTEXT:
|
||||||
|
return "An EGLContext argument does not name a valid EGL rendering context";
|
||||||
|
case EGL_BAD_CONFIG:
|
||||||
|
return "An EGLConfig argument does not name a valid EGL frame buffer configuration";
|
||||||
|
case EGL_BAD_CURRENT_SURFACE:
|
||||||
|
return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";
|
||||||
|
case EGL_BAD_DISPLAY:
|
||||||
|
return "An EGLDisplay argument does not name a valid EGL display connection";
|
||||||
|
case EGL_BAD_SURFACE:
|
||||||
|
return "An EGLSurface argument does not name a valid surface configured for GL rendering";
|
||||||
|
case EGL_BAD_MATCH:
|
||||||
|
return "Arguments are inconsistent";
|
||||||
|
case EGL_BAD_PARAMETER:
|
||||||
|
return "One or more argument values are invalid";
|
||||||
|
case EGL_BAD_NATIVE_PIXMAP:
|
||||||
|
return "A NativePixmapType argument does not refer to a valid native pixmap";
|
||||||
|
case EGL_BAD_NATIVE_WINDOW:
|
||||||
|
return "A NativeWindowType argument does not refer to a valid native window";
|
||||||
|
case EGL_CONTEXT_LOST:
|
||||||
|
return "The application must destroy all contexts and reinitialise";
|
||||||
|
default:
|
||||||
|
return "ERROR: UNKNOWN EGL ERROR";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the specified attribute of the specified EGLConfig
|
||||||
|
//
|
||||||
|
static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the EGLConfig most closely matching the specified hints
|
||||||
|
//
|
||||||
|
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* desired,
|
||||||
|
EGLConfig* result)
|
||||||
|
{
|
||||||
|
EGLConfig* nativeConfigs;
|
||||||
|
_GLFWfbconfig* usableConfigs;
|
||||||
|
const _GLFWfbconfig* closest;
|
||||||
|
int i, nativeCount, usableCount;
|
||||||
|
|
||||||
|
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
|
||||||
|
if (!nativeCount)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
|
||||||
|
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
|
||||||
|
|
||||||
|
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||||
|
usableCount = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nativeCount; i++)
|
||||||
|
{
|
||||||
|
const EGLConfig n = nativeConfigs[i];
|
||||||
|
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||||
|
|
||||||
|
// Only consider RGB(A) EGLConfigs
|
||||||
|
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Only consider window EGLConfigs
|
||||||
|
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#if defined(_GLFW_X11)
|
||||||
|
{
|
||||||
|
XVisualInfo vi = {0};
|
||||||
|
|
||||||
|
// Only consider EGLConfigs with associated Visuals
|
||||||
|
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
|
||||||
|
if (!vi.visualid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (desired->transparent)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
XVisualInfo* vis =
|
||||||
|
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
|
||||||
|
if (vis)
|
||||||
|
{
|
||||||
|
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
|
||||||
|
XFree(vis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->major == 1)
|
||||||
|
{
|
||||||
|
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
|
||||||
|
u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
|
||||||
|
u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
|
||||||
|
|
||||||
|
u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
|
||||||
|
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
|
||||||
|
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
|
||||||
|
|
||||||
|
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
|
||||||
|
u->doublebuffer = desired->doublebuffer;
|
||||||
|
|
||||||
|
u->handle = (uintptr_t) n;
|
||||||
|
usableCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||||
|
if (closest)
|
||||||
|
*result = (EGLConfig) closest->handle;
|
||||||
|
|
||||||
|
free(nativeConfigs);
|
||||||
|
free(usableConfigs);
|
||||||
|
|
||||||
|
return closest != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeContextCurrentEGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
if (!eglMakeCurrent(_glfw.egl.display,
|
||||||
|
window->context.egl.surface,
|
||||||
|
window->context.egl.surface,
|
||||||
|
window->context.egl.handle))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"EGL: Failed to make context current: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!eglMakeCurrent(_glfw.egl.display,
|
||||||
|
EGL_NO_SURFACE,
|
||||||
|
EGL_NO_SURFACE,
|
||||||
|
EGL_NO_CONTEXT))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"EGL: Failed to clear current context: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapBuffersEGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"EGL: The context must be current on the calling thread when swapping buffers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_GLFW_WAYLAND)
|
||||||
|
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
|
||||||
|
if (!window->wl.visible)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapIntervalEGL(int interval)
|
||||||
|
{
|
||||||
|
eglSwapInterval(_glfw.egl.display, interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int extensionSupportedEGL(const char* extension)
|
||||||
|
{
|
||||||
|
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
|
||||||
|
if (extensions)
|
||||||
|
{
|
||||||
|
if (_glfwStringInExtensionString(extension, extensions))
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWglproc getProcAddressEGL(const char* procname)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
|
||||||
|
if (window->context.egl.client)
|
||||||
|
{
|
||||||
|
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
|
||||||
|
procname);
|
||||||
|
if (proc)
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eglGetProcAddress(procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyContextEGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_X11)
|
||||||
|
// NOTE: Do not unload libGL.so.1 while the X11 display is still open,
|
||||||
|
// as it will make XCloseDisplay segfault
|
||||||
|
if (window->context.client != GLFW_OPENGL_API)
|
||||||
|
#endif // _GLFW_X11
|
||||||
|
{
|
||||||
|
if (window->context.egl.client)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(window->context.egl.client);
|
||||||
|
window->context.egl.client = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.egl.surface)
|
||||||
|
{
|
||||||
|
eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
|
||||||
|
window->context.egl.surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.egl.handle)
|
||||||
|
{
|
||||||
|
eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
|
||||||
|
window->context.egl.handle = EGL_NO_CONTEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize EGL
|
||||||
|
//
|
||||||
|
GLFWbool _glfwInitEGL(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char* sonames[] =
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_EGL_LIBRARY)
|
||||||
|
_GLFW_EGL_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
|
"libEGL.dll",
|
||||||
|
"EGL.dll",
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
"libEGL.dylib",
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
"libEGL-1.so",
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
"libEGL.so",
|
||||||
|
#else
|
||||||
|
"libEGL.so.1",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_glfw.egl.handle)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
for (i = 0; sonames[i]; i++)
|
||||||
|
{
|
||||||
|
_glfw.egl.handle = _glfw_dlopen(sonames[i]);
|
||||||
|
if (_glfw.egl.handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.egl.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
|
||||||
|
|
||||||
|
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||||
|
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
|
||||||
|
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
|
||||||
|
_glfw.egl.GetError = (PFN_eglGetError)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglGetError");
|
||||||
|
_glfw.egl.Initialize = (PFN_eglInitialize)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglInitialize");
|
||||||
|
_glfw.egl.Terminate = (PFN_eglTerminate)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglTerminate");
|
||||||
|
_glfw.egl.BindAPI = (PFN_eglBindAPI)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
|
||||||
|
_glfw.egl.CreateContext = (PFN_eglCreateContext)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
|
||||||
|
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
|
||||||
|
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
|
||||||
|
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
|
||||||
|
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
|
||||||
|
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
|
||||||
|
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
|
||||||
|
_glfw.egl.QueryString = (PFN_eglQueryString)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglQueryString");
|
||||||
|
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
|
||||||
|
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
|
||||||
|
|
||||||
|
if (!_glfw.egl.GetConfigAttrib ||
|
||||||
|
!_glfw.egl.GetConfigs ||
|
||||||
|
!_glfw.egl.GetDisplay ||
|
||||||
|
!_glfw.egl.GetError ||
|
||||||
|
!_glfw.egl.Initialize ||
|
||||||
|
!_glfw.egl.Terminate ||
|
||||||
|
!_glfw.egl.BindAPI ||
|
||||||
|
!_glfw.egl.CreateContext ||
|
||||||
|
!_glfw.egl.DestroySurface ||
|
||||||
|
!_glfw.egl.DestroyContext ||
|
||||||
|
!_glfw.egl.CreateWindowSurface ||
|
||||||
|
!_glfw.egl.MakeCurrent ||
|
||||||
|
!_glfw.egl.SwapBuffers ||
|
||||||
|
!_glfw.egl.SwapInterval ||
|
||||||
|
!_glfw.egl.QueryString ||
|
||||||
|
!_glfw.egl.GetProcAddress)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"EGL: Failed to load required entry points");
|
||||||
|
|
||||||
|
_glfwTerminateEGL();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
|
||||||
|
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"EGL: Failed to get EGL display: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
|
||||||
|
_glfwTerminateEGL();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"EGL: Failed to initialize EGL: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
|
||||||
|
_glfwTerminateEGL();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.egl.KHR_create_context =
|
||||||
|
extensionSupportedEGL("EGL_KHR_create_context");
|
||||||
|
_glfw.egl.KHR_create_context_no_error =
|
||||||
|
extensionSupportedEGL("EGL_KHR_create_context_no_error");
|
||||||
|
_glfw.egl.KHR_gl_colorspace =
|
||||||
|
extensionSupportedEGL("EGL_KHR_gl_colorspace");
|
||||||
|
_glfw.egl.KHR_get_all_proc_addresses =
|
||||||
|
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
|
||||||
|
_glfw.egl.KHR_context_flush_control =
|
||||||
|
extensionSupportedEGL("EGL_KHR_context_flush_control");
|
||||||
|
_glfw.egl.EXT_present_opaque =
|
||||||
|
extensionSupportedEGL("EGL_EXT_present_opaque");
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate EGL
|
||||||
|
//
|
||||||
|
void _glfwTerminateEGL(void)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.display)
|
||||||
|
{
|
||||||
|
eglTerminate(_glfw.egl.display);
|
||||||
|
_glfw.egl.display = EGL_NO_DISPLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.egl.handle);
|
||||||
|
_glfw.egl.handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define setAttrib(a, v) \
|
||||||
|
{ \
|
||||||
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
|
attribs[index++] = a; \
|
||||||
|
attribs[index++] = v; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the OpenGL or OpenGL ES context
|
||||||
|
//
|
||||||
|
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
EGLint attribs[40];
|
||||||
|
EGLConfig config;
|
||||||
|
EGLContext share = NULL;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
if (!_glfw.egl.display)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->share)
|
||||||
|
share = ctxconfig->share->context.egl.handle;
|
||||||
|
|
||||||
|
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"EGL: Failed to find a suitable EGLConfig");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
if (!eglBindAPI(EGL_OPENGL_ES_API))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"EGL: Failed to bind OpenGL ES: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!eglBindAPI(EGL_OPENGL_API))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"EGL: Failed to bind OpenGL: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.KHR_create_context)
|
||||||
|
{
|
||||||
|
int mask = 0, flags = 0;
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||||
|
|
||||||
|
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
||||||
|
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
|
mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->debug)
|
||||||
|
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||||
|
|
||||||
|
if (ctxconfig->robustness)
|
||||||
|
{
|
||||||
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
|
{
|
||||||
|
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||||
|
EGL_NO_RESET_NOTIFICATION_KHR);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
|
{
|
||||||
|
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||||
|
EGL_LOSE_CONTEXT_ON_RESET_KHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->noerror)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.KHR_create_context_no_error)
|
||||||
|
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
|
{
|
||||||
|
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
||||||
|
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.KHR_context_flush_control)
|
||||||
|
{
|
||||||
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
|
{
|
||||||
|
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
||||||
|
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
|
{
|
||||||
|
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
||||||
|
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setAttrib(EGL_NONE, EGL_NONE);
|
||||||
|
|
||||||
|
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
|
||||||
|
config, share, attribs);
|
||||||
|
|
||||||
|
if (window->context.egl.handle == EGL_NO_CONTEXT)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"EGL: Failed to create context: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up attributes for surface creation
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
if (fbconfig->sRGB)
|
||||||
|
{
|
||||||
|
if (_glfw.egl.KHR_gl_colorspace)
|
||||||
|
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fbconfig->doublebuffer)
|
||||||
|
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
||||||
|
|
||||||
|
if (_glfw.egl.EXT_present_opaque)
|
||||||
|
setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
||||||
|
|
||||||
|
setAttrib(EGL_NONE, EGL_NONE);
|
||||||
|
|
||||||
|
window->context.egl.surface =
|
||||||
|
eglCreateWindowSurface(_glfw.egl.display,
|
||||||
|
config,
|
||||||
|
_GLFW_EGL_NATIVE_WINDOW,
|
||||||
|
attribs);
|
||||||
|
if (window->context.egl.surface == EGL_NO_SURFACE)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"EGL: Failed to create window surface: %s",
|
||||||
|
getEGLErrorString(eglGetError()));
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.egl.config = config;
|
||||||
|
|
||||||
|
// Load the appropriate client library
|
||||||
|
if (!_glfw.egl.KHR_get_all_proc_addresses)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char** sonames;
|
||||||
|
const char* es1sonames[] =
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_GLESV1_LIBRARY)
|
||||||
|
_GLFW_GLESV1_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
|
"GLESv1_CM.dll",
|
||||||
|
"libGLES_CM.dll",
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
"libGLESv1_CM.dylib",
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
"libGLESv1_CM.so",
|
||||||
|
#else
|
||||||
|
"libGLESv1_CM.so.1",
|
||||||
|
"libGLES_CM.so.1",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const char* es2sonames[] =
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_GLESV2_LIBRARY)
|
||||||
|
_GLFW_GLESV2_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
|
"GLESv2.dll",
|
||||||
|
"libGLESv2.dll",
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
"libGLESv2.dylib",
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
"libGLESv2-2.so",
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
"libGLESv2.so",
|
||||||
|
#else
|
||||||
|
"libGLESv2.so.2",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const char* glsonames[] =
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_OPENGL_LIBRARY)
|
||||||
|
_GLFW_OPENGL_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
"libGL.so",
|
||||||
|
#else
|
||||||
|
"libGL.so.1",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->major == 1)
|
||||||
|
sonames = es1sonames;
|
||||||
|
else
|
||||||
|
sonames = es2sonames;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sonames = glsonames;
|
||||||
|
|
||||||
|
for (i = 0; sonames[i]; i++)
|
||||||
|
{
|
||||||
|
// HACK: Match presence of lib prefix to increase chance of finding
|
||||||
|
// a matching pair in the jungle that is Win32 EGL/GLES
|
||||||
|
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
window->context.egl.client = _glfw_dlopen(sonames[i]);
|
||||||
|
if (window->context.egl.client)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window->context.egl.client)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"EGL: Failed to load client library");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.makeCurrent = makeContextCurrentEGL;
|
||||||
|
window->context.swapBuffers = swapBuffersEGL;
|
||||||
|
window->context.swapInterval = swapIntervalEGL;
|
||||||
|
window->context.extensionSupported = extensionSupportedEGL;
|
||||||
|
window->context.getProcAddress = getProcAddressEGL;
|
||||||
|
window->context.destroy = destroyContextEGL;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef setAttrib
|
||||||
|
|
||||||
|
// Returns the Visual and depth of the chosen EGLConfig
|
||||||
|
//
|
||||||
|
#if defined(_GLFW_X11)
|
||||||
|
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig,
|
||||||
|
Visual** visual, int* depth)
|
||||||
|
{
|
||||||
|
XVisualInfo* result;
|
||||||
|
XVisualInfo desired;
|
||||||
|
EGLConfig native;
|
||||||
|
EGLint visualID = 0, count = 0;
|
||||||
|
const long vimask = VisualScreenMask | VisualIDMask;
|
||||||
|
|
||||||
|
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"EGL: Failed to find a suitable EGLConfig");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
eglGetConfigAttrib(_glfw.egl.display, native,
|
||||||
|
EGL_NATIVE_VISUAL_ID, &visualID);
|
||||||
|
|
||||||
|
desired.screen = _glfw.x11.screen;
|
||||||
|
desired.visualid = visualID;
|
||||||
|
|
||||||
|
result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"EGL: Failed to retrieve Visual for EGLConfig");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*visual = result->visual;
|
||||||
|
*depth = result->depth;
|
||||||
|
|
||||||
|
XFree(result);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW native API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY);
|
||||||
|
return _glfw.egl.display;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
|
||||||
|
|
||||||
|
if (window->context.source != GLFW_EGL_CONTEXT_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.source != GLFW_EGL_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window->context.egl.surface;
|
||||||
|
}
|
||||||
|
|
217
external/glfw-3.3.8/src/egl_context.h
vendored
Normal file
217
external/glfw-3.3.8/src/egl_context.h
vendored
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 EGL - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#if defined(_GLFW_USE_EGLPLATFORM_H)
|
||||||
|
#include <EGL/eglplatform.h>
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
|
#define EGLAPIENTRY __stdcall
|
||||||
|
typedef HDC EGLNativeDisplayType;
|
||||||
|
typedef HWND EGLNativeWindowType;
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
#define EGLAPIENTRY
|
||||||
|
typedef void* EGLNativeDisplayType;
|
||||||
|
typedef id EGLNativeWindowType;
|
||||||
|
#elif defined(_GLFW_X11)
|
||||||
|
#define EGLAPIENTRY
|
||||||
|
typedef Display* EGLNativeDisplayType;
|
||||||
|
typedef Window EGLNativeWindowType;
|
||||||
|
#elif defined(_GLFW_WAYLAND)
|
||||||
|
#define EGLAPIENTRY
|
||||||
|
typedef struct wl_display* EGLNativeDisplayType;
|
||||||
|
typedef struct wl_egl_window* EGLNativeWindowType;
|
||||||
|
#else
|
||||||
|
#error "No supported EGL platform selected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EGL_SUCCESS 0x3000
|
||||||
|
#define EGL_NOT_INITIALIZED 0x3001
|
||||||
|
#define EGL_BAD_ACCESS 0x3002
|
||||||
|
#define EGL_BAD_ALLOC 0x3003
|
||||||
|
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||||
|
#define EGL_BAD_CONFIG 0x3005
|
||||||
|
#define EGL_BAD_CONTEXT 0x3006
|
||||||
|
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||||
|
#define EGL_BAD_DISPLAY 0x3008
|
||||||
|
#define EGL_BAD_MATCH 0x3009
|
||||||
|
#define EGL_BAD_NATIVE_PIXMAP 0x300a
|
||||||
|
#define EGL_BAD_NATIVE_WINDOW 0x300b
|
||||||
|
#define EGL_BAD_PARAMETER 0x300c
|
||||||
|
#define EGL_BAD_SURFACE 0x300d
|
||||||
|
#define EGL_CONTEXT_LOST 0x300e
|
||||||
|
#define EGL_COLOR_BUFFER_TYPE 0x303f
|
||||||
|
#define EGL_RGB_BUFFER 0x308e
|
||||||
|
#define EGL_SURFACE_TYPE 0x3033
|
||||||
|
#define EGL_WINDOW_BIT 0x0004
|
||||||
|
#define EGL_RENDERABLE_TYPE 0x3040
|
||||||
|
#define EGL_OPENGL_ES_BIT 0x0001
|
||||||
|
#define EGL_OPENGL_ES2_BIT 0x0004
|
||||||
|
#define EGL_OPENGL_BIT 0x0008
|
||||||
|
#define EGL_ALPHA_SIZE 0x3021
|
||||||
|
#define EGL_BLUE_SIZE 0x3022
|
||||||
|
#define EGL_GREEN_SIZE 0x3023
|
||||||
|
#define EGL_RED_SIZE 0x3024
|
||||||
|
#define EGL_DEPTH_SIZE 0x3025
|
||||||
|
#define EGL_STENCIL_SIZE 0x3026
|
||||||
|
#define EGL_SAMPLES 0x3031
|
||||||
|
#define EGL_OPENGL_ES_API 0x30a0
|
||||||
|
#define EGL_OPENGL_API 0x30a2
|
||||||
|
#define EGL_NONE 0x3038
|
||||||
|
#define EGL_RENDER_BUFFER 0x3086
|
||||||
|
#define EGL_SINGLE_BUFFER 0x3085
|
||||||
|
#define EGL_EXTENSIONS 0x3055
|
||||||
|
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||||
|
#define EGL_NATIVE_VISUAL_ID 0x302e
|
||||||
|
#define EGL_NO_SURFACE ((EGLSurface) 0)
|
||||||
|
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
|
||||||
|
#define EGL_NO_CONTEXT ((EGLContext) 0)
|
||||||
|
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
|
||||||
|
|
||||||
|
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
|
||||||
|
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
|
||||||
|
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
|
||||||
|
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
|
||||||
|
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd
|
||||||
|
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be
|
||||||
|
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf
|
||||||
|
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
|
||||||
|
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
|
||||||
|
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
|
||||||
|
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
|
||||||
|
#define EGL_CONTEXT_FLAGS_KHR 0x30fc
|
||||||
|
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
|
||||||
|
#define EGL_GL_COLORSPACE_KHR 0x309d
|
||||||
|
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
|
||||||
|
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
|
||||||
|
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
|
||||||
|
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
|
||||||
|
#define EGL_PRESENT_OPAQUE_EXT 0x31df
|
||||||
|
|
||||||
|
typedef int EGLint;
|
||||||
|
typedef unsigned int EGLBoolean;
|
||||||
|
typedef unsigned int EGLenum;
|
||||||
|
typedef void* EGLConfig;
|
||||||
|
typedef void* EGLContext;
|
||||||
|
typedef void* EGLDisplay;
|
||||||
|
typedef void* EGLSurface;
|
||||||
|
|
||||||
|
// EGL function pointer typedefs
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
|
||||||
|
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
|
||||||
|
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);
|
||||||
|
typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
|
||||||
|
typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
|
||||||
|
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
|
||||||
|
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
|
||||||
|
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
|
||||||
|
#define eglGetConfigs _glfw.egl.GetConfigs
|
||||||
|
#define eglGetDisplay _glfw.egl.GetDisplay
|
||||||
|
#define eglGetError _glfw.egl.GetError
|
||||||
|
#define eglInitialize _glfw.egl.Initialize
|
||||||
|
#define eglTerminate _glfw.egl.Terminate
|
||||||
|
#define eglBindAPI _glfw.egl.BindAPI
|
||||||
|
#define eglCreateContext _glfw.egl.CreateContext
|
||||||
|
#define eglDestroySurface _glfw.egl.DestroySurface
|
||||||
|
#define eglDestroyContext _glfw.egl.DestroyContext
|
||||||
|
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
|
||||||
|
#define eglMakeCurrent _glfw.egl.MakeCurrent
|
||||||
|
#define eglSwapBuffers _glfw.egl.SwapBuffers
|
||||||
|
#define eglSwapInterval _glfw.egl.SwapInterval
|
||||||
|
#define eglQueryString _glfw.egl.QueryString
|
||||||
|
#define eglGetProcAddress _glfw.egl.GetProcAddress
|
||||||
|
|
||||||
|
#define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl
|
||||||
|
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
|
||||||
|
|
||||||
|
|
||||||
|
// EGL-specific per-context data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcontextEGL
|
||||||
|
{
|
||||||
|
EGLConfig config;
|
||||||
|
EGLContext handle;
|
||||||
|
EGLSurface surface;
|
||||||
|
|
||||||
|
void* client;
|
||||||
|
} _GLFWcontextEGL;
|
||||||
|
|
||||||
|
// EGL-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryEGL
|
||||||
|
{
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLint major, minor;
|
||||||
|
GLFWbool prefix;
|
||||||
|
|
||||||
|
GLFWbool KHR_create_context;
|
||||||
|
GLFWbool KHR_create_context_no_error;
|
||||||
|
GLFWbool KHR_gl_colorspace;
|
||||||
|
GLFWbool KHR_get_all_proc_addresses;
|
||||||
|
GLFWbool KHR_context_flush_control;
|
||||||
|
GLFWbool EXT_present_opaque;
|
||||||
|
|
||||||
|
void* handle;
|
||||||
|
|
||||||
|
PFN_eglGetConfigAttrib GetConfigAttrib;
|
||||||
|
PFN_eglGetConfigs GetConfigs;
|
||||||
|
PFN_eglGetDisplay GetDisplay;
|
||||||
|
PFN_eglGetError GetError;
|
||||||
|
PFN_eglInitialize Initialize;
|
||||||
|
PFN_eglTerminate Terminate;
|
||||||
|
PFN_eglBindAPI BindAPI;
|
||||||
|
PFN_eglCreateContext CreateContext;
|
||||||
|
PFN_eglDestroySurface DestroySurface;
|
||||||
|
PFN_eglDestroyContext DestroyContext;
|
||||||
|
PFN_eglCreateWindowSurface CreateWindowSurface;
|
||||||
|
PFN_eglMakeCurrent MakeCurrent;
|
||||||
|
PFN_eglSwapBuffers SwapBuffers;
|
||||||
|
PFN_eglSwapInterval SwapInterval;
|
||||||
|
PFN_eglQueryString QueryString;
|
||||||
|
PFN_eglGetProcAddress GetProcAddress;
|
||||||
|
} _GLFWlibraryEGL;
|
||||||
|
|
||||||
|
|
||||||
|
GLFWbool _glfwInitEGL(void);
|
||||||
|
void _glfwTerminateEGL(void);
|
||||||
|
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
#if defined(_GLFW_X11)
|
||||||
|
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig,
|
||||||
|
Visual** visual, int* depth);
|
||||||
|
#endif /*_GLFW_X11*/
|
||||||
|
|
13
external/glfw-3.3.8/src/glfw3.pc.in
vendored
Normal file
13
external/glfw-3.3.8/src/glfw3.pc.in
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=${prefix}
|
||||||
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
|
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||||
|
|
||||||
|
Name: GLFW
|
||||||
|
Description: A multi-platform library for OpenGL, window and input
|
||||||
|
Version: @GLFW_VERSION@
|
||||||
|
URL: https://www.glfw.org/
|
||||||
|
Requires.private: @GLFW_PKG_DEPS@
|
||||||
|
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
||||||
|
Libs.private: @GLFW_PKG_LIBS@
|
||||||
|
Cflags: -I${includedir}
|
1
external/glfw-3.3.8/src/glfw3Config.cmake.in
vendored
Normal file
1
external/glfw-3.3.8/src/glfw3Config.cmake.in
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
|
58
external/glfw-3.3.8/src/glfw_config.h.in
vendored
Normal file
58
external/glfw-3.3.8/src/glfw_config.h.in
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2010-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// As glfw_config.h.in, this file is used by CMake to produce the
|
||||||
|
// glfw_config.h configuration header file. If you are adding a feature
|
||||||
|
// requiring conditional compilation, this is where to add the macro.
|
||||||
|
//========================================================================
|
||||||
|
// As glfw_config.h, this file defines compile-time option macros for a
|
||||||
|
// specific platform and development environment. If you are using the
|
||||||
|
// GLFW CMake files, modify glfw_config.h.in instead of this file. If you
|
||||||
|
// are using your own build system, make this file define the appropriate
|
||||||
|
// macros in whatever way is suitable.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
// Define this to 1 if building GLFW for X11
|
||||||
|
#cmakedefine _GLFW_X11
|
||||||
|
// Define this to 1 if building GLFW for Win32
|
||||||
|
#cmakedefine _GLFW_WIN32
|
||||||
|
// Define this to 1 if building GLFW for Cocoa
|
||||||
|
#cmakedefine _GLFW_COCOA
|
||||||
|
// Define this to 1 if building GLFW for Wayland
|
||||||
|
#cmakedefine _GLFW_WAYLAND
|
||||||
|
// Define this to 1 if building GLFW for OSMesa
|
||||||
|
#cmakedefine _GLFW_OSMESA
|
||||||
|
|
||||||
|
// Define this to 1 if building as a shared library / dynamic library / DLL
|
||||||
|
#cmakedefine _GLFW_BUILD_DLL
|
||||||
|
// Define this to 1 to use Vulkan loader linked statically into application
|
||||||
|
#cmakedefine _GLFW_VULKAN_STATIC
|
||||||
|
|
||||||
|
// Define this to 1 to force use of high-performance GPU on hybrid systems
|
||||||
|
#cmakedefine _GLFW_USE_HYBRID_HPG
|
||||||
|
|
||||||
|
// Define this to 1 if the libc supports memfd_create()
|
||||||
|
#cmakedefine HAVE_MEMFD_CREATE
|
||||||
|
|
701
external/glfw-3.3.8/src/glx_context.c
vendored
Normal file
701
external/glfw-3.3.8/src/glx_context.c
vendored
Normal file
@ -0,0 +1,701 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 GLX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifndef GLXBadProfileARB
|
||||||
|
#define GLXBadProfileARB 13
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the specified attribute of the specified GLXFBConfig
|
||||||
|
//
|
||||||
|
static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the GLXFBConfig most closely matching the specified hints
|
||||||
|
//
|
||||||
|
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||||
|
GLXFBConfig* result)
|
||||||
|
{
|
||||||
|
GLXFBConfig* nativeConfigs;
|
||||||
|
_GLFWfbconfig* usableConfigs;
|
||||||
|
const _GLFWfbconfig* closest;
|
||||||
|
int i, nativeCount, usableCount;
|
||||||
|
const char* vendor;
|
||||||
|
GLFWbool trustWindowBit = GLFW_TRUE;
|
||||||
|
|
||||||
|
// HACK: This is a (hopefully temporary) workaround for Chromium
|
||||||
|
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
||||||
|
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
||||||
|
if (vendor && strcmp(vendor, "Chromium") == 0)
|
||||||
|
trustWindowBit = GLFW_FALSE;
|
||||||
|
|
||||||
|
nativeConfigs =
|
||||||
|
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
||||||
|
if (!nativeConfigs || !nativeCount)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||||
|
usableCount = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nativeCount; i++)
|
||||||
|
{
|
||||||
|
const GLXFBConfig n = nativeConfigs[i];
|
||||||
|
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||||
|
|
||||||
|
// Only consider RGBA GLXFBConfigs
|
||||||
|
if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Only consider window GLXFBConfigs
|
||||||
|
if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
|
||||||
|
{
|
||||||
|
if (trustWindowBit)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER) != desired->doublebuffer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (desired->transparent)
|
||||||
|
{
|
||||||
|
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
|
||||||
|
if (vi)
|
||||||
|
{
|
||||||
|
u->transparent = _glfwIsVisualTransparentX11(vi->visual);
|
||||||
|
XFree(vi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
|
||||||
|
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
|
||||||
|
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
|
||||||
|
|
||||||
|
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
|
||||||
|
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
|
||||||
|
u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
|
||||||
|
|
||||||
|
u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
|
||||||
|
u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
|
||||||
|
u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
|
||||||
|
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
|
||||||
|
|
||||||
|
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
|
||||||
|
|
||||||
|
if (getGLXFBConfigAttrib(n, GLX_STEREO))
|
||||||
|
u->stereo = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (_glfw.glx.ARB_multisample)
|
||||||
|
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
|
||||||
|
|
||||||
|
if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
|
||||||
|
u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
||||||
|
|
||||||
|
u->handle = (uintptr_t) n;
|
||||||
|
usableCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||||
|
if (closest)
|
||||||
|
*result = (GLXFBConfig) closest->handle;
|
||||||
|
|
||||||
|
XFree(nativeConfigs);
|
||||||
|
free(usableConfigs);
|
||||||
|
|
||||||
|
return closest != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the OpenGL context using legacy API
|
||||||
|
//
|
||||||
|
static GLXContext createLegacyContextGLX(_GLFWwindow* window,
|
||||||
|
GLXFBConfig fbconfig,
|
||||||
|
GLXContext share)
|
||||||
|
{
|
||||||
|
return glXCreateNewContext(_glfw.x11.display,
|
||||||
|
fbconfig,
|
||||||
|
GLX_RGBA_TYPE,
|
||||||
|
share,
|
||||||
|
True);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeContextCurrentGLX(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
if (!glXMakeCurrent(_glfw.x11.display,
|
||||||
|
window->context.glx.window,
|
||||||
|
window->context.glx.handle))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"GLX: Failed to make context current");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"GLX: Failed to clear current context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapBuffersGLX(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapIntervalGLX(int interval)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
|
||||||
|
if (_glfw.glx.EXT_swap_control)
|
||||||
|
{
|
||||||
|
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
|
||||||
|
window->context.glx.window,
|
||||||
|
interval);
|
||||||
|
}
|
||||||
|
else if (_glfw.glx.MESA_swap_control)
|
||||||
|
_glfw.glx.SwapIntervalMESA(interval);
|
||||||
|
else if (_glfw.glx.SGI_swap_control)
|
||||||
|
{
|
||||||
|
if (interval > 0)
|
||||||
|
_glfw.glx.SwapIntervalSGI(interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int extensionSupportedGLX(const char* extension)
|
||||||
|
{
|
||||||
|
const char* extensions =
|
||||||
|
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
if (extensions)
|
||||||
|
{
|
||||||
|
if (_glfwStringInExtensionString(extension, extensions))
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWglproc getProcAddressGLX(const char* procname)
|
||||||
|
{
|
||||||
|
if (_glfw.glx.GetProcAddress)
|
||||||
|
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
|
||||||
|
else if (_glfw.glx.GetProcAddressARB)
|
||||||
|
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
|
||||||
|
else
|
||||||
|
return _glfw_dlsym(_glfw.glx.handle, procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyContextGLX(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->context.glx.window)
|
||||||
|
{
|
||||||
|
glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
|
||||||
|
window->context.glx.window = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.glx.handle)
|
||||||
|
{
|
||||||
|
glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
|
||||||
|
window->context.glx.handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize GLX
|
||||||
|
//
|
||||||
|
GLFWbool _glfwInitGLX(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char* sonames[] =
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_GLX_LIBRARY)
|
||||||
|
_GLFW_GLX_LIBRARY,
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
"libGL-1.so",
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
"libGL.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 = _glfw_dlopen(sonames[i]);
|
||||||
|
if (_glfw.glx.handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.glx.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.glx.GetFBConfigs =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs");
|
||||||
|
_glfw.glx.GetFBConfigAttrib =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||||
|
_glfw.glx.GetClientString =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString");
|
||||||
|
_glfw.glx.QueryExtension =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension");
|
||||||
|
_glfw.glx.QueryVersion =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion");
|
||||||
|
_glfw.glx.DestroyContext =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext");
|
||||||
|
_glfw.glx.MakeCurrent =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent");
|
||||||
|
_glfw.glx.SwapBuffers =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers");
|
||||||
|
_glfw.glx.QueryExtensionsString =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
|
||||||
|
_glfw.glx.CreateNewContext =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext");
|
||||||
|
_glfw.glx.CreateWindow =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
|
||||||
|
_glfw.glx.DestroyWindow =
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
|
||||||
|
_glfw.glx.GetVisualFromFBConfig =
|
||||||
|
_glfw_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.GetVisualFromFBConfig)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"GLX: Failed to load required entry points");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Unlike GLX 1.3 entry points these are not required to be present
|
||||||
|
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
|
||||||
|
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
|
||||||
|
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
|
||||||
|
|
||||||
|
if (!glXQueryExtension(_glfw.x11.display,
|
||||||
|
&_glfw.glx.errorBase,
|
||||||
|
&_glfw.glx.eventBase))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"GLX: Failed to query GLX version");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"GLX: GLX version 1.3 is required");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_EXT_swap_control"))
|
||||||
|
{
|
||||||
|
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
|
||||||
|
getProcAddressGLX("glXSwapIntervalEXT");
|
||||||
|
|
||||||
|
if (_glfw.glx.SwapIntervalEXT)
|
||||||
|
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_SGI_swap_control"))
|
||||||
|
{
|
||||||
|
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
|
||||||
|
getProcAddressGLX("glXSwapIntervalSGI");
|
||||||
|
|
||||||
|
if (_glfw.glx.SwapIntervalSGI)
|
||||||
|
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_MESA_swap_control"))
|
||||||
|
{
|
||||||
|
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
|
||||||
|
getProcAddressGLX("glXSwapIntervalMESA");
|
||||||
|
|
||||||
|
if (_glfw.glx.SwapIntervalMESA)
|
||||||
|
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_multisample"))
|
||||||
|
_glfw.glx.ARB_multisample = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
|
||||||
|
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
|
||||||
|
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_create_context"))
|
||||||
|
{
|
||||||
|
_glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
|
||||||
|
getProcAddressGLX("glXCreateContextAttribsARB");
|
||||||
|
|
||||||
|
if (_glfw.glx.CreateContextAttribsARB)
|
||||||
|
_glfw.glx.ARB_create_context = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
|
||||||
|
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
|
||||||
|
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
|
||||||
|
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
|
||||||
|
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
|
||||||
|
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate GLX
|
||||||
|
//
|
||||||
|
void _glfwTerminateGLX(void)
|
||||||
|
{
|
||||||
|
// NOTE: This function must not call any X11 functions, as it is called
|
||||||
|
// after XCloseDisplay (see _glfwPlatformTerminate for details)
|
||||||
|
|
||||||
|
if (_glfw.glx.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.glx.handle);
|
||||||
|
_glfw.glx.handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define setAttrib(a, v) \
|
||||||
|
{ \
|
||||||
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
|
attribs[index++] = a; \
|
||||||
|
attribs[index++] = v; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the OpenGL or OpenGL ES context
|
||||||
|
//
|
||||||
|
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
int attribs[40];
|
||||||
|
GLXFBConfig native = NULL;
|
||||||
|
GLXContext share = NULL;
|
||||||
|
|
||||||
|
if (ctxconfig->share)
|
||||||
|
share = ctxconfig->share->context.glx.handle;
|
||||||
|
|
||||||
|
if (!chooseGLXFBConfig(fbconfig, &native))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"GLX: Failed to find a suitable GLXFBConfig");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
if (!_glfw.glx.ARB_create_context ||
|
||||||
|
!_glfw.glx.ARB_create_context_profile ||
|
||||||
|
!_glfw.glx.EXT_create_context_es2_profile)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
{
|
||||||
|
if (!_glfw.glx.ARB_create_context)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->profile)
|
||||||
|
{
|
||||||
|
if (!_glfw.glx.ARB_create_context ||
|
||||||
|
!_glfw.glx.ARB_create_context_profile)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwGrabErrorHandlerX11();
|
||||||
|
|
||||||
|
if (_glfw.glx.ARB_create_context)
|
||||||
|
{
|
||||||
|
int index = 0, mask = 0, flags = 0;
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||||
|
|
||||||
|
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||||
|
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
|
mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
|
||||||
|
|
||||||
|
if (ctxconfig->debug)
|
||||||
|
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
|
||||||
|
|
||||||
|
if (ctxconfig->robustness)
|
||||||
|
{
|
||||||
|
if (_glfw.glx.ARB_create_context_robustness)
|
||||||
|
{
|
||||||
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
|
{
|
||||||
|
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
|
GLX_NO_RESET_NOTIFICATION_ARB);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
|
{
|
||||||
|
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
|
GLX_LOSE_CONTEXT_ON_RESET_ARB);
|
||||||
|
}
|
||||||
|
|
||||||
|
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->release)
|
||||||
|
{
|
||||||
|
if (_glfw.glx.ARB_context_flush_control)
|
||||||
|
{
|
||||||
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
|
{
|
||||||
|
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
|
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
|
{
|
||||||
|
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
|
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->noerror)
|
||||||
|
{
|
||||||
|
if (_glfw.glx.ARB_create_context_no_error)
|
||||||
|
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
|
// explicitly requesting version 1.0 does not always return the
|
||||||
|
// highest version supported by the driver
|
||||||
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
|
{
|
||||||
|
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||||
|
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
|
||||||
|
|
||||||
|
setAttrib(None, None);
|
||||||
|
|
||||||
|
window->context.glx.handle =
|
||||||
|
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
|
||||||
|
native,
|
||||||
|
share,
|
||||||
|
True,
|
||||||
|
attribs);
|
||||||
|
|
||||||
|
// HACK: This is a fallback for broken versions of the Mesa
|
||||||
|
// implementation of GLX_ARB_create_context_profile that fail
|
||||||
|
// default 1.0 context creation with a GLXBadProfileARB error in
|
||||||
|
// violation of the extension spec
|
||||||
|
if (!window->context.glx.handle)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
|
||||||
|
ctxconfig->client == GLFW_OPENGL_API &&
|
||||||
|
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
|
||||||
|
ctxconfig->forward == GLFW_FALSE)
|
||||||
|
{
|
||||||
|
window->context.glx.handle =
|
||||||
|
createLegacyContextGLX(window, native, share);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->context.glx.handle =
|
||||||
|
createLegacyContextGLX(window, native, share);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwReleaseErrorHandlerX11();
|
||||||
|
|
||||||
|
if (!window->context.glx.handle)
|
||||||
|
{
|
||||||
|
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.glx.window =
|
||||||
|
glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
|
||||||
|
if (!window->context.glx.window)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.makeCurrent = makeContextCurrentGLX;
|
||||||
|
window->context.swapBuffers = swapBuffersGLX;
|
||||||
|
window->context.swapInterval = swapIntervalGLX;
|
||||||
|
window->context.extensionSupported = extensionSupportedGLX;
|
||||||
|
window->context.getProcAddress = getProcAddressGLX;
|
||||||
|
window->context.destroy = destroyContextGLX;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef setAttrib
|
||||||
|
|
||||||
|
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||||
|
//
|
||||||
|
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig,
|
||||||
|
Visual** visual, int* depth)
|
||||||
|
{
|
||||||
|
GLXFBConfig native;
|
||||||
|
XVisualInfo* result;
|
||||||
|
|
||||||
|
if (!chooseGLXFBConfig(fbconfig, &native))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"GLX: Failed to find a suitable GLXFBConfig");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"GLX: Failed to retrieve Visual for GLXFBConfig");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*visual = result->visual;
|
||||||
|
*depth = result->depth;
|
||||||
|
|
||||||
|
XFree(result);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW native API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (window->context.source != GLFW_NATIVE_CONTEXT_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.source != GLFW_NATIVE_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window->context.glx.window;
|
||||||
|
}
|
||||||
|
|
179
external/glfw-3.3.8/src/glx_context.h
vendored
Normal file
179
external/glfw-3.3.8/src/glx_context.h
vendored
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 GLX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define GLX_VENDOR 1
|
||||||
|
#define GLX_RGBA_BIT 0x00000001
|
||||||
|
#define GLX_WINDOW_BIT 0x00000001
|
||||||
|
#define GLX_DRAWABLE_TYPE 0x8010
|
||||||
|
#define GLX_RENDER_TYPE 0x8011
|
||||||
|
#define GLX_RGBA_TYPE 0x8014
|
||||||
|
#define GLX_DOUBLEBUFFER 5
|
||||||
|
#define GLX_STEREO 6
|
||||||
|
#define GLX_AUX_BUFFERS 7
|
||||||
|
#define GLX_RED_SIZE 8
|
||||||
|
#define GLX_GREEN_SIZE 9
|
||||||
|
#define GLX_BLUE_SIZE 10
|
||||||
|
#define GLX_ALPHA_SIZE 11
|
||||||
|
#define GLX_DEPTH_SIZE 12
|
||||||
|
#define GLX_STENCIL_SIZE 13
|
||||||
|
#define GLX_ACCUM_RED_SIZE 14
|
||||||
|
#define GLX_ACCUM_GREEN_SIZE 15
|
||||||
|
#define GLX_ACCUM_BLUE_SIZE 16
|
||||||
|
#define GLX_ACCUM_ALPHA_SIZE 17
|
||||||
|
#define GLX_SAMPLES 0x186a1
|
||||||
|
#define GLX_VISUAL_ID 0x800b
|
||||||
|
|
||||||
|
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2
|
||||||
|
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||||
|
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
|
||||||
|
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||||
|
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||||
|
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||||
|
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||||
|
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||||
|
#define GLX_CONTEXT_FLAGS_ARB 0x2094
|
||||||
|
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
||||||
|
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
|
||||||
|
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||||
|
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
|
||||||
|
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||||
|
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||||
|
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||||
|
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||||
|
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
||||||
|
|
||||||
|
typedef XID GLXWindow;
|
||||||
|
typedef XID GLXDrawable;
|
||||||
|
typedef struct __GLXFBConfig* GLXFBConfig;
|
||||||
|
typedef struct __GLXcontext* GLXContext;
|
||||||
|
typedef void (*__GLXextproc)(void);
|
||||||
|
|
||||||
|
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
|
||||||
|
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
|
||||||
|
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
|
||||||
|
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
|
||||||
|
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
|
||||||
|
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
|
||||||
|
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
|
||||||
|
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
|
||||||
|
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
|
||||||
|
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
|
||||||
|
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);
|
||||||
|
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
|
||||||
|
typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);
|
||||||
|
typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);
|
||||||
|
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
|
||||||
|
|
||||||
|
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
|
||||||
|
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
||||||
|
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
|
||||||
|
|
||||||
|
// libGL.so function pointer typedefs
|
||||||
|
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
|
||||||
|
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
|
||||||
|
#define glXGetClientString _glfw.glx.GetClientString
|
||||||
|
#define glXQueryExtension _glfw.glx.QueryExtension
|
||||||
|
#define glXQueryVersion _glfw.glx.QueryVersion
|
||||||
|
#define glXDestroyContext _glfw.glx.DestroyContext
|
||||||
|
#define glXMakeCurrent _glfw.glx.MakeCurrent
|
||||||
|
#define glXSwapBuffers _glfw.glx.SwapBuffers
|
||||||
|
#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString
|
||||||
|
#define glXCreateNewContext _glfw.glx.CreateNewContext
|
||||||
|
#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
|
||||||
|
#define glXCreateWindow _glfw.glx.CreateWindow
|
||||||
|
#define glXDestroyWindow _glfw.glx.DestroyWindow
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
|
||||||
|
|
||||||
|
|
||||||
|
// GLX-specific per-context data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcontextGLX
|
||||||
|
{
|
||||||
|
GLXContext handle;
|
||||||
|
GLXWindow window;
|
||||||
|
} _GLFWcontextGLX;
|
||||||
|
|
||||||
|
// GLX-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryGLX
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
|
||||||
|
// dlopen handle for libGL.so.1
|
||||||
|
void* handle;
|
||||||
|
|
||||||
|
// GLX 1.3 functions
|
||||||
|
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
|
||||||
|
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
|
||||||
|
PFNGLXGETCLIENTSTRINGPROC GetClientString;
|
||||||
|
PFNGLXQUERYEXTENSIONPROC QueryExtension;
|
||||||
|
PFNGLXQUERYVERSIONPROC QueryVersion;
|
||||||
|
PFNGLXDESTROYCONTEXTPROC DestroyContext;
|
||||||
|
PFNGLXMAKECURRENTPROC MakeCurrent;
|
||||||
|
PFNGLXSWAPBUFFERSPROC SwapBuffers;
|
||||||
|
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
|
||||||
|
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
|
||||||
|
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
|
||||||
|
PFNGLXCREATEWINDOWPROC CreateWindow;
|
||||||
|
PFNGLXDESTROYWINDOWPROC DestroyWindow;
|
||||||
|
|
||||||
|
// GLX 1.4 and extension functions
|
||||||
|
PFNGLXGETPROCADDRESSPROC GetProcAddress;
|
||||||
|
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
|
||||||
|
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
|
||||||
|
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||||
|
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
|
||||||
|
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||||
|
GLFWbool SGI_swap_control;
|
||||||
|
GLFWbool EXT_swap_control;
|
||||||
|
GLFWbool MESA_swap_control;
|
||||||
|
GLFWbool ARB_multisample;
|
||||||
|
GLFWbool ARB_framebuffer_sRGB;
|
||||||
|
GLFWbool EXT_framebuffer_sRGB;
|
||||||
|
GLFWbool ARB_create_context;
|
||||||
|
GLFWbool ARB_create_context_profile;
|
||||||
|
GLFWbool ARB_create_context_robustness;
|
||||||
|
GLFWbool EXT_create_context_es2_profile;
|
||||||
|
GLFWbool ARB_create_context_no_error;
|
||||||
|
GLFWbool ARB_context_flush_control;
|
||||||
|
} _GLFWlibraryGLX;
|
||||||
|
|
||||||
|
GLFWbool _glfwInitGLX(void);
|
||||||
|
void _glfwTerminateGLX(void);
|
||||||
|
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
||||||
|
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig,
|
||||||
|
Visual** visual, int* depth);
|
||||||
|
|
420
external/glfw-3.3.8/src/init.c
vendored
Normal file
420
external/glfw-3.3.8/src/init.c
vendored
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: The global variables below comprise all mutable global data in GLFW
|
||||||
|
// Any other mutable global variable is a bug
|
||||||
|
|
||||||
|
// This contains all mutable state shared between compilation units of GLFW
|
||||||
|
//
|
||||||
|
_GLFWlibrary _glfw = { GLFW_FALSE };
|
||||||
|
|
||||||
|
// These are outside of _glfw so they can be used before initialization and
|
||||||
|
// after termination without special handling when _glfw is cleared to zero
|
||||||
|
//
|
||||||
|
static _GLFWerror _glfwMainThreadError;
|
||||||
|
static GLFWerrorfun _glfwErrorCallback;
|
||||||
|
static _GLFWinitconfig _glfwInitHints =
|
||||||
|
{
|
||||||
|
GLFW_TRUE, // hat buttons
|
||||||
|
{
|
||||||
|
GLFW_TRUE, // macOS menu bar
|
||||||
|
GLFW_TRUE // macOS bundle chdir
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Terminate the library
|
||||||
|
//
|
||||||
|
static void terminate(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
|
||||||
|
|
||||||
|
while (_glfw.windowListHead)
|
||||||
|
glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
|
||||||
|
|
||||||
|
while (_glfw.cursorListHead)
|
||||||
|
glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead);
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = _glfw.monitors[i];
|
||||||
|
if (monitor->originalRamp.size)
|
||||||
|
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
||||||
|
_glfwFreeMonitor(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(_glfw.monitors);
|
||||||
|
_glfw.monitors = NULL;
|
||||||
|
_glfw.monitorCount = 0;
|
||||||
|
|
||||||
|
free(_glfw.mappings);
|
||||||
|
_glfw.mappings = NULL;
|
||||||
|
_glfw.mappingCount = 0;
|
||||||
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
_glfwPlatformTerminate();
|
||||||
|
|
||||||
|
_glfw.initialized = GLFW_FALSE;
|
||||||
|
|
||||||
|
while (_glfw.errorListHead)
|
||||||
|
{
|
||||||
|
_GLFWerror* error = _glfw.errorListHead;
|
||||||
|
_glfw.errorListHead = error->next;
|
||||||
|
free(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformDestroyTls(&_glfw.contextSlot);
|
||||||
|
_glfwPlatformDestroyTls(&_glfw.errorSlot);
|
||||||
|
_glfwPlatformDestroyMutex(&_glfw.errorLock);
|
||||||
|
|
||||||
|
memset(&_glfw, 0, sizeof(_glfw));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Encode a Unicode code point to a UTF-8 stream
|
||||||
|
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||||
|
//
|
||||||
|
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
if (codepoint < 0x80)
|
||||||
|
s[count++] = (char) codepoint;
|
||||||
|
else if (codepoint < 0x800)
|
||||||
|
{
|
||||||
|
s[count++] = (codepoint >> 6) | 0xc0;
|
||||||
|
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (codepoint < 0x10000)
|
||||||
|
{
|
||||||
|
s[count++] = (codepoint >> 12) | 0xe0;
|
||||||
|
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (codepoint < 0x110000)
|
||||||
|
{
|
||||||
|
s[count++] = (codepoint >> 18) | 0xf0;
|
||||||
|
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
|
||||||
|
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splits and translates a text/uri-list into separate file paths
|
||||||
|
// NOTE: This function destroys the provided string
|
||||||
|
//
|
||||||
|
char** _glfwParseUriList(char* text, int* count)
|
||||||
|
{
|
||||||
|
const char* prefix = "file://";
|
||||||
|
char** paths = NULL;
|
||||||
|
char* line;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
while ((line = strtok(text, "\r\n")))
|
||||||
|
{
|
||||||
|
char* path;
|
||||||
|
|
||||||
|
text = NULL;
|
||||||
|
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strncmp(line, prefix, strlen(prefix)) == 0)
|
||||||
|
{
|
||||||
|
line += strlen(prefix);
|
||||||
|
// TODO: Validate hostname
|
||||||
|
while (*line != '/')
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*count)++;
|
||||||
|
|
||||||
|
path = 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 = (char) strtol(digits, NULL, 16);
|
||||||
|
line += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*path = *line;
|
||||||
|
|
||||||
|
path++;
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* _glfw_strdup(const char* source)
|
||||||
|
{
|
||||||
|
const size_t length = strlen(source);
|
||||||
|
char* result = calloc(length + 1, 1);
|
||||||
|
strcpy(result, source);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfw_min(int a, int b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfw_max(int a, int b)
|
||||||
|
{
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float _glfw_fminf(float a, float b)
|
||||||
|
{
|
||||||
|
if (a != a)
|
||||||
|
return b;
|
||||||
|
else if (b != b)
|
||||||
|
return a;
|
||||||
|
else if (a < b)
|
||||||
|
return a;
|
||||||
|
else
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float _glfw_fmaxf(float a, float b)
|
||||||
|
{
|
||||||
|
if (a != a)
|
||||||
|
return b;
|
||||||
|
else if (b != b)
|
||||||
|
return a;
|
||||||
|
else if (a > b)
|
||||||
|
return a;
|
||||||
|
else
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW event API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Notifies shared code of an error
|
||||||
|
//
|
||||||
|
void _glfwInputError(int code, const char* format, ...)
|
||||||
|
{
|
||||||
|
_GLFWerror* error;
|
||||||
|
char description[_GLFW_MESSAGE_SIZE];
|
||||||
|
|
||||||
|
if (format)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
|
||||||
|
va_start(vl, format);
|
||||||
|
vsnprintf(description, sizeof(description), format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
description[sizeof(description) - 1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (code == GLFW_NOT_INITIALIZED)
|
||||||
|
strcpy(description, "The GLFW library is not initialized");
|
||||||
|
else if (code == GLFW_NO_CURRENT_CONTEXT)
|
||||||
|
strcpy(description, "There is no current context");
|
||||||
|
else if (code == GLFW_INVALID_ENUM)
|
||||||
|
strcpy(description, "Invalid argument for enum parameter");
|
||||||
|
else if (code == GLFW_INVALID_VALUE)
|
||||||
|
strcpy(description, "Invalid value for parameter");
|
||||||
|
else if (code == GLFW_OUT_OF_MEMORY)
|
||||||
|
strcpy(description, "Out of memory");
|
||||||
|
else if (code == GLFW_API_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested API is unavailable");
|
||||||
|
else if (code == GLFW_VERSION_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested API version is unavailable");
|
||||||
|
else if (code == GLFW_PLATFORM_ERROR)
|
||||||
|
strcpy(description, "A platform-specific error occurred");
|
||||||
|
else if (code == GLFW_FORMAT_UNAVAILABLE)
|
||||||
|
strcpy(description, "The requested format is unavailable");
|
||||||
|
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
||||||
|
strcpy(description, "The specified window has no context");
|
||||||
|
else
|
||||||
|
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.initialized)
|
||||||
|
{
|
||||||
|
error = _glfwPlatformGetTls(&_glfw.errorSlot);
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
error = calloc(1, sizeof(_GLFWerror));
|
||||||
|
_glfwPlatformSetTls(&_glfw.errorSlot, error);
|
||||||
|
_glfwPlatformLockMutex(&_glfw.errorLock);
|
||||||
|
error->next = _glfw.errorListHead;
|
||||||
|
_glfw.errorListHead = error;
|
||||||
|
_glfwPlatformUnlockMutex(&_glfw.errorLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = &_glfwMainThreadError;
|
||||||
|
|
||||||
|
error->code = code;
|
||||||
|
strcpy(error->description, description);
|
||||||
|
|
||||||
|
if (_glfwErrorCallback)
|
||||||
|
_glfwErrorCallback(code, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW public API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI int glfwInit(void)
|
||||||
|
{
|
||||||
|
if (_glfw.initialized)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
memset(&_glfw, 0, sizeof(_glfw));
|
||||||
|
_glfw.hints.init = _glfwInitHints;
|
||||||
|
|
||||||
|
if (!_glfwPlatformInit())
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
|
||||||
|
!_glfwPlatformCreateTls(&_glfw.errorSlot) ||
|
||||||
|
!_glfwPlatformCreateTls(&_glfw.contextSlot))
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
|
||||||
|
|
||||||
|
_glfwInitGamepadMappings();
|
||||||
|
|
||||||
|
_glfw.initialized = GLFW_TRUE;
|
||||||
|
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
||||||
|
|
||||||
|
glfwDefaultWindowHints();
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwTerminate(void)
|
||||||
|
{
|
||||||
|
if (!_glfw.initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwInitHint(int hint, int value)
|
||||||
|
{
|
||||||
|
switch (hint)
|
||||||
|
{
|
||||||
|
case GLFW_JOYSTICK_HAT_BUTTONS:
|
||||||
|
_glfwInitHints.hatButtons = value;
|
||||||
|
return;
|
||||||
|
case GLFW_COCOA_CHDIR_RESOURCES:
|
||||||
|
_glfwInitHints.ns.chdir = value;
|
||||||
|
return;
|
||||||
|
case GLFW_COCOA_MENUBAR:
|
||||||
|
_glfwInitHints.ns.menubar = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
"Invalid init hint 0x%08X", hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||||
|
{
|
||||||
|
if (major != NULL)
|
||||||
|
*major = GLFW_VERSION_MAJOR;
|
||||||
|
if (minor != NULL)
|
||||||
|
*minor = GLFW_VERSION_MINOR;
|
||||||
|
if (rev != NULL)
|
||||||
|
*rev = GLFW_VERSION_REVISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI const char* glfwGetVersionString(void)
|
||||||
|
{
|
||||||
|
return _glfwPlatformGetVersionString();
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI int glfwGetError(const char** description)
|
||||||
|
{
|
||||||
|
_GLFWerror* error;
|
||||||
|
int code = GLFW_NO_ERROR;
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
*description = NULL;
|
||||||
|
|
||||||
|
if (_glfw.initialized)
|
||||||
|
error = _glfwPlatformGetTls(&_glfw.errorSlot);
|
||||||
|
else
|
||||||
|
error = &_glfwMainThreadError;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
code = error->code;
|
||||||
|
error->code = GLFW_NO_ERROR;
|
||||||
|
if (description && code)
|
||||||
|
*description = error->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
||||||
|
{
|
||||||
|
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
|
||||||
|
return cbfun;
|
||||||
|
}
|
||||||
|
|
1380
external/glfw-3.3.8/src/input.c
vendored
Normal file
1380
external/glfw-3.3.8/src/input.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
786
external/glfw-3.3.8/src/internal.h
vendored
Normal file
786
external/glfw-3.3.8/src/internal.h
vendored
Normal file
@ -0,0 +1,786 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_GLFW_USE_CONFIG_H)
|
||||||
|
#include "glfw_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLFW_INCLUDE_GLCOREARB) || \
|
||||||
|
defined(GLFW_INCLUDE_ES1) || \
|
||||||
|
defined(GLFW_INCLUDE_ES2) || \
|
||||||
|
defined(GLFW_INCLUDE_ES3) || \
|
||||||
|
defined(GLFW_INCLUDE_ES31) || \
|
||||||
|
defined(GLFW_INCLUDE_ES32) || \
|
||||||
|
defined(GLFW_INCLUDE_NONE) || \
|
||||||
|
defined(GLFW_INCLUDE_GLEXT) || \
|
||||||
|
defined(GLFW_INCLUDE_GLU) || \
|
||||||
|
defined(GLFW_INCLUDE_VULKAN) || \
|
||||||
|
defined(GLFW_DLL)
|
||||||
|
#error "You must not define any header option macros when compiling GLFW"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
|
#include "../include/GLFW/glfw3.h"
|
||||||
|
|
||||||
|
#define _GLFW_INSERT_FIRST 0
|
||||||
|
#define _GLFW_INSERT_LAST 1
|
||||||
|
|
||||||
|
#define _GLFW_POLL_PRESENCE 0
|
||||||
|
#define _GLFW_POLL_AXES 1
|
||||||
|
#define _GLFW_POLL_BUTTONS 2
|
||||||
|
#define _GLFW_POLL_ALL (_GLFW_POLL_AXES | _GLFW_POLL_BUTTONS)
|
||||||
|
|
||||||
|
#define _GLFW_MESSAGE_SIZE 1024
|
||||||
|
|
||||||
|
typedef int GLFWbool;
|
||||||
|
|
||||||
|
typedef struct _GLFWerror _GLFWerror;
|
||||||
|
typedef struct _GLFWinitconfig _GLFWinitconfig;
|
||||||
|
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
||||||
|
typedef struct _GLFWctxconfig _GLFWctxconfig;
|
||||||
|
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
||||||
|
typedef struct _GLFWcontext _GLFWcontext;
|
||||||
|
typedef struct _GLFWwindow _GLFWwindow;
|
||||||
|
typedef struct _GLFWlibrary _GLFWlibrary;
|
||||||
|
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||||
|
typedef struct _GLFWcursor _GLFWcursor;
|
||||||
|
typedef struct _GLFWmapelement _GLFWmapelement;
|
||||||
|
typedef struct _GLFWmapping _GLFWmapping;
|
||||||
|
typedef struct _GLFWjoystick _GLFWjoystick;
|
||||||
|
typedef struct _GLFWtls _GLFWtls;
|
||||||
|
typedef struct _GLFWmutex _GLFWmutex;
|
||||||
|
|
||||||
|
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
|
||||||
|
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
|
||||||
|
typedef void (* _GLFWswapintervalfun)(int);
|
||||||
|
typedef int (* _GLFWextensionsupportedfun)(const char*);
|
||||||
|
typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
|
||||||
|
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
||||||
|
|
||||||
|
#define GL_VERSION 0x1f02
|
||||||
|
#define GL_NONE 0
|
||||||
|
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||||
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
|
#define GL_EXTENSIONS 0x1f03
|
||||||
|
#define GL_NUM_EXTENSIONS 0x821d
|
||||||
|
#define GL_CONTEXT_FLAGS 0x821e
|
||||||
|
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
|
||||||
|
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
|
||||||
|
#define GL_CONTEXT_PROFILE_MASK 0x9126
|
||||||
|
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||||
|
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
|
||||||
|
#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
|
||||||
|
#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||||
|
#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||||
|
#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82fb
|
||||||
|
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
|
||||||
|
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
|
||||||
|
|
||||||
|
typedef int GLint;
|
||||||
|
typedef unsigned int GLuint;
|
||||||
|
typedef unsigned int GLenum;
|
||||||
|
typedef unsigned int GLbitfield;
|
||||||
|
typedef unsigned char GLubyte;
|
||||||
|
|
||||||
|
typedef void (APIENTRY * PFNGLCLEARPROC)(GLbitfield);
|
||||||
|
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
|
||||||
|
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
|
||||||
|
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
||||||
|
|
||||||
|
#define VK_NULL_HANDLE 0
|
||||||
|
|
||||||
|
typedef void* VkInstance;
|
||||||
|
typedef void* VkPhysicalDevice;
|
||||||
|
typedef uint64_t VkSurfaceKHR;
|
||||||
|
typedef uint32_t VkFlags;
|
||||||
|
typedef uint32_t VkBool32;
|
||||||
|
|
||||||
|
typedef enum VkStructureType
|
||||||
|
{
|
||||||
|
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
|
||||||
|
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
|
||||||
|
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
||||||
|
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
||||||
|
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
||||||
|
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
|
||||||
|
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_OSMESA)
|
||||||
|
#include "null_platform.h"
|
||||||
|
#else
|
||||||
|
#error "No supported window creation API selected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Constructs a version number string from the public header macros
|
||||||
|
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
||||||
|
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
|
||||||
|
#define _GLFW_VERSION_NUMBER _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, \
|
||||||
|
GLFW_VERSION_MINOR, \
|
||||||
|
GLFW_VERSION_REVISION)
|
||||||
|
|
||||||
|
// Checks for whether the library has been initialized
|
||||||
|
#define _GLFW_REQUIRE_INIT() \
|
||||||
|
if (!_glfw.initialized) \
|
||||||
|
{ \
|
||||||
|
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \
|
||||||
|
if (!_glfw.initialized) \
|
||||||
|
{ \
|
||||||
|
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
|
||||||
|
return x; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swaps the provided pointers
|
||||||
|
#define _GLFW_SWAP_POINTERS(x, y) \
|
||||||
|
{ \
|
||||||
|
void* t; \
|
||||||
|
t = x; \
|
||||||
|
x = y; \
|
||||||
|
y = t; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-thread error structure
|
||||||
|
//
|
||||||
|
struct _GLFWerror
|
||||||
|
{
|
||||||
|
_GLFWerror* next;
|
||||||
|
int code;
|
||||||
|
char description[_GLFW_MESSAGE_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialization configuration
|
||||||
|
//
|
||||||
|
// Parameters relating to the initialization of the library
|
||||||
|
//
|
||||||
|
struct _GLFWinitconfig
|
||||||
|
{
|
||||||
|
GLFWbool hatButtons;
|
||||||
|
struct {
|
||||||
|
GLFWbool menubar;
|
||||||
|
GLFWbool chdir;
|
||||||
|
} ns;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Window configuration
|
||||||
|
//
|
||||||
|
// Parameters relating to the creation of the window but not directly related
|
||||||
|
// to the framebuffer. This is used to pass window creation parameters from
|
||||||
|
// shared code to the platform API.
|
||||||
|
//
|
||||||
|
struct _GLFWwndconfig
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
const char* title;
|
||||||
|
GLFWbool resizable;
|
||||||
|
GLFWbool visible;
|
||||||
|
GLFWbool decorated;
|
||||||
|
GLFWbool focused;
|
||||||
|
GLFWbool autoIconify;
|
||||||
|
GLFWbool floating;
|
||||||
|
GLFWbool maximized;
|
||||||
|
GLFWbool centerCursor;
|
||||||
|
GLFWbool focusOnShow;
|
||||||
|
GLFWbool scaleToMonitor;
|
||||||
|
struct {
|
||||||
|
GLFWbool retina;
|
||||||
|
char frameName[256];
|
||||||
|
} ns;
|
||||||
|
struct {
|
||||||
|
char className[256];
|
||||||
|
char instanceName[256];
|
||||||
|
} x11;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Context configuration
|
||||||
|
//
|
||||||
|
// Parameters relating to the creation of the context but not directly related
|
||||||
|
// to the framebuffer. This is used to pass context creation parameters from
|
||||||
|
// shared code to the platform API.
|
||||||
|
//
|
||||||
|
struct _GLFWctxconfig
|
||||||
|
{
|
||||||
|
int client;
|
||||||
|
int source;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
GLFWbool forward;
|
||||||
|
GLFWbool debug;
|
||||||
|
GLFWbool noerror;
|
||||||
|
int profile;
|
||||||
|
int robustness;
|
||||||
|
int release;
|
||||||
|
_GLFWwindow* share;
|
||||||
|
struct {
|
||||||
|
GLFWbool offline;
|
||||||
|
} nsgl;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Framebuffer configuration
|
||||||
|
//
|
||||||
|
// This describes buffers and their sizes. It also contains
|
||||||
|
// a platform-specific ID used to map back to the backend API object.
|
||||||
|
//
|
||||||
|
// It is used to pass framebuffer parameters from shared code to the platform
|
||||||
|
// API and also to enumerate and select available framebuffer configs.
|
||||||
|
//
|
||||||
|
struct _GLFWfbconfig
|
||||||
|
{
|
||||||
|
int redBits;
|
||||||
|
int greenBits;
|
||||||
|
int blueBits;
|
||||||
|
int alphaBits;
|
||||||
|
int depthBits;
|
||||||
|
int stencilBits;
|
||||||
|
int accumRedBits;
|
||||||
|
int accumGreenBits;
|
||||||
|
int accumBlueBits;
|
||||||
|
int accumAlphaBits;
|
||||||
|
int auxBuffers;
|
||||||
|
GLFWbool stereo;
|
||||||
|
int samples;
|
||||||
|
GLFWbool sRGB;
|
||||||
|
GLFWbool doublebuffer;
|
||||||
|
GLFWbool transparent;
|
||||||
|
uintptr_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Context structure
|
||||||
|
//
|
||||||
|
struct _GLFWcontext
|
||||||
|
{
|
||||||
|
int client;
|
||||||
|
int source;
|
||||||
|
int major, minor, revision;
|
||||||
|
GLFWbool forward, debug, noerror;
|
||||||
|
int profile;
|
||||||
|
int robustness;
|
||||||
|
int release;
|
||||||
|
|
||||||
|
PFNGLGETSTRINGIPROC GetStringi;
|
||||||
|
PFNGLGETINTEGERVPROC GetIntegerv;
|
||||||
|
PFNGLGETSTRINGPROC GetString;
|
||||||
|
|
||||||
|
_GLFWmakecontextcurrentfun makeCurrent;
|
||||||
|
_GLFWswapbuffersfun swapBuffers;
|
||||||
|
_GLFWswapintervalfun swapInterval;
|
||||||
|
_GLFWextensionsupportedfun extensionSupported;
|
||||||
|
_GLFWgetprocaddressfun getProcAddress;
|
||||||
|
_GLFWdestroycontextfun destroy;
|
||||||
|
|
||||||
|
// This is defined in the context API's context.h
|
||||||
|
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||||
|
// This is defined in egl_context.h
|
||||||
|
_GLFW_EGL_CONTEXT_STATE;
|
||||||
|
// This is defined in osmesa_context.h
|
||||||
|
_GLFW_OSMESA_CONTEXT_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Window and context structure
|
||||||
|
//
|
||||||
|
struct _GLFWwindow
|
||||||
|
{
|
||||||
|
struct _GLFWwindow* next;
|
||||||
|
|
||||||
|
// Window settings and state
|
||||||
|
GLFWbool resizable;
|
||||||
|
GLFWbool decorated;
|
||||||
|
GLFWbool autoIconify;
|
||||||
|
GLFWbool floating;
|
||||||
|
GLFWbool focusOnShow;
|
||||||
|
GLFWbool shouldClose;
|
||||||
|
void* userPointer;
|
||||||
|
GLFWbool doublebuffer;
|
||||||
|
GLFWvidmode videoMode;
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
_GLFWcursor* cursor;
|
||||||
|
|
||||||
|
int minwidth, minheight;
|
||||||
|
int maxwidth, maxheight;
|
||||||
|
int numer, denom;
|
||||||
|
|
||||||
|
GLFWbool stickyKeys;
|
||||||
|
GLFWbool stickyMouseButtons;
|
||||||
|
GLFWbool lockKeyMods;
|
||||||
|
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;
|
||||||
|
GLFWbool rawMouseMotion;
|
||||||
|
|
||||||
|
_GLFWcontext context;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWwindowposfun pos;
|
||||||
|
GLFWwindowsizefun size;
|
||||||
|
GLFWwindowclosefun close;
|
||||||
|
GLFWwindowrefreshfun refresh;
|
||||||
|
GLFWwindowfocusfun focus;
|
||||||
|
GLFWwindowiconifyfun iconify;
|
||||||
|
GLFWwindowmaximizefun maximize;
|
||||||
|
GLFWframebuffersizefun fbsize;
|
||||||
|
GLFWwindowcontentscalefun scale;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Monitor structure
|
||||||
|
//
|
||||||
|
struct _GLFWmonitor
|
||||||
|
{
|
||||||
|
char name[128];
|
||||||
|
void* userPointer;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cursor structure
|
||||||
|
//
|
||||||
|
struct _GLFWcursor
|
||||||
|
{
|
||||||
|
_GLFWcursor* next;
|
||||||
|
|
||||||
|
// This is defined in the window API's platform.h
|
||||||
|
_GLFW_PLATFORM_CURSOR_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gamepad mapping element structure
|
||||||
|
//
|
||||||
|
struct _GLFWmapelement
|
||||||
|
{
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t index;
|
||||||
|
int8_t axisScale;
|
||||||
|
int8_t axisOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gamepad mapping structure
|
||||||
|
//
|
||||||
|
struct _GLFWmapping
|
||||||
|
{
|
||||||
|
char name[128];
|
||||||
|
char guid[33];
|
||||||
|
_GLFWmapelement buttons[15];
|
||||||
|
_GLFWmapelement axes[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Joystick structure
|
||||||
|
//
|
||||||
|
struct _GLFWjoystick
|
||||||
|
{
|
||||||
|
GLFWbool allocated;
|
||||||
|
GLFWbool connected;
|
||||||
|
float* axes;
|
||||||
|
int axisCount;
|
||||||
|
unsigned char* buttons;
|
||||||
|
int buttonCount;
|
||||||
|
unsigned char* hats;
|
||||||
|
int hatCount;
|
||||||
|
char name[128];
|
||||||
|
void* userPointer;
|
||||||
|
char guid[33];
|
||||||
|
_GLFWmapping* mapping;
|
||||||
|
|
||||||
|
// This is defined in the joystick API's joystick.h
|
||||||
|
_GLFW_PLATFORM_JOYSTICK_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Thread local storage structure
|
||||||
|
//
|
||||||
|
struct _GLFWtls
|
||||||
|
{
|
||||||
|
// This is defined in the platform's thread.h
|
||||||
|
_GLFW_PLATFORM_TLS_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mutex structure
|
||||||
|
//
|
||||||
|
struct _GLFWmutex
|
||||||
|
{
|
||||||
|
// This is defined in the platform's thread.h
|
||||||
|
_GLFW_PLATFORM_MUTEX_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Library global data
|
||||||
|
//
|
||||||
|
struct _GLFWlibrary
|
||||||
|
{
|
||||||
|
GLFWbool initialized;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
_GLFWinitconfig init;
|
||||||
|
_GLFWfbconfig framebuffer;
|
||||||
|
_GLFWwndconfig window;
|
||||||
|
_GLFWctxconfig context;
|
||||||
|
int refreshRate;
|
||||||
|
} hints;
|
||||||
|
|
||||||
|
_GLFWerror* errorListHead;
|
||||||
|
_GLFWcursor* cursorListHead;
|
||||||
|
_GLFWwindow* windowListHead;
|
||||||
|
|
||||||
|
_GLFWmonitor** monitors;
|
||||||
|
int monitorCount;
|
||||||
|
|
||||||
|
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
|
||||||
|
_GLFWmapping* mappings;
|
||||||
|
int mappingCount;
|
||||||
|
|
||||||
|
_GLFWtls errorSlot;
|
||||||
|
_GLFWtls contextSlot;
|
||||||
|
_GLFWmutex errorLock;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint64_t offset;
|
||||||
|
// This is defined in the platform's time.h
|
||||||
|
_GLFW_PLATFORM_LIBRARY_TIMER_STATE;
|
||||||
|
} timer;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
char* extensions[2];
|
||||||
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
|
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||||
|
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||||
|
#endif
|
||||||
|
GLFWbool KHR_surface;
|
||||||
|
#if defined(_GLFW_WIN32)
|
||||||
|
GLFWbool KHR_win32_surface;
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
GLFWbool MVK_macos_surface;
|
||||||
|
GLFWbool EXT_metal_surface;
|
||||||
|
#elif defined(_GLFW_X11)
|
||||||
|
GLFWbool KHR_xlib_surface;
|
||||||
|
GLFWbool KHR_xcb_surface;
|
||||||
|
#elif defined(_GLFW_WAYLAND)
|
||||||
|
GLFWbool KHR_wayland_surface;
|
||||||
|
#endif
|
||||||
|
} vk;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWmonitorfun monitor;
|
||||||
|
GLFWjoystickfun joystick;
|
||||||
|
} callbacks;
|
||||||
|
|
||||||
|
// This is defined in the window API's platform.h
|
||||||
|
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
||||||
|
// This is defined in the context API's context.h
|
||||||
|
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
||||||
|
// This is defined in the platform's joystick.h
|
||||||
|
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||||
|
// This is defined in egl_context.h
|
||||||
|
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
||||||
|
// This is defined in osmesa_context.h
|
||||||
|
_GLFW_OSMESA_LIBRARY_CONTEXT_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global state shared between compilation units of GLFW
|
||||||
|
//
|
||||||
|
extern _GLFWlibrary _glfw;
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformInit(void);
|
||||||
|
void _glfwPlatformTerminate(void);
|
||||||
|
const char* _glfwPlatformGetVersionString(void);
|
||||||
|
|
||||||
|
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
|
||||||
|
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||||
|
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||||
|
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled);
|
||||||
|
GLFWbool _glfwPlatformRawMouseMotionSupported(void);
|
||||||
|
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||||
|
const GLFWimage* image, int xhot, int yhot);
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
|
||||||
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
|
||||||
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetScancodeName(int scancode);
|
||||||
|
int _glfwPlatformGetKeyScancode(int key);
|
||||||
|
|
||||||
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
|
||||||
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||||
|
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||||
|
float* xscale, float* yscale);
|
||||||
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
|
||||||
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||||
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||||
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||||
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||||
|
|
||||||
|
void _glfwPlatformSetClipboardString(const char* string);
|
||||||
|
const char* _glfwPlatformGetClipboardString(void);
|
||||||
|
|
||||||
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
||||||
|
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerValue(void);
|
||||||
|
uint64_t _glfwPlatformGetTimerFrequency(void);
|
||||||
|
|
||||||
|
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
|
||||||
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||||
|
int count, const GLFWimage* images);
|
||||||
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
|
||||||
|
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||||
|
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
|
||||||
|
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
|
||||||
|
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||||
|
int minwidth, int minheight,
|
||||||
|
int maxwidth, int maxheight);
|
||||||
|
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
|
||||||
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
|
||||||
|
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
|
int* left, int* top,
|
||||||
|
int* right, int* bottom);
|
||||||
|
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||||
|
float* xscale, float* yscale);
|
||||||
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformShowWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformHideWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformFocusWindow(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||||
|
int xpos, int ypos, int width, int height,
|
||||||
|
int refreshRate);
|
||||||
|
int _glfwPlatformWindowFocused(_GLFWwindow* window);
|
||||||
|
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
||||||
|
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||||
|
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||||
|
int _glfwPlatformWindowHovered(_GLFWwindow* window);
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
|
||||||
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
||||||
|
|
||||||
|
void _glfwPlatformPollEvents(void);
|
||||||
|
void _glfwPlatformWaitEvents(void);
|
||||||
|
void _glfwPlatformWaitEventsTimeout(double timeout);
|
||||||
|
void _glfwPlatformPostEmptyEvent(void);
|
||||||
|
|
||||||
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
uint32_t queuefamily);
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface);
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
|
||||||
|
void _glfwPlatformDestroyTls(_GLFWtls* tls);
|
||||||
|
void* _glfwPlatformGetTls(_GLFWtls* tls);
|
||||||
|
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
|
||||||
|
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
|
||||||
|
void _glfwPlatformLockMutex(_GLFWmutex* mutex);
|
||||||
|
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW event API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
|
||||||
|
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||||
|
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
|
||||||
|
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
|
||||||
|
void _glfwInputWindowContentScale(_GLFWwindow* window,
|
||||||
|
float xscale, float yscale);
|
||||||
|
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
|
||||||
|
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
|
||||||
|
void _glfwInputWindowDamage(_GLFWwindow* window);
|
||||||
|
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
||||||
|
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
void _glfwInputKey(_GLFWwindow* window,
|
||||||
|
int key, int scancode, int action, int mods);
|
||||||
|
void _glfwInputChar(_GLFWwindow* window,
|
||||||
|
uint32_t codepoint, int mods, GLFWbool plain);
|
||||||
|
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
||||||
|
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||||
|
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||||
|
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
||||||
|
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||||
|
void _glfwInputJoystick(_GLFWjoystick* js, int event);
|
||||||
|
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
||||||
|
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
|
||||||
|
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
||||||
|
|
||||||
|
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
||||||
|
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
void _glfwInputError(int code, const char* format, ...)
|
||||||
|
__attribute__((format(printf, 2, 3)));
|
||||||
|
#else
|
||||||
|
void _glfwInputError(int code, const char* format, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||||
|
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||||
|
const _GLFWfbconfig* alternatives,
|
||||||
|
unsigned int count);
|
||||||
|
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig);
|
||||||
|
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||||
|
|
||||||
|
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
||||||
|
const GLFWvidmode* desired);
|
||||||
|
int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second);
|
||||||
|
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM);
|
||||||
|
void _glfwFreeMonitor(_GLFWmonitor* monitor);
|
||||||
|
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
|
||||||
|
void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
|
||||||
|
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
||||||
|
|
||||||
|
void _glfwInitGamepadMappings(void);
|
||||||
|
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||||
|
const char* guid,
|
||||||
|
int axisCount,
|
||||||
|
int buttonCount,
|
||||||
|
int hatCount);
|
||||||
|
void _glfwFreeJoystick(_GLFWjoystick* js);
|
||||||
|
void _glfwCenterCursorInContentArea(_GLFWwindow* window);
|
||||||
|
|
||||||
|
GLFWbool _glfwInitVulkan(int mode);
|
||||||
|
void _glfwTerminateVulkan(void);
|
||||||
|
const char* _glfwGetVulkanResultString(VkResult result);
|
||||||
|
|
||||||
|
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
||||||
|
char** _glfwParseUriList(char* text, int* count);
|
||||||
|
|
||||||
|
char* _glfw_strdup(const char* source);
|
||||||
|
int _glfw_min(int a, int b);
|
||||||
|
int _glfw_max(int a, int b);
|
||||||
|
float _glfw_fminf(float a, float b);
|
||||||
|
float _glfw_fmaxf(float a, float b);
|
||||||
|
|
433
external/glfw-3.3.8/src/linux_joystick.c
vendored
Normal file
433
external/glfw-3.3.8/src/linux_joystick.c
vendored
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Linux - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef SYN_DROPPED // < v2.6.39 kernel headers
|
||||||
|
// Workaround for CentOS-6, which is supported till 2020-11-30, but still on v2.6.32
|
||||||
|
#define SYN_DROPPED 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Apply an EV_KEY event to the specified joystick
|
||||||
|
//
|
||||||
|
static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
|
||||||
|
{
|
||||||
|
_glfwInputJoystickButton(js,
|
||||||
|
js->linjs.keyMap[code - BTN_MISC],
|
||||||
|
value ? GLFW_PRESS : GLFW_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply an EV_ABS event to the specified joystick
|
||||||
|
//
|
||||||
|
static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
|
||||||
|
{
|
||||||
|
const int index = js->linjs.absMap[code];
|
||||||
|
|
||||||
|
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
|
||||||
|
{
|
||||||
|
static const char stateMap[3][3] =
|
||||||
|
{
|
||||||
|
{ GLFW_HAT_CENTERED, GLFW_HAT_UP, GLFW_HAT_DOWN },
|
||||||
|
{ GLFW_HAT_LEFT, GLFW_HAT_LEFT_UP, GLFW_HAT_LEFT_DOWN },
|
||||||
|
{ GLFW_HAT_RIGHT, GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN },
|
||||||
|
};
|
||||||
|
|
||||||
|
const int hat = (code - ABS_HAT0X) / 2;
|
||||||
|
const int axis = (code - ABS_HAT0X) % 2;
|
||||||
|
int* state = js->linjs.hats[hat];
|
||||||
|
|
||||||
|
// NOTE: Looking at several input drivers, it seems all hat events use
|
||||||
|
// -1 for left / up, 0 for centered and 1 for right / down
|
||||||
|
if (value == 0)
|
||||||
|
state[axis] = 0;
|
||||||
|
else if (value < 0)
|
||||||
|
state[axis] = 1;
|
||||||
|
else if (value > 0)
|
||||||
|
state[axis] = 2;
|
||||||
|
|
||||||
|
_glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const struct input_absinfo* info = &js->linjs.absInfo[code];
|
||||||
|
float normalized = value;
|
||||||
|
|
||||||
|
const int range = info->maximum - info->minimum;
|
||||||
|
if (range)
|
||||||
|
{
|
||||||
|
// Normalize to 0.0 -> 1.0
|
||||||
|
normalized = (normalized - info->minimum) / range;
|
||||||
|
// Normalize to -1.0 -> 1.0
|
||||||
|
normalized = normalized * 2.0f - 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputJoystickAxis(js, index, normalized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll state of absolute axes
|
||||||
|
//
|
||||||
|
static void pollAbsState(_GLFWjoystick* js)
|
||||||
|
{
|
||||||
|
for (int code = 0; code < ABS_CNT; code++)
|
||||||
|
{
|
||||||
|
if (js->linjs.absMap[code] < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct input_absinfo* info = &js->linjs.absInfo[code];
|
||||||
|
|
||||||
|
if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
handleAbsEvent(js, code, info->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
|
||||||
|
|
||||||
|
// Attempt to open the specified joystick device
|
||||||
|
//
|
||||||
|
static GLFWbool openJoystickDevice(const char* path)
|
||||||
|
{
|
||||||
|
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (!_glfw.joysticks[jid].connected)
|
||||||
|
continue;
|
||||||
|
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWjoystickLinux linjs = {0};
|
||||||
|
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||||
|
if (linjs.fd == -1)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||||
|
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||||
|
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||||
|
struct input_id id;
|
||||||
|
|
||||||
|
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||||
|
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||||
|
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||||
|
ioctl(linjs.fd, EVIOCGID, &id) < 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Linux: Failed to query input device: %s",
|
||||||
|
strerror(errno));
|
||||||
|
close(linjs.fd);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure this device supports the events expected of a joystick
|
||||||
|
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
|
||||||
|
{
|
||||||
|
close(linjs.fd);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[256] = "";
|
||||||
|
|
||||||
|
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
||||||
|
strncpy(name, "Unknown", sizeof(name));
|
||||||
|
|
||||||
|
char guid[33] = "";
|
||||||
|
|
||||||
|
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||||
|
if (id.vendor && id.product && id.version)
|
||||||
|
{
|
||||||
|
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
|
||||||
|
id.bustype & 0xff, id.bustype >> 8,
|
||||||
|
id.vendor & 0xff, id.vendor >> 8,
|
||||||
|
id.product & 0xff, id.product >> 8,
|
||||||
|
id.version & 0xff, id.version >> 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||||
|
id.bustype & 0xff, id.bustype >> 8,
|
||||||
|
name[0], name[1], name[2], name[3],
|
||||||
|
name[4], name[5], name[6], name[7],
|
||||||
|
name[8], name[9], name[10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||||
|
|
||||||
|
for (int code = BTN_MISC; code < KEY_CNT; code++)
|
||||||
|
{
|
||||||
|
if (!isBitSet(code, keyBits))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
linjs.keyMap[code - BTN_MISC] = buttonCount;
|
||||||
|
buttonCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int code = 0; code < ABS_CNT; code++)
|
||||||
|
{
|
||||||
|
linjs.absMap[code] = -1;
|
||||||
|
if (!isBitSet(code, absBits))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
|
||||||
|
{
|
||||||
|
linjs.absMap[code] = hatCount;
|
||||||
|
hatCount++;
|
||||||
|
// Skip the Y axis
|
||||||
|
code++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
linjs.absMap[code] = axisCount;
|
||||||
|
axisCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWjoystick* js =
|
||||||
|
_glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||||
|
if (!js)
|
||||||
|
{
|
||||||
|
close(linjs.fd);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
|
||||||
|
memcpy(&js->linjs, &linjs, sizeof(linjs));
|
||||||
|
|
||||||
|
pollAbsState(js);
|
||||||
|
|
||||||
|
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef isBitSet
|
||||||
|
|
||||||
|
// Frees all resources associated with the specified joystick
|
||||||
|
//
|
||||||
|
static void closeJoystick(_GLFWjoystick* js)
|
||||||
|
{
|
||||||
|
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||||
|
close(js->linjs.fd);
|
||||||
|
_glfwFreeJoystick(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lexically compare joysticks by name; used by qsort
|
||||||
|
//
|
||||||
|
static int compareJoysticks(const void* fp, const void* sp)
|
||||||
|
{
|
||||||
|
const _GLFWjoystick* fj = fp;
|
||||||
|
const _GLFWjoystick* sj = sp;
|
||||||
|
return strcmp(fj->linjs.path, sj->linjs.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize joystick interface
|
||||||
|
//
|
||||||
|
GLFWbool _glfwInitJoysticksLinux(void)
|
||||||
|
{
|
||||||
|
const char* dirname = "/dev/input";
|
||||||
|
|
||||||
|
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||||
|
if (_glfw.linjs.inotify > 0)
|
||||||
|
{
|
||||||
|
// HACK: Register for IN_ATTRIB to get notified when udev is done
|
||||||
|
// This works well in practice but the true way is libudev
|
||||||
|
|
||||||
|
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
|
||||||
|
dirname,
|
||||||
|
IN_CREATE | IN_ATTRIB | IN_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue without device connection notifications if inotify fails
|
||||||
|
|
||||||
|
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
DIR* dir = opendir(dirname);
|
||||||
|
if (dir)
|
||||||
|
{
|
||||||
|
struct dirent* entry;
|
||||||
|
|
||||||
|
while ((entry = readdir(dir)))
|
||||||
|
{
|
||||||
|
regmatch_t match;
|
||||||
|
|
||||||
|
if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
|
||||||
|
|
||||||
|
if (openJoystickDevice(path))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue with no joysticks if enumeration fails
|
||||||
|
|
||||||
|
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close all opened joystick handles
|
||||||
|
//
|
||||||
|
void _glfwTerminateJoysticksLinux(void)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||||
|
if (js->connected)
|
||||||
|
closeJoystick(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
regfree(&_glfw.linjs.regex);
|
||||||
|
|
||||||
|
if (_glfw.linjs.inotify > 0)
|
||||||
|
{
|
||||||
|
if (_glfw.linjs.watch > 0)
|
||||||
|
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
|
||||||
|
|
||||||
|
close(_glfw.linjs.inotify);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwDetectJoystickConnectionLinux(void)
|
||||||
|
{
|
||||||
|
if (_glfw.linjs.inotify <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ssize_t offset = 0;
|
||||||
|
char buffer[16384];
|
||||||
|
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
while (size > offset)
|
||||||
|
{
|
||||||
|
regmatch_t match;
|
||||||
|
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
||||||
|
|
||||||
|
offset += sizeof(struct inotify_event) + e->len;
|
||||||
|
|
||||||
|
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
||||||
|
|
||||||
|
if (e->mask & (IN_CREATE | IN_ATTRIB))
|
||||||
|
openJoystickDevice(path);
|
||||||
|
else if (e->mask & IN_DELETE)
|
||||||
|
{
|
||||||
|
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||||
|
{
|
||||||
|
closeJoystick(_glfw.joysticks + jid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
|
{
|
||||||
|
// Read all queued events (non-blocking)
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
struct input_event e;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (read(js->linjs.fd, &e, sizeof(e)) < 0)
|
||||||
|
{
|
||||||
|
// Reset the joystick slot if the device was disconnected
|
||||||
|
if (errno == ENODEV)
|
||||||
|
closeJoystick(js);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.type == EV_SYN)
|
||||||
|
{
|
||||||
|
if (e.code == SYN_DROPPED)
|
||||||
|
_glfw.linjs.dropped = GLFW_TRUE;
|
||||||
|
else if (e.code == SYN_REPORT)
|
||||||
|
{
|
||||||
|
_glfw.linjs.dropped = GLFW_FALSE;
|
||||||
|
pollAbsState(js);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.linjs.dropped)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (e.type == EV_KEY)
|
||||||
|
handleKeyEvent(js, e.code, e.value);
|
||||||
|
else if (e.type == EV_ABS)
|
||||||
|
handleAbsEvent(js, e.code, e.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return js->connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
63
external/glfw-3.3.8/src/linux_joystick.h
vendored
Normal file
63
external/glfw-3.3.8/src/linux_joystick.h
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Linux - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
|
||||||
|
#define GLFW_BUILD_LINUX_MAPPINGS
|
||||||
|
|
||||||
|
// Linux-specific joystick data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWjoystickLinux
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int keyMap[KEY_CNT - BTN_MISC];
|
||||||
|
int absMap[ABS_CNT];
|
||||||
|
struct input_absinfo absInfo[ABS_CNT];
|
||||||
|
int hats[4][2];
|
||||||
|
} _GLFWjoystickLinux;
|
||||||
|
|
||||||
|
// Linux-specific joystick API data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryLinux
|
||||||
|
{
|
||||||
|
int inotify;
|
||||||
|
int watch;
|
||||||
|
regex_t regex;
|
||||||
|
GLFWbool dropped;
|
||||||
|
} _GLFWlibraryLinux;
|
||||||
|
|
||||||
|
|
||||||
|
GLFWbool _glfwInitJoysticksLinux(void);
|
||||||
|
void _glfwTerminateJoysticksLinux(void);
|
||||||
|
void _glfwDetectJoystickConnectionLinux(void);
|
||||||
|
|
1001
external/glfw-3.3.8/src/mappings.h
vendored
Normal file
1001
external/glfw-3.3.8/src/mappings.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
82
external/glfw-3.3.8/src/mappings.h.in
vendored
Normal file
82
external/glfw-3.3.8/src/mappings.h.in
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// As mappings.h.in, this file is used by CMake to produce the mappings.h
|
||||||
|
// header file. If you are adding a GLFW specific gamepad mapping, this is
|
||||||
|
// where to put it.
|
||||||
|
//========================================================================
|
||||||
|
// As mappings.h, this provides all pre-defined gamepad mappings, including
|
||||||
|
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
|
||||||
|
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
|
||||||
|
// This file can be re-generated from mappings.h.in and the upstream
|
||||||
|
// gamecontrollerdb.txt with the 'update_mappings' CMake target.
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
// All gamepad mappings not labeled GLFW are copied from the
|
||||||
|
// SDL_GameControllerDB project under the following license:
|
||||||
|
//
|
||||||
|
// Simple DirectMedia Layer
|
||||||
|
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the
|
||||||
|
// use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
const char* _glfwDefaultMappings[] =
|
||||||
|
{
|
||||||
|
#if defined(GLFW_BUILD_WIN32_MAPPINGS)
|
||||||
|
@GLFW_WIN32_MAPPINGS@
|
||||||
|
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||||
|
#endif // GLFW_BUILD_WIN32_MAPPINGS
|
||||||
|
|
||||||
|
#if defined(GLFW_BUILD_COCOA_MAPPINGS)
|
||||||
|
@GLFW_COCOA_MAPPINGS@
|
||||||
|
#endif // GLFW_BUILD_COCOA_MAPPINGS
|
||||||
|
|
||||||
|
#if defined(GLFW_BUILD_LINUX_MAPPINGS)
|
||||||
|
@GLFW_LINUX_MAPPINGS@
|
||||||
|
#endif // GLFW_BUILD_LINUX_MAPPINGS
|
||||||
|
};
|
||||||
|
|
542
external/glfw-3.3.8/src/monitor.c
vendored
Normal file
542
external/glfw-3.3.8/src/monitor.c
vendored
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Lexically compare video modes, used by qsort
|
||||||
|
//
|
||||||
|
static int compareVideoModes(const void* fp, const void* sp)
|
||||||
|
{
|
||||||
|
const GLFWvidmode* fm = fp;
|
||||||
|
const GLFWvidmode* sm = sp;
|
||||||
|
const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;
|
||||||
|
const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;
|
||||||
|
const int farea = fm->width * fm->height;
|
||||||
|
const int sarea = sm->width * sm->height;
|
||||||
|
|
||||||
|
// First sort on color bits per pixel
|
||||||
|
if (fbpp != sbpp)
|
||||||
|
return fbpp - sbpp;
|
||||||
|
|
||||||
|
// Then sort on screen area
|
||||||
|
if (farea != sarea)
|
||||||
|
return farea - sarea;
|
||||||
|
|
||||||
|
// Then sort on width
|
||||||
|
if (fm->width != sm->width)
|
||||||
|
return fm->width - sm->width;
|
||||||
|
|
||||||
|
// 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 //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Notifies shared code of a monitor connection or disconnection
|
||||||
|
//
|
||||||
|
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
||||||
|
{
|
||||||
|
if (action == GLFW_CONNECTED)
|
||||||
|
{
|
||||||
|
_glfw.monitorCount++;
|
||||||
|
_glfw.monitors =
|
||||||
|
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
|
||||||
|
|
||||||
|
if (placement == _GLFW_INSERT_FIRST)
|
||||||
|
{
|
||||||
|
memmove(_glfw.monitors + 1,
|
||||||
|
_glfw.monitors,
|
||||||
|
((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
||||||
|
_glfw.monitors[0] = monitor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_glfw.monitors[_glfw.monitorCount - 1] = monitor;
|
||||||
|
}
|
||||||
|
else if (action == GLFW_DISCONNECTED)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
_GLFWwindow* window;
|
||||||
|
|
||||||
|
for (window = _glfw.windowListHead; window; window = window->next)
|
||||||
|
{
|
||||||
|
if (window->monitor == monitor)
|
||||||
|
{
|
||||||
|
int width, height, xoff, yoff;
|
||||||
|
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||||
|
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
|
||||||
|
_glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
|
||||||
|
_glfwPlatformSetWindowPos(window, xoff, yoff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
{
|
||||||
|
if (_glfw.monitors[i] == monitor)
|
||||||
|
{
|
||||||
|
_glfw.monitorCount--;
|
||||||
|
memmove(_glfw.monitors + i,
|
||||||
|
_glfw.monitors + i + 1,
|
||||||
|
((size_t) _glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.callbacks.monitor)
|
||||||
|
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
|
||||||
|
|
||||||
|
if (action == GLFW_DISCONNECTED)
|
||||||
|
_glfwFreeMonitor(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifies shared code that a full screen window has acquired or released
|
||||||
|
// a monitor
|
||||||
|
//
|
||||||
|
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
|
||||||
|
{
|
||||||
|
monitor->window = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Allocates and returns a monitor object with the specified name and dimensions
|
||||||
|
//
|
||||||
|
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor));
|
||||||
|
monitor->widthMM = widthMM;
|
||||||
|
monitor->heightMM = heightMM;
|
||||||
|
|
||||||
|
strncpy(monitor->name, name, sizeof(monitor->name) - 1);
|
||||||
|
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frees a monitor object and any data associated with it
|
||||||
|
//
|
||||||
|
void _glfwFreeMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
if (monitor == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_glfwPlatformFreeMonitor(monitor);
|
||||||
|
|
||||||
|
_glfwFreeGammaArrays(&monitor->originalRamp);
|
||||||
|
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||||
|
|
||||||
|
free(monitor->modes);
|
||||||
|
free(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocates red, green and blue value arrays of the specified size
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frees the red, green and blue value arrays and clears the struct
|
||||||
|
//
|
||||||
|
void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
free(ramp->red);
|
||||||
|
free(ramp->green);
|
||||||
|
free(ramp->blue);
|
||||||
|
|
||||||
|
memset(ramp, 0, sizeof(GLFWgammaramp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chooses the video mode most closely matching the desired one
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performs lexical comparison between two @ref GLFWvidmode structures
|
||||||
|
//
|
||||||
|
int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm)
|
||||||
|
{
|
||||||
|
return compareVideoModes(fm, sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splits a color depth into red, green and blue bit depths
|
||||||
|
//
|
||||||
|
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 glfwGetMonitorWorkarea(GLFWmonitor* handle,
|
||||||
|
int* xpos, int* ypos,
|
||||||
|
int* width, int* height)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = 0;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = 0;
|
||||||
|
if (width)
|
||||||
|
*width = 0;
|
||||||
|
if (height)
|
||||||
|
*height = 0;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
_glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
if (widthMM)
|
||||||
|
*widthMM = 0;
|
||||||
|
if (heightMM)
|
||||||
|
*heightMM = 0;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
if (widthMM)
|
||||||
|
*widthMM = monitor->widthMM;
|
||||||
|
if (heightMM)
|
||||||
|
*heightMM = monitor->heightMM;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
if (xscale)
|
||||||
|
*xscale = 0.f;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = 0.f;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
_glfwPlatformGetMonitorContentScale(monitor, xscale, yscale);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return monitor->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
monitor->userPointer = pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return monitor->userPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
unsigned short* values;
|
||||||
|
GLFWgammaramp ramp;
|
||||||
|
const GLFWgammaramp* original;
|
||||||
|
assert(handle != NULL);
|
||||||
|
assert(gamma > 0.f);
|
||||||
|
assert(gamma <= FLT_MAX);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
original = glfwGetGammaRamp(handle);
|
||||||
|
if (!original)
|
||||||
|
return;
|
||||||
|
|
||||||
|
values = calloc(original->size, sizeof(unsigned short));
|
||||||
|
|
||||||
|
for (i = 0; i < original->size; i++)
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
|
||||||
|
// Calculate intensity
|
||||||
|
value = i / (float) (original->size - 1);
|
||||||
|
// Apply gamma curve
|
||||||
|
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||||
|
// Clamp to value range
|
||||||
|
value = _glfw_fminf(value, 65535.f);
|
||||||
|
|
||||||
|
values[i] = (unsigned short) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ramp.red = values;
|
||||||
|
ramp.green = values;
|
||||||
|
ramp.blue = values;
|
||||||
|
ramp.size = original->size;
|
||||||
|
|
||||||
|
glfwSetGammaRamp(handle, &ramp);
|
||||||
|
free(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||||
|
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &monitor->currentRamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
assert(monitor != NULL);
|
||||||
|
assert(ramp != NULL);
|
||||||
|
assert(ramp->size > 0);
|
||||||
|
assert(ramp->red != NULL);
|
||||||
|
assert(ramp->green != NULL);
|
||||||
|
assert(ramp->blue != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
if (ramp->size <= 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Invalid gamma ramp size %i",
|
||||||
|
ramp->size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!monitor->originalRamp.size)
|
||||||
|
{
|
||||||
|
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetGammaRamp(monitor, ramp);
|
||||||
|
}
|
||||||
|
|
66
external/glfw-3.3.8/src/nsgl_context.h
vendored
Normal file
66
external/glfw-3.3.8/src/nsgl_context.h
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 macOS - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
// NOTE: Many Cocoa enum values have been renamed and we need to build across
|
||||||
|
// SDK versions where one is unavailable or deprecated.
|
||||||
|
// We use the newer names in code and replace them with the older names if
|
||||||
|
// the base SDK does not provide the newer names.
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
|
||||||
|
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
||||||
|
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
|
|
||||||
|
// NSGL-specific per-context data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcontextNSGL
|
||||||
|
{
|
||||||
|
id pixelFormat;
|
||||||
|
id object;
|
||||||
|
} _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);
|
||||||
|
|
376
external/glfw-3.3.8/src/nsgl_context.m
vendored
Normal file
376
external/glfw-3.3.8/src/nsgl_context.m
vendored
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 macOS - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
[window->context.nsgl.object makeCurrentContext];
|
||||||
|
else
|
||||||
|
[NSOpenGLContext clearCurrentContext];
|
||||||
|
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapBuffersNSGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
||||||
|
// windows with a non-visible occlusion state
|
||||||
|
if (window->ns.occluded)
|
||||||
|
{
|
||||||
|
int interval = 0;
|
||||||
|
[window->context.nsgl.object getValues:&interval
|
||||||
|
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
|
|
||||||
|
if (interval > 0)
|
||||||
|
{
|
||||||
|
const double framerate = 60.0;
|
||||||
|
const uint64_t frequency = _glfwPlatformGetTimerFrequency();
|
||||||
|
const uint64_t value = _glfwPlatformGetTimerValue();
|
||||||
|
|
||||||
|
const double elapsed = value / (double) frequency;
|
||||||
|
const double period = 1.0 / framerate;
|
||||||
|
const double delay = period - fmod(elapsed, period);
|
||||||
|
|
||||||
|
usleep(floorl(delay * 1e6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[window->context.nsgl.object flushBuffer];
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapIntervalNSGL(int interval)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
[window->context.nsgl.object setValues:&interval
|
||||||
|
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyContextNSGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
|
||||||
|
[window->context.nsgl.pixelFormat release];
|
||||||
|
window->context.nsgl.pixelFormat = nil;
|
||||||
|
|
||||||
|
[window->context.nsgl.object release];
|
||||||
|
window->context.nsgl.object = nil;
|
||||||
|
|
||||||
|
} // autoreleasepool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize OpenGL support
|
||||||
|
//
|
||||||
|
GLFWbool _glfwInitNSGL(void)
|
||||||
|
{
|
||||||
|
if (_glfw.nsgl.framework)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
_glfw.nsgl.framework =
|
||||||
|
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
||||||
|
if (_glfw.nsgl.framework == NULL)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"NSGL: Failed to locate OpenGL framework");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate OpenGL support
|
||||||
|
//
|
||||||
|
void _glfwTerminateNSGL(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the OpenGL context
|
||||||
|
//
|
||||||
|
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"NSGL: OpenGL ES is not available on macOS");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->major > 2)
|
||||||
|
{
|
||||||
|
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context robustness modes (GL_KHR_robustness) are not yet supported by
|
||||||
|
// macOS but are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
|
// Context release behaviors (GL_KHR_context_flush_control) are not yet
|
||||||
|
// supported by macOS but are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
|
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
|
||||||
|
// a hard constraint, so ignore and continue
|
||||||
|
|
||||||
|
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
||||||
|
// are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
|
#define addAttrib(a) \
|
||||||
|
{ \
|
||||||
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
|
attribs[index++] = a; \
|
||||||
|
}
|
||||||
|
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
|
||||||
|
|
||||||
|
NSOpenGLPixelFormatAttribute attribs[40];
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
addAttrib(NSOpenGLPFAAccelerated);
|
||||||
|
addAttrib(NSOpenGLPFAClosestPolicy);
|
||||||
|
|
||||||
|
if (ctxconfig->nsgl.offline)
|
||||||
|
{
|
||||||
|
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
|
||||||
|
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
|
||||||
|
// Info.plist for unbundled applications
|
||||||
|
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
||||||
|
// a straightforward wrapper of its CGL counterpart
|
||||||
|
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||||
|
if (ctxconfig->major >= 4)
|
||||||
|
{
|
||||||
|
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||||
|
if (ctxconfig->major >= 3)
|
||||||
|
{
|
||||||
|
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->major <= 2)
|
||||||
|
{
|
||||||
|
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
||||||
|
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
||||||
|
|
||||||
|
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
||||||
|
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
||||||
|
fbconfig->accumBlueBits != GLFW_DONT_CARE &&
|
||||||
|
fbconfig->accumAlphaBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
const int accumBits = fbconfig->accumRedBits +
|
||||||
|
fbconfig->accumGreenBits +
|
||||||
|
fbconfig->accumBlueBits +
|
||||||
|
fbconfig->accumAlphaBits;
|
||||||
|
|
||||||
|
setAttrib(NSOpenGLPFAAccumSize, accumBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbconfig->redBits != GLFW_DONT_CARE &&
|
||||||
|
fbconfig->greenBits != GLFW_DONT_CARE &&
|
||||||
|
fbconfig->blueBits != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
int colorBits = fbconfig->redBits +
|
||||||
|
fbconfig->greenBits +
|
||||||
|
fbconfig->blueBits;
|
||||||
|
|
||||||
|
// macOS needs non-zero color size, so set reasonable values
|
||||||
|
if (colorBits == 0)
|
||||||
|
colorBits = 24;
|
||||||
|
else if (colorBits < 15)
|
||||||
|
colorBits = 15;
|
||||||
|
|
||||||
|
setAttrib(NSOpenGLPFAColorSize, colorBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
||||||
|
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
||||||
|
|
||||||
|
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
||||||
|
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
||||||
|
|
||||||
|
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
||||||
|
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
||||||
|
|
||||||
|
if (fbconfig->stereo)
|
||||||
|
{
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"NSGL: Stereo rendering is deprecated");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
#else
|
||||||
|
addAttrib(NSOpenGLPFAStereo);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbconfig->doublebuffer)
|
||||||
|
addAttrib(NSOpenGLPFADoubleBuffer);
|
||||||
|
|
||||||
|
if (fbconfig->samples != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
if (fbconfig->samples == 0)
|
||||||
|
{
|
||||||
|
setAttrib(NSOpenGLPFASampleBuffers, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setAttrib(NSOpenGLPFASampleBuffers, 1);
|
||||||
|
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
||||||
|
// framebuffer, so there's no need (and no way) to request it
|
||||||
|
|
||||||
|
addAttrib(0);
|
||||||
|
|
||||||
|
#undef addAttrib
|
||||||
|
#undef setAttrib
|
||||||
|
|
||||||
|
window->context.nsgl.pixelFormat =
|
||||||
|
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||||
|
if (window->context.nsgl.pixelFormat == nil)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"NSGL: Failed to find a suitable pixel format");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSOpenGLContext* share = nil;
|
||||||
|
|
||||||
|
if (ctxconfig->share)
|
||||||
|
share = ctxconfig->share->context.nsgl.object;
|
||||||
|
|
||||||
|
window->context.nsgl.object =
|
||||||
|
[[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
|
||||||
|
shareContext:share];
|
||||||
|
if (window->context.nsgl.object == nil)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"NSGL: Failed to create OpenGL context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbconfig->transparent)
|
||||||
|
{
|
||||||
|
GLint opaque = 0;
|
||||||
|
[window->context.nsgl.object setValues:&opaque
|
||||||
|
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
[window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina];
|
||||||
|
|
||||||
|
[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.source != GLFW_NATIVE_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window->context.nsgl.object;
|
||||||
|
}
|
||||||
|
|
52
external/glfw-3.3.8/src/null_init.c
vendored
Normal file
52
external/glfw-3.3.8/src/null_init.c
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016 Google Inc.
|
||||||
|
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformInit(void)
|
||||||
|
{
|
||||||
|
_glfwInitTimerPOSIX();
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformTerminate(void)
|
||||||
|
{
|
||||||
|
_glfwTerminateOSMesa();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
|
{
|
||||||
|
return _GLFW_VERSION_NUMBER " null OSMesa";
|
||||||
|
}
|
||||||
|
|
44
external/glfw-3.3.8/src/null_joystick.c
vendored
Normal file
44
external/glfw-3.3.8/src/null_joystick.c
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
31
external/glfw-3.3.8/src/null_joystick.h
vendored
Normal file
31
external/glfw-3.3.8/src/null_joystick.h
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_JOYSTICK_STATE struct { int dummyJoystick; }
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; }
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
||||||
|
|
77
external/glfw-3.3.8/src/null_monitor.c
vendored
Normal file
77
external/glfw-3.3.8/src/null_monitor.c
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016 Google Inc.
|
||||||
|
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
if (xscale)
|
||||||
|
*xscale = 1.f;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||||
|
int* xpos, int* ypos,
|
||||||
|
int* width, int* height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
62
external/glfw-3.3.8/src/null_platform.h
vendored
Normal file
62
external/glfw-3.3.8/src/null_platform.h
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016 Google Inc.
|
||||||
|
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE struct { int dummyMonitor; }
|
||||||
|
#define _GLFW_PLATFORM_CURSOR_STATE struct { int dummyCursor; }
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE struct { int dummyLibraryWindow; }
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
|
||||||
|
#define _GLFW_EGL_CONTEXT_STATE struct { int dummyEGLContext; }
|
||||||
|
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE struct { int dummyEGLLibraryContext; }
|
||||||
|
|
||||||
|
#include "osmesa_context.h"
|
||||||
|
#include "posix_time.h"
|
||||||
|
#include "posix_thread.h"
|
||||||
|
#include "null_joystick.h"
|
||||||
|
|
||||||
|
#if defined(_GLFW_WIN32)
|
||||||
|
#define _glfw_dlopen(name) LoadLibraryA(name)
|
||||||
|
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||||
|
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||||
|
#else
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Null-specific per-window data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWwindowNull
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} _GLFWwindowNull;
|
||||||
|
|
335
external/glfw-3.3.8/src/null_window.c
vendored
Normal file
335
external/glfw-3.3.8/src/null_window.c
vendored
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016 Google Inc.
|
||||||
|
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int createNativeWindow(_GLFWwindow* window,
|
||||||
|
const _GLFWwndconfig* wndconfig)
|
||||||
|
{
|
||||||
|
window->null.width = wndconfig->width;
|
||||||
|
window->null.height = wndconfig->height;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
if (!createNativeWindow(window, wndconfig))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API ||
|
||||||
|
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||||
|
{
|
||||||
|
if (!_glfwInitOSMesa())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->context.destroy)
|
||||||
|
window->context.destroy(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count,
|
||||||
|
const GLFWimage* images)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||||
|
_GLFWmonitor* monitor,
|
||||||
|
int xpos, int ypos,
|
||||||
|
int width, int height,
|
||||||
|
int refreshRate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||||
|
{
|
||||||
|
if (width)
|
||||||
|
*width = window->null.width;
|
||||||
|
if (height)
|
||||||
|
*height = window->null.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
window->null.width = width;
|
||||||
|
window->null.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||||
|
int minwidth, int minheight,
|
||||||
|
int maxwidth, int maxheight)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
||||||
|
{
|
||||||
|
if (width)
|
||||||
|
*width = window->null.width;
|
||||||
|
if (height)
|
||||||
|
*height = window->null.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
|
int* left, int* top,
|
||||||
|
int* right, int* bottom)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
if (xscale)
|
||||||
|
*xscale = 1.f;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformRawMouseMotionSupported(void)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformPollEvents(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformWaitEvents(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformPostEmptyEvent(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||||
|
const GLFWimage* image,
|
||||||
|
int xhot, int yhot)
|
||||||
|
{
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
|
{
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetClipboardString(const char* string)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetClipboardString(void)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetKeyScancode(int key)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
uint32_t queuefamily)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||||
|
_GLFWwindow* window,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
// This seems like the most appropriate error to return here
|
||||||
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
|
}
|
||||||
|
|
386
external/glfw-3.3.8/src/osmesa_context.c
vendored
Normal file
386
external/glfw-3.3.8/src/osmesa_context.c
vendored
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 OSMesa - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016 Google Inc.
|
||||||
|
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
_glfwPlatformGetFramebufferSize(window, &width, &height);
|
||||||
|
|
||||||
|
// Check to see if we need to allocate a new buffer
|
||||||
|
if ((window->context.osmesa.buffer == NULL) ||
|
||||||
|
(width != window->context.osmesa.width) ||
|
||||||
|
(height != window->context.osmesa.height))
|
||||||
|
{
|
||||||
|
free(window->context.osmesa.buffer);
|
||||||
|
|
||||||
|
// Allocate the new buffer (width * height * 8-bit RGBA)
|
||||||
|
window->context.osmesa.buffer = calloc(4, (size_t) width * height);
|
||||||
|
window->context.osmesa.width = width;
|
||||||
|
window->context.osmesa.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
|
||||||
|
window->context.osmesa.buffer,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
width, height))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"OSMesa: Failed to make context current");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWglproc getProcAddressOSMesa(const char* procname)
|
||||||
|
{
|
||||||
|
return (GLFWglproc) OSMesaGetProcAddress(procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyContextOSMesa(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->context.osmesa.handle)
|
||||||
|
{
|
||||||
|
OSMesaDestroyContext(window->context.osmesa.handle);
|
||||||
|
window->context.osmesa.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.osmesa.buffer)
|
||||||
|
{
|
||||||
|
free(window->context.osmesa.buffer);
|
||||||
|
window->context.osmesa.width = 0;
|
||||||
|
window->context.osmesa.height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapBuffersOSMesa(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
// No double buffering on OSMesa
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapIntervalOSMesa(int interval)
|
||||||
|
{
|
||||||
|
// No swap interval on OSMesa
|
||||||
|
}
|
||||||
|
|
||||||
|
static int extensionSupportedOSMesa(const char* extension)
|
||||||
|
{
|
||||||
|
// OSMesa does not have extensions
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwInitOSMesa(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char* sonames[] =
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_OSMESA_LIBRARY)
|
||||||
|
_GLFW_OSMESA_LIBRARY,
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
"libOSMesa.dll",
|
||||||
|
"OSMesa.dll",
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
"libOSMesa.8.dylib",
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
"libOSMesa-8.so",
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
"libOSMesa.so",
|
||||||
|
#else
|
||||||
|
"libOSMesa.so.8",
|
||||||
|
"libOSMesa.so.6",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_glfw.osmesa.handle)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
for (i = 0; sonames[i]; i++)
|
||||||
|
{
|
||||||
|
_glfw.osmesa.handle = _glfw_dlopen(sonames[i]);
|
||||||
|
if (_glfw.osmesa.handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.osmesa.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
|
||||||
|
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
||||||
|
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
|
||||||
|
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
|
||||||
|
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
||||||
|
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
||||||
|
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
|
||||||
|
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
|
||||||
|
|
||||||
|
if (!_glfw.osmesa.CreateContextExt ||
|
||||||
|
!_glfw.osmesa.DestroyContext ||
|
||||||
|
!_glfw.osmesa.MakeCurrent ||
|
||||||
|
!_glfw.osmesa.GetColorBuffer ||
|
||||||
|
!_glfw.osmesa.GetDepthBuffer ||
|
||||||
|
!_glfw.osmesa.GetProcAddress)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"OSMesa: Failed to load required entry points");
|
||||||
|
|
||||||
|
_glfwTerminateOSMesa();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateOSMesa(void)
|
||||||
|
{
|
||||||
|
if (_glfw.osmesa.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.osmesa.handle);
|
||||||
|
_glfw.osmesa.handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define setAttrib(a, v) \
|
||||||
|
{ \
|
||||||
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
|
attribs[index++] = a; \
|
||||||
|
attribs[index++] = v; \
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
OSMesaContext share = NULL;
|
||||||
|
const int accumBits = fbconfig->accumRedBits +
|
||||||
|
fbconfig->accumGreenBits +
|
||||||
|
fbconfig->accumBlueBits +
|
||||||
|
fbconfig->accumAlphaBits;
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"OSMesa: OpenGL ES is not available on OSMesa");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->share)
|
||||||
|
share = ctxconfig->share->context.osmesa.handle;
|
||||||
|
|
||||||
|
if (OSMesaCreateContextAttribs)
|
||||||
|
{
|
||||||
|
int index = 0, attribs[40];
|
||||||
|
|
||||||
|
setAttrib(OSMESA_FORMAT, OSMESA_RGBA);
|
||||||
|
setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits);
|
||||||
|
setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
|
||||||
|
setAttrib(OSMESA_ACCUM_BITS, accumBits);
|
||||||
|
|
||||||
|
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
{
|
||||||
|
setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
|
{
|
||||||
|
setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
|
{
|
||||||
|
setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
|
||||||
|
setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"OSMesa: Forward-compatible contexts not supported");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAttrib(0, 0);
|
||||||
|
|
||||||
|
window->context.osmesa.handle =
|
||||||
|
OSMesaCreateContextAttribs(attribs, share);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ctxconfig->profile)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"OSMesa: OpenGL profiles unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.osmesa.handle =
|
||||||
|
OSMesaCreateContextExt(OSMESA_RGBA,
|
||||||
|
fbconfig->depthBits,
|
||||||
|
fbconfig->stencilBits,
|
||||||
|
accumBits,
|
||||||
|
share);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.osmesa.handle == NULL)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"OSMesa: Failed to create context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.makeCurrent = makeContextCurrentOSMesa;
|
||||||
|
window->context.swapBuffers = swapBuffersOSMesa;
|
||||||
|
window->context.swapInterval = swapIntervalOSMesa;
|
||||||
|
window->context.extensionSupported = extensionSupportedOSMesa;
|
||||||
|
window->context.getProcAddress = getProcAddressOSMesa;
|
||||||
|
window->context.destroy = destroyContextOSMesa;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef setAttrib
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW native API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||||
|
int* height, int* format, void** buffer)
|
||||||
|
{
|
||||||
|
void* mesaBuffer;
|
||||||
|
GLint mesaWidth, mesaHeight, mesaFormat;
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
|
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
|
||||||
|
&mesaWidth, &mesaHeight,
|
||||||
|
&mesaFormat, &mesaBuffer))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"OSMesa: Failed to retrieve color buffer");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width)
|
||||||
|
*width = mesaWidth;
|
||||||
|
if (height)
|
||||||
|
*height = mesaHeight;
|
||||||
|
if (format)
|
||||||
|
*format = mesaFormat;
|
||||||
|
if (buffer)
|
||||||
|
*buffer = mesaBuffer;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||||
|
int* width, int* height,
|
||||||
|
int* bytesPerValue,
|
||||||
|
void** buffer)
|
||||||
|
{
|
||||||
|
void* mesaBuffer;
|
||||||
|
GLint mesaWidth, mesaHeight, mesaBytes;
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
|
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
|
||||||
|
&mesaWidth, &mesaHeight,
|
||||||
|
&mesaBytes, &mesaBuffer))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"OSMesa: Failed to retrieve depth buffer");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width)
|
||||||
|
*width = mesaWidth;
|
||||||
|
if (height)
|
||||||
|
*height = mesaHeight;
|
||||||
|
if (bytesPerValue)
|
||||||
|
*bytesPerValue = mesaBytes;
|
||||||
|
if (buffer)
|
||||||
|
*buffer = mesaBuffer;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window->context.osmesa.handle;
|
||||||
|
}
|
||||||
|
|
92
external/glfw-3.3.8/src/osmesa_context.h
vendored
Normal file
92
external/glfw-3.3.8/src/osmesa_context.h
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 OSMesa - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2016 Google Inc.
|
||||||
|
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define OSMESA_RGBA 0x1908
|
||||||
|
#define OSMESA_FORMAT 0x22
|
||||||
|
#define OSMESA_DEPTH_BITS 0x30
|
||||||
|
#define OSMESA_STENCIL_BITS 0x31
|
||||||
|
#define OSMESA_ACCUM_BITS 0x32
|
||||||
|
#define OSMESA_PROFILE 0x33
|
||||||
|
#define OSMESA_CORE_PROFILE 0x34
|
||||||
|
#define OSMESA_COMPAT_PROFILE 0x35
|
||||||
|
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
|
||||||
|
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
|
||||||
|
|
||||||
|
typedef void* OSMesaContext;
|
||||||
|
typedef void (*OSMESAproc)(void);
|
||||||
|
|
||||||
|
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext);
|
||||||
|
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext);
|
||||||
|
typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext);
|
||||||
|
typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int);
|
||||||
|
typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**);
|
||||||
|
typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**);
|
||||||
|
typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
|
||||||
|
#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt
|
||||||
|
#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs
|
||||||
|
#define OSMesaDestroyContext _glfw.osmesa.DestroyContext
|
||||||
|
#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent
|
||||||
|
#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer
|
||||||
|
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
|
||||||
|
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
|
||||||
|
|
||||||
|
#define _GLFW_OSMESA_CONTEXT_STATE _GLFWcontextOSMesa osmesa
|
||||||
|
#define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
|
||||||
|
|
||||||
|
|
||||||
|
// OSMesa-specific per-context data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcontextOSMesa
|
||||||
|
{
|
||||||
|
OSMesaContext handle;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
void* buffer;
|
||||||
|
} _GLFWcontextOSMesa;
|
||||||
|
|
||||||
|
// OSMesa-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryOSMesa
|
||||||
|
{
|
||||||
|
void* handle;
|
||||||
|
|
||||||
|
PFN_OSMesaCreateContextExt CreateContextExt;
|
||||||
|
PFN_OSMesaCreateContextAttribs CreateContextAttribs;
|
||||||
|
PFN_OSMesaDestroyContext DestroyContext;
|
||||||
|
PFN_OSMesaMakeCurrent MakeCurrent;
|
||||||
|
PFN_OSMesaGetColorBuffer GetColorBuffer;
|
||||||
|
PFN_OSMesaGetDepthBuffer GetDepthBuffer;
|
||||||
|
PFN_OSMesaGetProcAddress GetProcAddress;
|
||||||
|
} _GLFWlibraryOSMesa;
|
||||||
|
|
||||||
|
|
||||||
|
GLFWbool _glfwInitOSMesa(void);
|
||||||
|
void _glfwTerminateOSMesa(void);
|
||||||
|
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
105
external/glfw-3.3.8/src/posix_thread.c
vendored
Normal file
105
external/glfw-3.3.8/src/posix_thread.c
vendored
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 POSIX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||||
|
{
|
||||||
|
assert(tls->posix.allocated == GLFW_FALSE);
|
||||||
|
|
||||||
|
if (pthread_key_create(&tls->posix.key, NULL) != 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"POSIX: Failed to create context TLS");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tls->posix.allocated = GLFW_TRUE;
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||||
|
{
|
||||||
|
if (tls->posix.allocated)
|
||||||
|
pthread_key_delete(tls->posix.key);
|
||||||
|
memset(tls, 0, sizeof(_GLFWtls));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
||||||
|
{
|
||||||
|
assert(tls->posix.allocated == GLFW_TRUE);
|
||||||
|
return pthread_getspecific(tls->posix.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
||||||
|
{
|
||||||
|
assert(tls->posix.allocated == GLFW_TRUE);
|
||||||
|
pthread_setspecific(tls->posix.key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
assert(mutex->posix.allocated == GLFW_FALSE);
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutex->posix.allocated = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
if (mutex->posix.allocated)
|
||||||
|
pthread_mutex_destroy(&mutex->posix.handle);
|
||||||
|
memset(mutex, 0, sizeof(_GLFWmutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||||
|
pthread_mutex_lock(&mutex->posix.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||||
|
pthread_mutex_unlock(&mutex->posix.handle);
|
||||||
|
}
|
||||||
|
|
49
external/glfw-3.3.8/src/posix_thread.h
vendored
Normal file
49
external/glfw-3.3.8/src/posix_thread.h
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 POSIX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix
|
||||||
|
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix
|
||||||
|
|
||||||
|
|
||||||
|
// POSIX-specific thread local storage data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWtlsPOSIX
|
||||||
|
{
|
||||||
|
GLFWbool allocated;
|
||||||
|
pthread_key_t key;
|
||||||
|
} _GLFWtlsPOSIX;
|
||||||
|
|
||||||
|
// POSIX-specific mutex data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmutexPOSIX
|
||||||
|
{
|
||||||
|
GLFWbool allocated;
|
||||||
|
pthread_mutex_t handle;
|
||||||
|
} _GLFWmutexPOSIX;
|
||||||
|
|
87
external/glfw-3.3.8/src/posix_time.c
vendored
Normal file
87
external/glfw-3.3.8/src/posix_time.c
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 POSIX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialise timer
|
||||||
|
//
|
||||||
|
void _glfwInitTimerPOSIX(void)
|
||||||
|
{
|
||||||
|
#if defined(CLOCK_MONOTONIC)
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||||
|
{
|
||||||
|
_glfw.timer.posix.monotonic = GLFW_TRUE;
|
||||||
|
_glfw.timer.posix.frequency = 1000000000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
_glfw.timer.posix.monotonic = GLFW_FALSE;
|
||||||
|
_glfw.timer.posix.frequency = 1000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerValue(void)
|
||||||
|
{
|
||||||
|
#if defined(CLOCK_MONOTONIC)
|
||||||
|
if (_glfw.timer.posix.monotonic)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||||
|
{
|
||||||
|
return _glfw.timer.posix.frequency;
|
||||||
|
}
|
||||||
|
|
43
external/glfw-3.3.8/src/posix_time.h
vendored
Normal file
43
external/glfw-3.3.8/src/posix_time.h
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 POSIX - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
// POSIX-specific global timer data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWtimerPOSIX
|
||||||
|
{
|
||||||
|
GLFWbool monotonic;
|
||||||
|
uint64_t frequency;
|
||||||
|
} _GLFWtimerPOSIX;
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwInitTimerPOSIX(void);
|
||||||
|
|
334
external/glfw-3.3.8/src/vulkan.c
vendored
Normal file
334
external/glfw-3.3.8/src/vulkan.c
vendored
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define _GLFW_FIND_LOADER 1
|
||||||
|
#define _GLFW_REQUIRE_LOADER 2
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwInitVulkan(int mode)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
VkExtensionProperties* ep;
|
||||||
|
uint32_t i, count;
|
||||||
|
|
||||||
|
if (_glfw.vk.available)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
|
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||||
|
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
|
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
|
||||||
|
if (!_glfw.vk.handle)
|
||||||
|
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
|
||||||
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.so");
|
||||||
|
#else
|
||||||
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
||||||
|
#endif
|
||||||
|
if (!_glfw.vk.handle)
|
||||||
|
{
|
||||||
|
if (mode == _GLFW_REQUIRE_LOADER)
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
||||||
|
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||||
|
if (!_glfw.vk.GetInstanceProcAddr)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||||
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||||
|
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
|
||||||
|
if (!_glfw.vk.EnumerateInstanceExtensionProperties)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||||
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
#endif // _GLFW_VULKAN_STATIC
|
||||||
|
|
||||||
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
// NOTE: This happens on systems with a loader but without any Vulkan ICD
|
||||||
|
if (mode == _GLFW_REQUIRE_LOADER)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Failed to query instance extension count: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||||
|
|
||||||
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Failed to query instance extensions: %s",
|
||||||
|
_glfwGetVulkanResultString(err));
|
||||||
|
|
||||||
|
free(ep);
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
|
||||||
|
_glfw.vk.KHR_surface = GLFW_TRUE;
|
||||||
|
#if defined(_GLFW_WIN32)
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
|
||||||
|
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
|
||||||
|
#elif defined(_GLFW_COCOA)
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
||||||
|
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
|
||||||
|
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
|
||||||
|
#elif defined(_GLFW_X11)
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
||||||
|
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
|
||||||
|
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
|
||||||
|
#elif defined(_GLFW_WAYLAND)
|
||||||
|
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
||||||
|
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ep);
|
||||||
|
|
||||||
|
_glfw.vk.available = GLFW_TRUE;
|
||||||
|
|
||||||
|
_glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateVulkan(void)
|
||||||
|
{
|
||||||
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
|
if (_glfw.vk.handle)
|
||||||
|
_glfw_dlclose(_glfw.vk.handle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwGetVulkanResultString(VkResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case VK_SUCCESS:
|
||||||
|
return "Success";
|
||||||
|
case VK_NOT_READY:
|
||||||
|
return "A fence or query has not yet completed";
|
||||||
|
case VK_TIMEOUT:
|
||||||
|
return "A wait operation has not completed in the specified time";
|
||||||
|
case VK_EVENT_SET:
|
||||||
|
return "An event is signaled";
|
||||||
|
case VK_EVENT_RESET:
|
||||||
|
return "An event is unsignaled";
|
||||||
|
case VK_INCOMPLETE:
|
||||||
|
return "A return array was too small for the result";
|
||||||
|
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||||
|
return "A host memory allocation has failed";
|
||||||
|
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||||
|
return "A device memory allocation has failed";
|
||||||
|
case VK_ERROR_INITIALIZATION_FAILED:
|
||||||
|
return "Initialization of an object could not be completed for implementation-specific reasons";
|
||||||
|
case VK_ERROR_DEVICE_LOST:
|
||||||
|
return "The logical or physical device has been lost";
|
||||||
|
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||||
|
return "Mapping of a memory object has failed";
|
||||||
|
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||||
|
return "A requested layer is not present or could not be loaded";
|
||||||
|
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||||
|
return "A requested extension is not supported";
|
||||||
|
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||||
|
return "A requested feature is not supported";
|
||||||
|
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||||
|
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
|
||||||
|
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||||
|
return "Too many objects of the type have already been created";
|
||||||
|
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||||
|
return "A requested format is not supported on this device";
|
||||||
|
case VK_ERROR_SURFACE_LOST_KHR:
|
||||||
|
return "A surface is no longer available";
|
||||||
|
case VK_SUBOPTIMAL_KHR:
|
||||||
|
return "A swapchain no longer matches the surface properties exactly, but can still be used";
|
||||||
|
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||||
|
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
|
||||||
|
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||||
|
return "The display used by a swapchain does not use the same presentable image layout";
|
||||||
|
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||||
|
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
|
||||||
|
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||||
|
return "A validation layer found an error";
|
||||||
|
default:
|
||||||
|
return "ERROR: UNKNOWN VULKAN ERROR";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW public API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI int glfwVulkanSupported(void)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
return _glfwInitVulkan(_GLFW_FIND_LOADER);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
||||||
|
{
|
||||||
|
assert(count != NULL);
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!_glfw.vk.extensions[0])
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*count = 2;
|
||||||
|
return (const char**) _glfw.vk.extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
||||||
|
const char* procname)
|
||||||
|
{
|
||||||
|
GLFWvkproc proc;
|
||||||
|
assert(procname != NULL);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
|
||||||
|
#if defined(_GLFW_VULKAN_STATIC)
|
||||||
|
if (!proc)
|
||||||
|
{
|
||||||
|
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
|
||||||
|
return (GLFWvkproc) vkGetInstanceProcAddr;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!proc)
|
||||||
|
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
|
VkPhysicalDevice device,
|
||||||
|
uint32_t queuefamily)
|
||||||
|
{
|
||||||
|
assert(instance != VK_NULL_HANDLE);
|
||||||
|
assert(device != VK_NULL_HANDLE);
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
|
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!_glfw.vk.extensions[0])
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Window surface creation extensions not found");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
|
||||||
|
device,
|
||||||
|
queuefamily);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
||||||
|
GLFWwindow* handle,
|
||||||
|
const VkAllocationCallbacks* allocator,
|
||||||
|
VkSurfaceKHR* surface)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(instance != VK_NULL_HANDLE);
|
||||||
|
assert(window != NULL);
|
||||||
|
assert(surface != NULL);
|
||||||
|
|
||||||
|
*surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
|
||||||
|
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||||
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
|
|
||||||
|
if (!_glfw.vk.extensions[0])
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: Window surface creation extensions not found");
|
||||||
|
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->context.client != GLFW_NO_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API");
|
||||||
|
return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
|
||||||
|
}
|
||||||
|
|
798
external/glfw-3.3.8/src/wgl_context.c
vendored
Normal file
798
external/glfw-3.3.8/src/wgl_context.c
vendored
Normal file
@ -0,0 +1,798 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 WGL - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
// Return the value corresponding to the specified attribute
|
||||||
|
//
|
||||||
|
static int findPixelFormatAttribValue(const int* attribs,
|
||||||
|
int attribCount,
|
||||||
|
const int* values,
|
||||||
|
int attrib)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < attribCount; i++)
|
||||||
|
{
|
||||||
|
if (attribs[i] == attrib)
|
||||||
|
return values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Unknown pixel format attribute requested");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define addAttrib(a) \
|
||||||
|
{ \
|
||||||
|
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
|
attribs[attribCount++] = a; \
|
||||||
|
}
|
||||||
|
#define findAttribValue(a) \
|
||||||
|
findPixelFormatAttribValue(attribs, attribCount, values, a)
|
||||||
|
|
||||||
|
// Return a list of available and usable framebuffer configs
|
||||||
|
//
|
||||||
|
static int choosePixelFormat(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
_GLFWfbconfig* usableConfigs;
|
||||||
|
const _GLFWfbconfig* closest;
|
||||||
|
int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0;
|
||||||
|
int attribs[40];
|
||||||
|
int values[sizeof(attribs) / sizeof(attribs[0])];
|
||||||
|
|
||||||
|
if (_glfw.wgl.ARB_pixel_format)
|
||||||
|
{
|
||||||
|
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||||
|
|
||||||
|
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||||
|
1, 0, 1, &attrib, &nativeCount))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to retrieve pixel format attribute");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addAttrib(WGL_SUPPORT_OPENGL_ARB);
|
||||||
|
addAttrib(WGL_DRAW_TO_WINDOW_ARB);
|
||||||
|
addAttrib(WGL_PIXEL_TYPE_ARB);
|
||||||
|
addAttrib(WGL_ACCELERATION_ARB);
|
||||||
|
addAttrib(WGL_RED_BITS_ARB);
|
||||||
|
addAttrib(WGL_RED_SHIFT_ARB);
|
||||||
|
addAttrib(WGL_GREEN_BITS_ARB);
|
||||||
|
addAttrib(WGL_GREEN_SHIFT_ARB);
|
||||||
|
addAttrib(WGL_BLUE_BITS_ARB);
|
||||||
|
addAttrib(WGL_BLUE_SHIFT_ARB);
|
||||||
|
addAttrib(WGL_ALPHA_BITS_ARB);
|
||||||
|
addAttrib(WGL_ALPHA_SHIFT_ARB);
|
||||||
|
addAttrib(WGL_DEPTH_BITS_ARB);
|
||||||
|
addAttrib(WGL_STENCIL_BITS_ARB);
|
||||||
|
addAttrib(WGL_ACCUM_BITS_ARB);
|
||||||
|
addAttrib(WGL_ACCUM_RED_BITS_ARB);
|
||||||
|
addAttrib(WGL_ACCUM_GREEN_BITS_ARB);
|
||||||
|
addAttrib(WGL_ACCUM_BLUE_BITS_ARB);
|
||||||
|
addAttrib(WGL_ACCUM_ALPHA_BITS_ARB);
|
||||||
|
addAttrib(WGL_AUX_BUFFERS_ARB);
|
||||||
|
addAttrib(WGL_STEREO_ARB);
|
||||||
|
addAttrib(WGL_DOUBLE_BUFFER_ARB);
|
||||||
|
|
||||||
|
if (_glfw.wgl.ARB_multisample)
|
||||||
|
addAttrib(WGL_SAMPLES_ARB);
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
|
||||||
|
addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.EXT_colorspace)
|
||||||
|
addAttrib(WGL_COLORSPACE_EXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
||||||
|
1,
|
||||||
|
sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||||
|
|
||||||
|
for (i = 0; i < nativeCount; i++)
|
||||||
|
{
|
||||||
|
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||||
|
pixelFormat = i + 1;
|
||||||
|
|
||||||
|
if (_glfw.wgl.ARB_pixel_format)
|
||||||
|
{
|
||||||
|
// Get pixel format attributes through "modern" extension
|
||||||
|
|
||||||
|
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||||
|
pixelFormat, 0,
|
||||||
|
attribCount,
|
||||||
|
attribs, values))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to retrieve pixel format attributes");
|
||||||
|
|
||||||
|
free(usableConfigs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) ||
|
||||||
|
!findAttribValue(WGL_DRAW_TO_WINDOW_ARB))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (findAttribValue(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
u->redBits = findAttribValue(WGL_RED_BITS_ARB);
|
||||||
|
u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB);
|
||||||
|
u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB);
|
||||||
|
u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB);
|
||||||
|
|
||||||
|
u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB);
|
||||||
|
u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB);
|
||||||
|
|
||||||
|
u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB);
|
||||||
|
u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB);
|
||||||
|
u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB);
|
||||||
|
u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB);
|
||||||
|
|
||||||
|
u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB);
|
||||||
|
|
||||||
|
if (findAttribValue(WGL_STEREO_ARB))
|
||||||
|
u->stereo = GLFW_TRUE;
|
||||||
|
|
||||||
|
if (_glfw.wgl.ARB_multisample)
|
||||||
|
u->samples = findAttribValue(WGL_SAMPLES_ARB);
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
||||||
|
_glfw.wgl.EXT_framebuffer_sRGB)
|
||||||
|
{
|
||||||
|
if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
||||||
|
u->sRGB = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.EXT_colorspace)
|
||||||
|
{
|
||||||
|
if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
|
||||||
|
u->sRGB = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get pixel format attributes through legacy PFDs
|
||||||
|
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
|
||||||
|
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||||
|
pixelFormat,
|
||||||
|
sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
|
&pfd))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to describe pixel format");
|
||||||
|
|
||||||
|
free(usableConfigs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!!(pfd.dwFlags & PFD_DOUBLEBUFFER) != fbconfig->doublebuffer)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->handle = pixelFormat;
|
||||||
|
usableCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usableCount)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"WGL: The driver does not appear to support OpenGL");
|
||||||
|
|
||||||
|
free(usableConfigs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
||||||
|
if (!closest)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"WGL: Failed to find a suitable pixel format");
|
||||||
|
|
||||||
|
free(usableConfigs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixelFormat = (int) closest->handle;
|
||||||
|
free(usableConfigs);
|
||||||
|
|
||||||
|
return pixelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef addAttrib
|
||||||
|
#undef findAttribValue
|
||||||
|
|
||||||
|
static void makeContextCurrentWGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to make context current");
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!wglMakeCurrent(NULL, NULL))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to clear current context");
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapBuffersWGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (!window->monitor)
|
||||||
|
{
|
||||||
|
if (IsWindowsVistaOrGreater())
|
||||||
|
{
|
||||||
|
// DWM Composition is always enabled on Win8+
|
||||||
|
BOOL enabled = IsWindows8OrGreater();
|
||||||
|
|
||||||
|
// HACK: Use DwmFlush when desktop composition is enabled
|
||||||
|
if (enabled ||
|
||||||
|
(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
|
||||||
|
{
|
||||||
|
int count = abs(window->context.wgl.interval);
|
||||||
|
while (count--)
|
||||||
|
DwmFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapBuffers(window->context.wgl.dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swapIntervalWGL(int interval)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||||
|
|
||||||
|
window->context.wgl.interval = interval;
|
||||||
|
|
||||||
|
if (!window->monitor)
|
||||||
|
{
|
||||||
|
if (IsWindowsVistaOrGreater())
|
||||||
|
{
|
||||||
|
// DWM Composition is always enabled on Win8+
|
||||||
|
BOOL enabled = IsWindows8OrGreater();
|
||||||
|
|
||||||
|
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||||
|
// avoid interfering with DWM vsync
|
||||||
|
if (enabled ||
|
||||||
|
(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
|
||||||
|
interval = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wgl.EXT_swap_control)
|
||||||
|
wglSwapIntervalEXT(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int extensionSupportedWGL(const char* extension)
|
||||||
|
{
|
||||||
|
const char* extensions = NULL;
|
||||||
|
|
||||||
|
if (_glfw.wgl.GetExtensionsStringARB)
|
||||||
|
extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
|
||||||
|
else if (_glfw.wgl.GetExtensionsStringEXT)
|
||||||
|
extensions = wglGetExtensionsStringEXT();
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
return _glfwStringInExtensionString(extension, extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWglproc getProcAddressWGL(const char* procname)
|
||||||
|
{
|
||||||
|
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
|
||||||
|
if (proc)
|
||||||
|
return proc;
|
||||||
|
|
||||||
|
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyContextWGL(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->context.wgl.handle)
|
||||||
|
{
|
||||||
|
wglDeleteContext(window->context.wgl.handle);
|
||||||
|
window->context.wgl.handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize WGL
|
||||||
|
//
|
||||||
|
GLFWbool _glfwInitWGL(void)
|
||||||
|
{
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
HGLRC prc, rc;
|
||||||
|
HDC pdc, dc;
|
||||||
|
|
||||||
|
if (_glfw.wgl.instance)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||||
|
if (!_glfw.wgl.instance)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to load opengl32.dll");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
|
||||||
|
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
|
||||||
|
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
|
||||||
|
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
|
||||||
|
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext");
|
||||||
|
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
|
||||||
|
_glfw.wgl.ShareLists = (PFN_wglShareLists)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglShareLists");
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
dc = GetDC(_glfw.win32.helperWindowHandle);
|
||||||
|
|
||||||
|
ZeroMemory(&pfd, sizeof(pfd));
|
||||||
|
pfd.nSize = sizeof(pfd);
|
||||||
|
pfd.nVersion = 1;
|
||||||
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||||
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||||
|
pfd.cColorBits = 24;
|
||||||
|
|
||||||
|
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to set pixel format for dummy context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = wglCreateContext(dc);
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to create dummy context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdc = wglGetCurrentDC();
|
||||||
|
prc = wglGetCurrentContext();
|
||||||
|
|
||||||
|
if (!wglMakeCurrent(dc, rc))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to make dummy context current");
|
||||||
|
wglMakeCurrent(pdc, prc);
|
||||||
|
wglDeleteContext(rc);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Functions must be loaded first as they're needed to retrieve the
|
||||||
|
// extension string that tells us whether the functions are supported
|
||||||
|
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
||||||
|
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||||
|
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||||||
|
wglGetProcAddress("wglGetExtensionsStringARB");
|
||||||
|
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||||
|
wglGetProcAddress("wglCreateContextAttribsARB");
|
||||||
|
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
||||||
|
wglGetProcAddress("wglSwapIntervalEXT");
|
||||||
|
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||||||
|
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||||
|
|
||||||
|
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
|
||||||
|
// checked below as we are already using them
|
||||||
|
_glfw.wgl.ARB_multisample =
|
||||||
|
extensionSupportedWGL("WGL_ARB_multisample");
|
||||||
|
_glfw.wgl.ARB_framebuffer_sRGB =
|
||||||
|
extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
|
||||||
|
_glfw.wgl.EXT_framebuffer_sRGB =
|
||||||
|
extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
|
||||||
|
_glfw.wgl.ARB_create_context =
|
||||||
|
extensionSupportedWGL("WGL_ARB_create_context");
|
||||||
|
_glfw.wgl.ARB_create_context_profile =
|
||||||
|
extensionSupportedWGL("WGL_ARB_create_context_profile");
|
||||||
|
_glfw.wgl.EXT_create_context_es2_profile =
|
||||||
|
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
|
||||||
|
_glfw.wgl.ARB_create_context_robustness =
|
||||||
|
extensionSupportedWGL("WGL_ARB_create_context_robustness");
|
||||||
|
_glfw.wgl.ARB_create_context_no_error =
|
||||||
|
extensionSupportedWGL("WGL_ARB_create_context_no_error");
|
||||||
|
_glfw.wgl.EXT_swap_control =
|
||||||
|
extensionSupportedWGL("WGL_EXT_swap_control");
|
||||||
|
_glfw.wgl.EXT_colorspace =
|
||||||
|
extensionSupportedWGL("WGL_EXT_colorspace");
|
||||||
|
_glfw.wgl.ARB_pixel_format =
|
||||||
|
extensionSupportedWGL("WGL_ARB_pixel_format");
|
||||||
|
_glfw.wgl.ARB_context_flush_control =
|
||||||
|
extensionSupportedWGL("WGL_ARB_context_flush_control");
|
||||||
|
|
||||||
|
wglMakeCurrent(pdc, prc);
|
||||||
|
wglDeleteContext(rc);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate WGL
|
||||||
|
//
|
||||||
|
void _glfwTerminateWGL(void)
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.instance)
|
||||||
|
FreeLibrary(_glfw.wgl.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define setAttrib(a, v) \
|
||||||
|
{ \
|
||||||
|
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
|
attribs[index++] = a; \
|
||||||
|
attribs[index++] = v; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the OpenGL or OpenGL ES context
|
||||||
|
//
|
||||||
|
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
int attribs[40];
|
||||||
|
int pixelFormat;
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
HGLRC share = NULL;
|
||||||
|
|
||||||
|
if (ctxconfig->share)
|
||||||
|
share = ctxconfig->share->context.wgl.handle;
|
||||||
|
|
||||||
|
window->context.wgl.dc = GetDC(window->win32.handle);
|
||||||
|
if (!window->context.wgl.dc)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to retrieve DC for window");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
|
||||||
|
if (!pixelFormat)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||||
|
pixelFormat, sizeof(pfd), &pfd))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to retrieve PFD for selected pixel format");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to set selected pixel format");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
{
|
||||||
|
if (!_glfw.wgl.ARB_create_context)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->profile)
|
||||||
|
{
|
||||||
|
if (!_glfw.wgl.ARB_create_context_profile)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!_glfw.wgl.ARB_create_context ||
|
||||||
|
!_glfw.wgl.ARB_create_context_profile ||
|
||||||
|
!_glfw.wgl.EXT_create_context_es2_profile)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wgl.ARB_create_context)
|
||||||
|
{
|
||||||
|
int index = 0, mask = 0, flags = 0;
|
||||||
|
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig->forward)
|
||||||
|
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||||
|
|
||||||
|
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||||
|
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
|
mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
|
||||||
|
|
||||||
|
if (ctxconfig->debug)
|
||||||
|
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||||
|
|
||||||
|
if (ctxconfig->robustness)
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.ARB_create_context_robustness)
|
||||||
|
{
|
||||||
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
|
{
|
||||||
|
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
|
WGL_NO_RESET_NOTIFICATION_ARB);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
|
{
|
||||||
|
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
|
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
||||||
|
}
|
||||||
|
|
||||||
|
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->release)
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.ARB_context_flush_control)
|
||||||
|
{
|
||||||
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
|
{
|
||||||
|
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
|
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||||
|
}
|
||||||
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
|
{
|
||||||
|
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
|
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig->noerror)
|
||||||
|
{
|
||||||
|
if (_glfw.wgl.ARB_create_context_no_error)
|
||||||
|
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
|
// explicitly requesting version 1.0 does not always return the
|
||||||
|
// highest version supported by the driver
|
||||||
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
|
{
|
||||||
|
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||||
|
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags)
|
||||||
|
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||||
|
|
||||||
|
setAttrib(0, 0);
|
||||||
|
|
||||||
|
window->context.wgl.handle =
|
||||||
|
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
|
||||||
|
if (!window->context.wgl.handle)
|
||||||
|
{
|
||||||
|
const DWORD error = GetLastError();
|
||||||
|
|
||||||
|
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
|
||||||
|
{
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: Driver does not support OpenGL version %i.%i",
|
||||||
|
ctxconfig->major,
|
||||||
|
ctxconfig->minor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: Driver does not support OpenGL ES version %i.%i",
|
||||||
|
ctxconfig->major,
|
||||||
|
ctxconfig->minor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: Driver does not support the requested OpenGL profile");
|
||||||
|
}
|
||||||
|
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"WGL: The share context is not compatible with the requested context");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: Failed to create OpenGL context");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: Failed to create OpenGL ES context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
||||||
|
if (!window->context.wgl.handle)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
|
||||||
|
"WGL: Failed to create OpenGL context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (share)
|
||||||
|
{
|
||||||
|
if (!wglShareLists(share, window->context.wgl.handle))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to enable sharing with specified OpenGL context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window->context.makeCurrent = makeContextCurrentWGL;
|
||||||
|
window->context.swapBuffers = swapBuffersWGL;
|
||||||
|
window->context.swapInterval = swapIntervalWGL;
|
||||||
|
window->context.extensionSupported = extensionSupportedWGL;
|
||||||
|
window->context.getProcAddress = getProcAddressWGL;
|
||||||
|
window->context.destroy = destroyContextWGL;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef setAttrib
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW native API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window->context.wgl.handle;
|
||||||
|
}
|
||||||
|
|
158
external/glfw-3.3.8/src/wgl_context.h
vendored
Normal file
158
external/glfw-3.3.8/src/wgl_context.h
vendored
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 WGL - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||||
|
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||||
|
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||||
|
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||||
|
#define WGL_TYPE_RGBA_ARB 0x202b
|
||||||
|
#define WGL_ACCELERATION_ARB 0x2003
|
||||||
|
#define WGL_NO_ACCELERATION_ARB 0x2025
|
||||||
|
#define WGL_RED_BITS_ARB 0x2015
|
||||||
|
#define WGL_RED_SHIFT_ARB 0x2016
|
||||||
|
#define WGL_GREEN_BITS_ARB 0x2017
|
||||||
|
#define WGL_GREEN_SHIFT_ARB 0x2018
|
||||||
|
#define WGL_BLUE_BITS_ARB 0x2019
|
||||||
|
#define WGL_BLUE_SHIFT_ARB 0x201a
|
||||||
|
#define WGL_ALPHA_BITS_ARB 0x201b
|
||||||
|
#define WGL_ALPHA_SHIFT_ARB 0x201c
|
||||||
|
#define WGL_ACCUM_BITS_ARB 0x201d
|
||||||
|
#define WGL_ACCUM_RED_BITS_ARB 0x201e
|
||||||
|
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
|
||||||
|
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||||
|
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||||
|
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||||
|
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||||
|
#define WGL_AUX_BUFFERS_ARB 0x2024
|
||||||
|
#define WGL_STEREO_ARB 0x2012
|
||||||
|
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||||
|
#define WGL_SAMPLES_ARB 0x2042
|
||||||
|
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
|
||||||
|
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||||
|
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||||
|
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||||
|
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||||
|
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
|
||||||
|
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||||
|
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||||
|
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||||
|
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
||||||
|
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
|
||||||
|
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||||
|
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
|
||||||
|
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||||
|
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||||
|
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||||
|
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||||
|
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
||||||
|
#define WGL_COLORSPACE_EXT 0x309d
|
||||||
|
#define WGL_COLORSPACE_SRGB_EXT 0x3089
|
||||||
|
|
||||||
|
#define ERROR_INVALID_VERSION_ARB 0x2095
|
||||||
|
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||||
|
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
||||||
|
|
||||||
|
// WGL extension pointer typedefs
|
||||||
|
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*);
|
||||||
|
#define wglSwapIntervalEXT _glfw.wgl.SwapIntervalEXT
|
||||||
|
#define wglGetPixelFormatAttribivARB _glfw.wgl.GetPixelFormatAttribivARB
|
||||||
|
#define wglGetExtensionsStringEXT _glfw.wgl.GetExtensionsStringEXT
|
||||||
|
#define wglGetExtensionsStringARB _glfw.wgl.GetExtensionsStringARB
|
||||||
|
#define wglCreateContextAttribsARB _glfw.wgl.CreateContextAttribsARB
|
||||||
|
|
||||||
|
// opengl32.dll function pointer typedefs
|
||||||
|
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
|
||||||
|
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
|
||||||
|
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
|
||||||
|
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
|
||||||
|
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
|
||||||
|
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
|
||||||
|
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
|
||||||
|
#define wglCreateContext _glfw.wgl.CreateContext
|
||||||
|
#define wglDeleteContext _glfw.wgl.DeleteContext
|
||||||
|
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
||||||
|
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
|
||||||
|
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
|
||||||
|
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
||||||
|
#define wglShareLists _glfw.wgl.ShareLists
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
|
||||||
|
|
||||||
|
|
||||||
|
// WGL-specific per-context data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcontextWGL
|
||||||
|
{
|
||||||
|
HDC dc;
|
||||||
|
HGLRC handle;
|
||||||
|
int interval;
|
||||||
|
} _GLFWcontextWGL;
|
||||||
|
|
||||||
|
// WGL-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryWGL
|
||||||
|
{
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_wglCreateContext CreateContext;
|
||||||
|
PFN_wglDeleteContext DeleteContext;
|
||||||
|
PFN_wglGetProcAddress GetProcAddress;
|
||||||
|
PFN_wglGetCurrentDC GetCurrentDC;
|
||||||
|
PFN_wglGetCurrentContext GetCurrentContext;
|
||||||
|
PFN_wglMakeCurrent MakeCurrent;
|
||||||
|
PFN_wglShareLists ShareLists;
|
||||||
|
|
||||||
|
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||||
|
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
|
||||||
|
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
||||||
|
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
||||||
|
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||||
|
GLFWbool EXT_swap_control;
|
||||||
|
GLFWbool EXT_colorspace;
|
||||||
|
GLFWbool ARB_multisample;
|
||||||
|
GLFWbool ARB_framebuffer_sRGB;
|
||||||
|
GLFWbool EXT_framebuffer_sRGB;
|
||||||
|
GLFWbool ARB_pixel_format;
|
||||||
|
GLFWbool ARB_create_context;
|
||||||
|
GLFWbool ARB_create_context_profile;
|
||||||
|
GLFWbool EXT_create_context_es2_profile;
|
||||||
|
GLFWbool ARB_create_context_robustness;
|
||||||
|
GLFWbool ARB_create_context_no_error;
|
||||||
|
GLFWbool ARB_context_flush_control;
|
||||||
|
} _GLFWlibraryWGL;
|
||||||
|
|
||||||
|
|
||||||
|
GLFWbool _glfwInitWGL(void);
|
||||||
|
void _glfwTerminateWGL(void);
|
||||||
|
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
638
external/glfw-3.3.8/src/win32_init.c
vendored
Normal file
638
external/glfw-3.3.8/src/win32_init.c
vendored
Normal file
@ -0,0 +1,638 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
static const GUID _glfw_GUID_DEVINTERFACE_HID =
|
||||||
|
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
|
||||||
|
|
||||||
|
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
|
||||||
|
|
||||||
|
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
||||||
|
|
||||||
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
|
#pragma message("These symbols must be exported by the executable and have no effect in a DLL")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Executables (but not DLLs) exporting this symbol with this value will be
|
||||||
|
// automatically directed to the high-performance GPU on Nvidia Optimus systems
|
||||||
|
// with up-to-date drivers
|
||||||
|
//
|
||||||
|
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
||||||
|
|
||||||
|
// Executables (but not DLLs) exporting this symbol with this value will be
|
||||||
|
// automatically directed to the high-performance GPU on AMD PowerXpress systems
|
||||||
|
// with up-to-date drivers
|
||||||
|
//
|
||||||
|
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||||
|
|
||||||
|
#endif // _GLFW_USE_HYBRID_HPG
|
||||||
|
|
||||||
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
|
|
||||||
|
// GLFW DLL entry point
|
||||||
|
//
|
||||||
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _GLFW_BUILD_DLL
|
||||||
|
|
||||||
|
// Load necessary libraries (DLLs)
|
||||||
|
//
|
||||||
|
static GLFWbool loadLibraries(void)
|
||||||
|
{
|
||||||
|
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||||
|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||||
|
(const WCHAR*) &_glfw,
|
||||||
|
(HMODULE*) &_glfw.win32.instance))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to retrieve own module handle");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
||||||
|
if (!_glfw.win32.user32.instance)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to load user32.dll");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||||
|
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||||
|
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
|
||||||
|
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
|
||||||
|
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
|
||||||
|
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
||||||
|
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
|
||||||
|
GetProcAddress(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
|
||||||
|
|
||||||
|
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||||
|
if (_glfw.win32.dinput8.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
|
||||||
|
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char* names[] =
|
||||||
|
{
|
||||||
|
"xinput1_4.dll",
|
||||||
|
"xinput1_3.dll",
|
||||||
|
"xinput9_1_0.dll",
|
||||||
|
"xinput1_2.dll",
|
||||||
|
"xinput1_1.dll",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; names[i]; i++)
|
||||||
|
{
|
||||||
|
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
|
||||||
|
if (_glfw.win32.xinput.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
|
||||||
|
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
|
||||||
|
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
|
||||||
|
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
|
||||||
|
if (_glfw.win32.dwmapi.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||||
|
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||||
|
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
|
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||||
|
if (_glfw.win32.shcore.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
|
||||||
|
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
||||||
|
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
|
||||||
|
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
|
||||||
|
if (_glfw.win32.ntdll.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
|
||||||
|
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
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.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);
|
||||||
|
|
||||||
|
if (_glfw.win32.ntdll.instance)
|
||||||
|
FreeLibrary(_glfw.win32.ntdll.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create key code translation tables
|
||||||
|
//
|
||||||
|
static void createKeyTables(void)
|
||||||
|
{
|
||||||
|
int scancode;
|
||||||
|
|
||||||
|
memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
|
||||||
|
memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
|
||||||
|
|
||||||
|
_glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
|
||||||
|
_glfw.win32.keycodes[0x002] = GLFW_KEY_1;
|
||||||
|
_glfw.win32.keycodes[0x003] = GLFW_KEY_2;
|
||||||
|
_glfw.win32.keycodes[0x004] = GLFW_KEY_3;
|
||||||
|
_glfw.win32.keycodes[0x005] = GLFW_KEY_4;
|
||||||
|
_glfw.win32.keycodes[0x006] = GLFW_KEY_5;
|
||||||
|
_glfw.win32.keycodes[0x007] = GLFW_KEY_6;
|
||||||
|
_glfw.win32.keycodes[0x008] = GLFW_KEY_7;
|
||||||
|
_glfw.win32.keycodes[0x009] = GLFW_KEY_8;
|
||||||
|
_glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
|
||||||
|
_glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
|
||||||
|
_glfw.win32.keycodes[0x030] = GLFW_KEY_B;
|
||||||
|
_glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
|
||||||
|
_glfw.win32.keycodes[0x020] = GLFW_KEY_D;
|
||||||
|
_glfw.win32.keycodes[0x012] = GLFW_KEY_E;
|
||||||
|
_glfw.win32.keycodes[0x021] = GLFW_KEY_F;
|
||||||
|
_glfw.win32.keycodes[0x022] = GLFW_KEY_G;
|
||||||
|
_glfw.win32.keycodes[0x023] = GLFW_KEY_H;
|
||||||
|
_glfw.win32.keycodes[0x017] = GLFW_KEY_I;
|
||||||
|
_glfw.win32.keycodes[0x024] = GLFW_KEY_J;
|
||||||
|
_glfw.win32.keycodes[0x025] = GLFW_KEY_K;
|
||||||
|
_glfw.win32.keycodes[0x026] = GLFW_KEY_L;
|
||||||
|
_glfw.win32.keycodes[0x032] = GLFW_KEY_M;
|
||||||
|
_glfw.win32.keycodes[0x031] = GLFW_KEY_N;
|
||||||
|
_glfw.win32.keycodes[0x018] = GLFW_KEY_O;
|
||||||
|
_glfw.win32.keycodes[0x019] = GLFW_KEY_P;
|
||||||
|
_glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
|
||||||
|
_glfw.win32.keycodes[0x013] = GLFW_KEY_R;
|
||||||
|
_glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
|
||||||
|
_glfw.win32.keycodes[0x014] = GLFW_KEY_T;
|
||||||
|
_glfw.win32.keycodes[0x016] = GLFW_KEY_U;
|
||||||
|
_glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
|
||||||
|
_glfw.win32.keycodes[0x011] = GLFW_KEY_W;
|
||||||
|
_glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
|
||||||
|
_glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
|
||||||
|
_glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
|
||||||
|
|
||||||
|
_glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
|
||||||
|
_glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
|
||||||
|
_glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
|
||||||
|
_glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
|
||||||
|
_glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
|
||||||
|
_glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
|
||||||
|
_glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
|
||||||
|
_glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
|
||||||
|
_glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
|
||||||
|
_glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
|
||||||
|
_glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
|
||||||
|
_glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
|
||||||
|
|
||||||
|
_glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
|
||||||
|
_glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
|
||||||
|
_glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
|
||||||
|
_glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
|
||||||
|
_glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
|
||||||
|
_glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
|
||||||
|
_glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
|
||||||
|
_glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
|
||||||
|
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
|
||||||
|
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
|
||||||
|
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
|
||||||
|
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
|
||||||
|
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
|
||||||
|
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
|
||||||
|
_glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
|
||||||
|
_glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
|
||||||
|
_glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
|
||||||
|
_glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
|
||||||
|
_glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
|
||||||
|
_glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
|
||||||
|
_glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
|
||||||
|
_glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
|
||||||
|
_glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
|
||||||
|
_glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
|
||||||
|
_glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
|
||||||
|
_glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
|
||||||
|
_glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
|
||||||
|
_glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
|
||||||
|
_glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
|
||||||
|
_glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
|
||||||
|
_glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
|
||||||
|
_glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
|
||||||
|
_glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
|
||||||
|
_glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
|
||||||
|
_glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
|
||||||
|
_glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
|
||||||
|
_glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
|
||||||
|
_glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
|
||||||
|
_glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
|
||||||
|
_glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
|
||||||
|
_glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
|
||||||
|
_glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
|
||||||
|
_glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
|
||||||
|
_glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
|
||||||
|
_glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
|
||||||
|
_glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
|
||||||
|
_glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
_glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
|
||||||
|
_glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
|
||||||
|
_glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
|
||||||
|
_glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
|
||||||
|
_glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
|
||||||
|
_glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
|
||||||
|
|
||||||
|
_glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
|
||||||
|
_glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
|
||||||
|
_glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
|
||||||
|
_glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
|
||||||
|
_glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
|
||||||
|
_glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
|
||||||
|
_glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
|
||||||
|
_glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
|
||||||
|
_glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
|
||||||
|
_glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
|
||||||
|
_glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
|
||||||
|
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
|
||||||
|
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
|
||||||
|
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
|
||||||
|
_glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
|
||||||
|
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
|
||||||
|
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
|
||||||
|
|
||||||
|
for (scancode = 0; scancode < 512; scancode++)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.keycodes[scancode] > 0)
|
||||||
|
_glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a dummy window for behind-the-scenes work
|
||||||
|
//
|
||||||
|
static GLFWbool createHelperWindow(void)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
_glfw.win32.helperWindowHandle =
|
||||||
|
CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
|
||||||
|
_GLFW_WNDCLASSNAME,
|
||||||
|
L"GLFW message window",
|
||||||
|
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||||
|
0, 0, 1, 1,
|
||||||
|
NULL, NULL,
|
||||||
|
_glfw.win32.instance,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!_glfw.win32.helperWindowHandle)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to create helper window");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: The command to the first ShowWindow call is ignored if the parent
|
||||||
|
// process passed along a STARTUPINFO, so clear that with a no-op call
|
||||||
|
ShowWindow(_glfw.win32.helperWindowHandle, 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;
|
||||||
|
|
||||||
|
_glfw.win32.deviceNotificationHandle =
|
||||||
|
RegisterDeviceNotificationW(_glfw.win32.helperWindowHandle,
|
||||||
|
(DEV_BROADCAST_HDR*) &dbi,
|
||||||
|
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessageW(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Returns a wide string version of the specified UTF-8 string
|
||||||
|
//
|
||||||
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
||||||
|
{
|
||||||
|
WCHAR* target;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
||||||
|
if (!count)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert string from UTF-8");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = calloc(count, sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert string from UTF-8");
|
||||||
|
free(target);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a UTF-8 string version of the specified wide string
|
||||||
|
//
|
||||||
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
||||||
|
{
|
||||||
|
char* target;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert string to UTF-8");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = calloc(size, 1);
|
||||||
|
|
||||||
|
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert string to UTF-8");
|
||||||
|
free(target);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reports the specified error, appending information about the last Win32 error
|
||||||
|
//
|
||||||
|
void _glfwInputErrorWin32(int error, const char* description)
|
||||||
|
{
|
||||||
|
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
|
||||||
|
char message[_GLFW_MESSAGE_SIZE] = "";
|
||||||
|
|
||||||
|
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||||
|
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||||
|
NULL,
|
||||||
|
GetLastError() & 0xffff,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
buffer,
|
||||||
|
sizeof(buffer) / sizeof(WCHAR),
|
||||||
|
NULL);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
|
||||||
|
|
||||||
|
_glfwInputError(error, "%s: %s", description, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates key names according to the current keyboard layout
|
||||||
|
//
|
||||||
|
void _glfwUpdateKeyNamesWin32(void)
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
BYTE state[256] = {0};
|
||||||
|
|
||||||
|
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
|
||||||
|
|
||||||
|
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
|
||||||
|
{
|
||||||
|
UINT vk;
|
||||||
|
int scancode, length;
|
||||||
|
WCHAR chars[16];
|
||||||
|
|
||||||
|
scancode = _glfw.win32.scancodes[key];
|
||||||
|
if (scancode == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
||||||
|
{
|
||||||
|
const UINT vks[] = {
|
||||||
|
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
||||||
|
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
||||||
|
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
||||||
|
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
|
||||||
|
};
|
||||||
|
|
||||||
|
vk = vks[key - GLFW_KEY_KP_0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK);
|
||||||
|
|
||||||
|
length = ToUnicode(vk, scancode, state,
|
||||||
|
chars, sizeof(chars) / sizeof(WCHAR),
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (length == -1)
|
||||||
|
{
|
||||||
|
// This is a dead key, so we need a second simulated key press
|
||||||
|
// to make it output its own character (usually a diacritic)
|
||||||
|
length = ToUnicode(vk, scancode, state,
|
||||||
|
chars, sizeof(chars) / sizeof(WCHAR),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
|
||||||
|
_glfw.win32.keynames[key],
|
||||||
|
sizeof(_glfw.win32.keynames[key]),
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
|
||||||
|
// application having a correct embedded manifest
|
||||||
|
//
|
||||||
|
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
||||||
|
{
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
|
||||||
|
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
||||||
|
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||||
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
|
// latter lies unless the user knew to embed a non-default manifest
|
||||||
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
|
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether we are on at least the specified build of Windows 10
|
||||||
|
//
|
||||||
|
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
|
||||||
|
{
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
|
||||||
|
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
|
||||||
|
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
||||||
|
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||||
|
// latter lies unless the user knew to embed a non-default manifest
|
||||||
|
// announcing support for Windows 10 via supportedOS GUID
|
||||||
|
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformInit(void)
|
||||||
|
{
|
||||||
|
// To make SetForegroundWindow work as we want, we need to fiddle
|
||||||
|
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
|
||||||
|
// as possible in the hope of still being the foreground process)
|
||||||
|
SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
|
||||||
|
&_glfw.win32.foregroundLockTimeout, 0);
|
||||||
|
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
|
||||||
|
SPIF_SENDCHANGE);
|
||||||
|
|
||||||
|
if (!loadLibraries())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
createKeyTables();
|
||||||
|
_glfwUpdateKeyNamesWin32();
|
||||||
|
|
||||||
|
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
||||||
|
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||||
|
else if (IsWindows8Point1OrGreater())
|
||||||
|
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
|
else if (IsWindowsVistaOrGreater())
|
||||||
|
SetProcessDPIAware();
|
||||||
|
|
||||||
|
if (!_glfwRegisterWindowClassWin32())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!createHelperWindow())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
_glfwInitTimerWin32();
|
||||||
|
_glfwInitJoysticksWin32();
|
||||||
|
|
||||||
|
_glfwPollMonitorsWin32();
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformTerminate(void)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.deviceNotificationHandle)
|
||||||
|
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
|
||||||
|
|
||||||
|
if (_glfw.win32.helperWindowHandle)
|
||||||
|
DestroyWindow(_glfw.win32.helperWindowHandle);
|
||||||
|
|
||||||
|
_glfwUnregisterWindowClassWin32();
|
||||||
|
|
||||||
|
// Restore previous foreground lock timeout system setting
|
||||||
|
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
|
||||||
|
UIntToPtr(_glfw.win32.foregroundLockTimeout),
|
||||||
|
SPIF_SENDCHANGE);
|
||||||
|
|
||||||
|
free(_glfw.win32.clipboardString);
|
||||||
|
free(_glfw.win32.rawInput);
|
||||||
|
|
||||||
|
_glfwTerminateWGL();
|
||||||
|
_glfwTerminateEGL();
|
||||||
|
_glfwTerminateOSMesa();
|
||||||
|
|
||||||
|
_glfwTerminateJoysticksWin32();
|
||||||
|
|
||||||
|
freeLibraries();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
|
{
|
||||||
|
return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa"
|
||||||
|
#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
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
755
external/glfw-3.3.8/src/win32_joystick.c
vendored
Normal file
755
external/glfw-3.3.8/src/win32_joystick.c
vendored
Normal file
@ -0,0 +1,755 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define _GLFW_TYPE_AXIS 0
|
||||||
|
#define _GLFW_TYPE_SLIDER 1
|
||||||
|
#define _GLFW_TYPE_BUTTON 2
|
||||||
|
#define _GLFW_TYPE_POV 3
|
||||||
|
|
||||||
|
// Data produced with DirectInput device object enumeration
|
||||||
|
//
|
||||||
|
typedef struct _GLFWobjenumWin32
|
||||||
|
{
|
||||||
|
IDirectInputDevice8W* device;
|
||||||
|
_GLFWjoyobjectWin32* objects;
|
||||||
|
int objectCount;
|
||||||
|
int axisCount;
|
||||||
|
int sliderCount;
|
||||||
|
int buttonCount;
|
||||||
|
int povCount;
|
||||||
|
} _GLFWobjenumWin32;
|
||||||
|
|
||||||
|
// Define local copies of the necessary GUIDs
|
||||||
|
//
|
||||||
|
static const GUID _glfw_IID_IDirectInput8W =
|
||||||
|
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
|
||||||
|
static const GUID _glfw_GUID_XAxis =
|
||||||
|
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_YAxis =
|
||||||
|
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_ZAxis =
|
||||||
|
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_RxAxis =
|
||||||
|
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_RyAxis =
|
||||||
|
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_RzAxis =
|
||||||
|
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_Slider =
|
||||||
|
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
static const GUID _glfw_GUID_POV =
|
||||||
|
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
|
||||||
|
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
|
||||||
|
#define GUID_XAxis _glfw_GUID_XAxis
|
||||||
|
#define GUID_YAxis _glfw_GUID_YAxis
|
||||||
|
#define GUID_ZAxis _glfw_GUID_ZAxis
|
||||||
|
#define GUID_RxAxis _glfw_GUID_RxAxis
|
||||||
|
#define GUID_RyAxis _glfw_GUID_RyAxis
|
||||||
|
#define GUID_RzAxis _glfw_GUID_RzAxis
|
||||||
|
#define GUID_Slider _glfw_GUID_Slider
|
||||||
|
#define GUID_POV _glfw_GUID_POV
|
||||||
|
|
||||||
|
// Object data array for our clone of c_dfDIJoystick
|
||||||
|
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
|
||||||
|
//
|
||||||
|
static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
|
||||||
|
{
|
||||||
|
{ &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
{ NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Our clone of c_dfDIJoystick
|
||||||
|
//
|
||||||
|
static const DIDATAFORMAT _glfwDataFormat =
|
||||||
|
{
|
||||||
|
sizeof(DIDATAFORMAT),
|
||||||
|
sizeof(DIOBJECTDATAFORMAT),
|
||||||
|
DIDFT_ABSAXIS,
|
||||||
|
sizeof(DIJOYSTATE),
|
||||||
|
sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
|
||||||
|
_glfwObjectDataFormats
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns a description fitting the specified XInput capabilities
|
||||||
|
//
|
||||||
|
static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
|
||||||
|
{
|
||||||
|
switch (xic->SubType)
|
||||||
|
{
|
||||||
|
case XINPUT_DEVSUBTYPE_WHEEL:
|
||||||
|
return "XInput Wheel";
|
||||||
|
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
|
||||||
|
return "XInput Arcade Stick";
|
||||||
|
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
|
||||||
|
return "XInput Flight Stick";
|
||||||
|
case XINPUT_DEVSUBTYPE_DANCE_PAD:
|
||||||
|
return "XInput Dance Pad";
|
||||||
|
case XINPUT_DEVSUBTYPE_GUITAR:
|
||||||
|
return "XInput Guitar";
|
||||||
|
case XINPUT_DEVSUBTYPE_DRUM_KIT:
|
||||||
|
return "XInput Drum Kit";
|
||||||
|
case XINPUT_DEVSUBTYPE_GAMEPAD:
|
||||||
|
{
|
||||||
|
if (xic->Flags & XINPUT_CAPS_WIRELESS)
|
||||||
|
return "Wireless Xbox Controller";
|
||||||
|
else
|
||||||
|
return "Xbox Controller";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown XInput Device";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lexically compare device objects
|
||||||
|
//
|
||||||
|
static int compareJoystickObjects(const void* first, const void* second)
|
||||||
|
{
|
||||||
|
const _GLFWjoyobjectWin32* fo = first;
|
||||||
|
const _GLFWjoyobjectWin32* so = second;
|
||||||
|
|
||||||
|
if (fo->type != so->type)
|
||||||
|
return fo->type - so->type;
|
||||||
|
|
||||||
|
return fo->offset - so->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether the specified device supports XInput
|
||||||
|
// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
|
||||||
|
//
|
||||||
|
static GLFWbool supportsXInput(const GUID* guid)
|
||||||
|
{
|
||||||
|
UINT i, count = 0;
|
||||||
|
RAWINPUTDEVICELIST* ridl;
|
||||||
|
GLFWbool result = GLFW_FALSE;
|
||||||
|
|
||||||
|
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||||
|
|
||||||
|
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
||||||
|
{
|
||||||
|
free(ridl);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
RID_DEVICE_INFO rdi;
|
||||||
|
char name[256];
|
||||||
|
UINT size;
|
||||||
|
|
||||||
|
if (ridl[i].dwType != RIM_TYPEHID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ZeroMemory(&rdi, sizeof(rdi));
|
||||||
|
rdi.cbSize = sizeof(rdi);
|
||||||
|
size = sizeof(rdi);
|
||||||
|
|
||||||
|
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
|
||||||
|
RIDI_DEVICEINFO,
|
||||||
|
&rdi, &size) == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memset(name, 0, sizeof(name));
|
||||||
|
size = sizeof(name);
|
||||||
|
|
||||||
|
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
|
||||||
|
RIDI_DEVICENAME,
|
||||||
|
name, &size) == -1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
name[sizeof(name) - 1] = '\0';
|
||||||
|
if (strstr(name, "IG_"))
|
||||||
|
{
|
||||||
|
result = GLFW_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ridl);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frees all resources associated with the specified joystick
|
||||||
|
//
|
||||||
|
static void closeJoystick(_GLFWjoystick* js)
|
||||||
|
{
|
||||||
|
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||||
|
|
||||||
|
if (js->win32.device)
|
||||||
|
{
|
||||||
|
IDirectInputDevice8_Unacquire(js->win32.device);
|
||||||
|
IDirectInputDevice8_Release(js->win32.device);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(js->win32.objects);
|
||||||
|
_glfwFreeJoystick(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DirectInput device object enumeration callback
|
||||||
|
// Insights gleaned from SDL
|
||||||
|
//
|
||||||
|
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
|
||||||
|
void* user)
|
||||||
|
{
|
||||||
|
_GLFWobjenumWin32* data = user;
|
||||||
|
_GLFWjoyobjectWin32* object = data->objects + data->objectCount;
|
||||||
|
|
||||||
|
if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
|
||||||
|
{
|
||||||
|
DIPROPRANGE dipr;
|
||||||
|
|
||||||
|
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_SLIDER(data->sliderCount);
|
||||||
|
else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_X;
|
||||||
|
else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_Y;
|
||||||
|
else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_Z;
|
||||||
|
else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_RX;
|
||||||
|
else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_RY;
|
||||||
|
else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
|
||||||
|
object->offset = DIJOFS_RZ;
|
||||||
|
else
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
|
||||||
|
ZeroMemory(&dipr, sizeof(dipr));
|
||||||
|
dipr.diph.dwSize = sizeof(dipr);
|
||||||
|
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
|
||||||
|
dipr.diph.dwObj = doi->dwType;
|
||||||
|
dipr.diph.dwHow = DIPH_BYID;
|
||||||
|
dipr.lMin = -32768;
|
||||||
|
dipr.lMax = 32767;
|
||||||
|
|
||||||
|
if (FAILED(IDirectInputDevice8_SetProperty(data->device,
|
||||||
|
DIPROP_RANGE,
|
||||||
|
&dipr.diph)))
|
||||||
|
{
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
|
||||||
|
{
|
||||||
|
object->type = _GLFW_TYPE_SLIDER;
|
||||||
|
data->sliderCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object->type = _GLFW_TYPE_AXIS;
|
||||||
|
data->axisCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
|
||||||
|
{
|
||||||
|
object->offset = DIJOFS_BUTTON(data->buttonCount);
|
||||||
|
object->type = _GLFW_TYPE_BUTTON;
|
||||||
|
data->buttonCount++;
|
||||||
|
}
|
||||||
|
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
|
||||||
|
{
|
||||||
|
object->offset = DIJOFS_POV(data->povCount);
|
||||||
|
object->type = _GLFW_TYPE_POV;
|
||||||
|
data->povCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->objectCount++;
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DirectInput device enumeration callback
|
||||||
|
//
|
||||||
|
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||||
|
{
|
||||||
|
int jid = 0;
|
||||||
|
DIDEVCAPS dc;
|
||||||
|
DIPROPDWORD dipd;
|
||||||
|
IDirectInputDevice8* device;
|
||||||
|
_GLFWobjenumWin32 data;
|
||||||
|
_GLFWjoystick* js;
|
||||||
|
char guid[33];
|
||||||
|
char name[256];
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
js = _glfw.joysticks + jid;
|
||||||
|
if (js->connected)
|
||||||
|
{
|
||||||
|
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsXInput(&di->guidProduct))
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
|
||||||
|
if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
|
||||||
|
&di->guidInstance,
|
||||||
|
&device,
|
||||||
|
NULL)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to set device data format");
|
||||||
|
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(&dc, sizeof(dc));
|
||||||
|
dc.dwSize = sizeof(dc);
|
||||||
|
|
||||||
|
if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to query device capabilities");
|
||||||
|
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(&dipd, sizeof(dipd));
|
||||||
|
dipd.diph.dwSize = sizeof(dipd);
|
||||||
|
dipd.diph.dwHeaderSize = sizeof(dipd.diph);
|
||||||
|
dipd.diph.dwHow = DIPH_DEVICE;
|
||||||
|
dipd.dwData = DIPROPAXISMODE_ABS;
|
||||||
|
|
||||||
|
if (FAILED(IDirectInputDevice8_SetProperty(device,
|
||||||
|
DIPROP_AXISMODE,
|
||||||
|
&dipd.diph)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to set device axis mode");
|
||||||
|
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
data.device = device;
|
||||||
|
data.objects = calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs,
|
||||||
|
sizeof(_GLFWjoyobjectWin32));
|
||||||
|
|
||||||
|
if (FAILED(IDirectInputDevice8_EnumObjects(device,
|
||||||
|
deviceObjectCallback,
|
||||||
|
&data,
|
||||||
|
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to enumerate device objects");
|
||||||
|
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
free(data.objects);
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(data.objects, data.objectCount,
|
||||||
|
sizeof(_GLFWjoyobjectWin32),
|
||||||
|
compareJoystickObjects);
|
||||||
|
|
||||||
|
if (!WideCharToMultiByte(CP_UTF8, 0,
|
||||||
|
di->tszInstanceName, -1,
|
||||||
|
name, sizeof(name),
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert joystick name to UTF-8");
|
||||||
|
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
free(data.objects);
|
||||||
|
return DIENUM_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||||
|
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
|
||||||
|
{
|
||||||
|
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
|
||||||
|
(uint8_t) di->guidProduct.Data1,
|
||||||
|
(uint8_t) (di->guidProduct.Data1 >> 8),
|
||||||
|
(uint8_t) (di->guidProduct.Data1 >> 16),
|
||||||
|
(uint8_t) (di->guidProduct.Data1 >> 24));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||||
|
name[0], name[1], name[2], name[3],
|
||||||
|
name[4], name[5], name[6], name[7],
|
||||||
|
name[8], name[9], name[10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
js = _glfwAllocJoystick(name, guid,
|
||||||
|
data.axisCount + data.sliderCount,
|
||||||
|
data.buttonCount,
|
||||||
|
data.povCount);
|
||||||
|
if (!js)
|
||||||
|
{
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
free(data.objects);
|
||||||
|
return DIENUM_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
js->win32.device = device;
|
||||||
|
js->win32.guid = di->guidInstance;
|
||||||
|
js->win32.objects = data.objects;
|
||||||
|
js->win32.objectCount = data.objectCount;
|
||||||
|
|
||||||
|
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialize joystick interface
|
||||||
|
//
|
||||||
|
void _glfwInitJoysticksWin32(void)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.dinput8.instance)
|
||||||
|
{
|
||||||
|
if (FAILED(DirectInput8Create(_glfw.win32.instance,
|
||||||
|
DIRECTINPUT_VERSION,
|
||||||
|
&IID_IDirectInput8W,
|
||||||
|
(void**) &_glfw.win32.dinput8.api,
|
||||||
|
NULL)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to create interface");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwDetectJoystickConnectionWin32();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close all opened joystick handles
|
||||||
|
//
|
||||||
|
void _glfwTerminateJoysticksWin32(void)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
closeJoystick(_glfw.joysticks + jid);
|
||||||
|
|
||||||
|
if (_glfw.win32.dinput8.api)
|
||||||
|
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks for new joysticks after DBT_DEVICEARRIVAL
|
||||||
|
//
|
||||||
|
void _glfwDetectJoystickConnectionWin32(void)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.xinput.instance)
|
||||||
|
{
|
||||||
|
DWORD index;
|
||||||
|
|
||||||
|
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
char guid[33];
|
||||||
|
XINPUT_CAPABILITIES xic;
|
||||||
|
_GLFWjoystick* js;
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (_glfw.joysticks[jid].connected &&
|
||||||
|
_glfw.joysticks[jid].win32.device == NULL &&
|
||||||
|
_glfw.joysticks[jid].win32.index == index)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jid <= GLFW_JOYSTICK_LAST)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||||
|
sprintf(guid, "78696e707574%02x000000000000000000",
|
||||||
|
xic.SubType & 0xff);
|
||||||
|
|
||||||
|
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
|
||||||
|
if (!js)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
js->win32.index = index;
|
||||||
|
|
||||||
|
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.win32.dinput8.api)
|
||||||
|
{
|
||||||
|
if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
|
||||||
|
DI8DEVCLASS_GAMECTRL,
|
||||||
|
deviceCallback,
|
||||||
|
NULL,
|
||||||
|
DIEDFL_ALLDEVICES)))
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Failed to enumerate DirectInput8 devices");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
|
||||||
|
//
|
||||||
|
void _glfwDetectJoystickDisconnectionWin32(void)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||||
|
if (js->connected)
|
||||||
|
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||||
|
{
|
||||||
|
if (js->win32.device)
|
||||||
|
{
|
||||||
|
int i, ai = 0, bi = 0, pi = 0;
|
||||||
|
HRESULT result;
|
||||||
|
DIJOYSTATE state = {0};
|
||||||
|
|
||||||
|
IDirectInputDevice8_Poll(js->win32.device);
|
||||||
|
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
||||||
|
sizeof(state),
|
||||||
|
&state);
|
||||||
|
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
|
||||||
|
{
|
||||||
|
IDirectInputDevice8_Acquire(js->win32.device);
|
||||||
|
IDirectInputDevice8_Poll(js->win32.device);
|
||||||
|
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
||||||
|
sizeof(state),
|
||||||
|
&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
closeJoystick(js);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == _GLFW_POLL_PRESENCE)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < js->win32.objectCount; i++)
|
||||||
|
{
|
||||||
|
const void* data = (char*) &state + js->win32.objects[i].offset;
|
||||||
|
|
||||||
|
switch (js->win32.objects[i].type)
|
||||||
|
{
|
||||||
|
case _GLFW_TYPE_AXIS:
|
||||||
|
case _GLFW_TYPE_SLIDER:
|
||||||
|
{
|
||||||
|
const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
|
||||||
|
_glfwInputJoystickAxis(js, ai, value);
|
||||||
|
ai++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GLFW_TYPE_BUTTON:
|
||||||
|
{
|
||||||
|
const char value = (*((BYTE*) data) & 0x80) != 0;
|
||||||
|
_glfwInputJoystickButton(js, bi, value);
|
||||||
|
bi++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GLFW_TYPE_POV:
|
||||||
|
{
|
||||||
|
const int states[9] =
|
||||||
|
{
|
||||||
|
GLFW_HAT_UP,
|
||||||
|
GLFW_HAT_RIGHT_UP,
|
||||||
|
GLFW_HAT_RIGHT,
|
||||||
|
GLFW_HAT_RIGHT_DOWN,
|
||||||
|
GLFW_HAT_DOWN,
|
||||||
|
GLFW_HAT_LEFT_DOWN,
|
||||||
|
GLFW_HAT_LEFT,
|
||||||
|
GLFW_HAT_LEFT_UP,
|
||||||
|
GLFW_HAT_CENTERED
|
||||||
|
};
|
||||||
|
|
||||||
|
// Screams of horror are appropriate at this point
|
||||||
|
int stateIndex = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
||||||
|
if (stateIndex < 0 || stateIndex > 8)
|
||||||
|
stateIndex = 8;
|
||||||
|
|
||||||
|
_glfwInputJoystickHat(js, pi, states[stateIndex]);
|
||||||
|
pi++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i, dpad = 0;
|
||||||
|
DWORD result;
|
||||||
|
XINPUT_STATE xis;
|
||||||
|
const WORD buttons[10] =
|
||||||
|
{
|
||||||
|
XINPUT_GAMEPAD_A,
|
||||||
|
XINPUT_GAMEPAD_B,
|
||||||
|
XINPUT_GAMEPAD_X,
|
||||||
|
XINPUT_GAMEPAD_Y,
|
||||||
|
XINPUT_GAMEPAD_LEFT_SHOULDER,
|
||||||
|
XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
||||||
|
XINPUT_GAMEPAD_BACK,
|
||||||
|
XINPUT_GAMEPAD_START,
|
||||||
|
XINPUT_GAMEPAD_LEFT_THUMB,
|
||||||
|
XINPUT_GAMEPAD_RIGHT_THUMB
|
||||||
|
};
|
||||||
|
|
||||||
|
result = XInputGetState(js->win32.index, &xis);
|
||||||
|
if (result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (result == ERROR_DEVICE_NOT_CONNECTED)
|
||||||
|
closeJoystick(js);
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == _GLFW_POLL_PRESENCE)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
|
||||||
|
_glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
|
||||||
|
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
|
||||||
|
_glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
|
||||||
|
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
|
||||||
|
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
|
||||||
|
_glfwInputJoystickButton(js, i, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||||
|
dpad |= GLFW_HAT_UP;
|
||||||
|
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||||
|
dpad |= GLFW_HAT_RIGHT;
|
||||||
|
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||||
|
dpad |= GLFW_HAT_DOWN;
|
||||||
|
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||||
|
dpad |= GLFW_HAT_LEFT;
|
||||||
|
|
||||||
|
_glfwInputJoystickHat(js, 0, dpad);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||||
|
{
|
||||||
|
if (strcmp(guid + 20, "504944564944") == 0)
|
||||||
|
{
|
||||||
|
char original[33];
|
||||||
|
strncpy(original, guid, sizeof(original) - 1);
|
||||||
|
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||||
|
original, original + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
57
external/glfw-3.3.8/src/win32_joystick.h
vendored
Normal file
57
external/glfw-3.3.8/src/win32_joystick.h
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; }
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
|
||||||
|
#define GLFW_BUILD_WIN32_MAPPINGS
|
||||||
|
|
||||||
|
// Joystick element (axis, button or slider)
|
||||||
|
//
|
||||||
|
typedef struct _GLFWjoyobjectWin32
|
||||||
|
{
|
||||||
|
int offset;
|
||||||
|
int type;
|
||||||
|
} _GLFWjoyobjectWin32;
|
||||||
|
|
||||||
|
// Win32-specific per-joystick data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWjoystickWin32
|
||||||
|
{
|
||||||
|
_GLFWjoyobjectWin32* objects;
|
||||||
|
int objectCount;
|
||||||
|
IDirectInputDevice8W* device;
|
||||||
|
DWORD index;
|
||||||
|
GUID guid;
|
||||||
|
} _GLFWjoystickWin32;
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwInitJoysticksWin32(void);
|
||||||
|
void _glfwTerminateJoysticksWin32(void);
|
||||||
|
void _glfwDetectJoystickConnectionWin32(void);
|
||||||
|
void _glfwDetectJoystickDisconnectionWin32(void);
|
||||||
|
|
548
external/glfw-3.3.8/src/win32_monitor.c
vendored
Normal file
548
external/glfw-3.3.8/src/win32_monitor.c
vendored
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Callback for EnumDisplayMonitors in createMonitor
|
||||||
|
//
|
||||||
|
static BOOL CALLBACK monitorCallback(HMONITOR handle,
|
||||||
|
HDC dc,
|
||||||
|
RECT* rect,
|
||||||
|
LPARAM data)
|
||||||
|
{
|
||||||
|
MONITORINFOEXW mi;
|
||||||
|
ZeroMemory(&mi, sizeof(mi));
|
||||||
|
mi.cbSize = sizeof(mi);
|
||||||
|
|
||||||
|
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
|
||||||
|
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
|
||||||
|
monitor->win32.handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create monitor from an adapter and (optionally) a display
|
||||||
|
//
|
||||||
|
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
||||||
|
DISPLAY_DEVICEW* display)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
int widthMM, heightMM;
|
||||||
|
char* name;
|
||||||
|
HDC dc;
|
||||||
|
DEVMODEW dm;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
|
if (display)
|
||||||
|
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
|
||||||
|
else
|
||||||
|
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
|
||||||
|
|
||||||
|
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
|
||||||
|
|
||||||
|
if (IsWindows8Point1OrGreater())
|
||||||
|
{
|
||||||
|
widthMM = GetDeviceCaps(dc, HORZSIZE);
|
||||||
|
heightMM = GetDeviceCaps(dc, VERTSIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
|
||||||
|
heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteDC(dc);
|
||||||
|
|
||||||
|
monitor = _glfwAllocMonitor(name, widthMM, heightMM);
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
|
||||||
|
monitor->win32.modesPruned = GLFW_TRUE;
|
||||||
|
|
||||||
|
wcscpy(monitor->win32.adapterName, adapter->DeviceName);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0,
|
||||||
|
adapter->DeviceName, -1,
|
||||||
|
monitor->win32.publicAdapterName,
|
||||||
|
sizeof(monitor->win32.publicAdapterName),
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
if (display)
|
||||||
|
{
|
||||||
|
wcscpy(monitor->win32.displayName, display->DeviceName);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0,
|
||||||
|
display->DeviceName, -1,
|
||||||
|
monitor->win32.publicDisplayName,
|
||||||
|
sizeof(monitor->win32.publicDisplayName),
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.left = dm.dmPosition.x;
|
||||||
|
rect.top = dm.dmPosition.y;
|
||||||
|
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
|
||||||
|
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
|
||||||
|
|
||||||
|
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsWin32(void)
|
||||||
|
{
|
||||||
|
int i, disconnectedCount;
|
||||||
|
_GLFWmonitor** disconnected = NULL;
|
||||||
|
DWORD adapterIndex, displayIndex;
|
||||||
|
DISPLAY_DEVICEW adapter, display;
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
|
||||||
|
disconnectedCount = _glfw.monitorCount;
|
||||||
|
if (disconnectedCount)
|
||||||
|
{
|
||||||
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
|
memcpy(disconnected,
|
||||||
|
_glfw.monitors,
|
||||||
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (adapterIndex = 0; ; adapterIndex++)
|
||||||
|
{
|
||||||
|
int type = _GLFW_INSERT_LAST;
|
||||||
|
|
||||||
|
ZeroMemory(&adapter, sizeof(adapter));
|
||||||
|
adapter.cb = sizeof(adapter);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||||
|
type = _GLFW_INSERT_FIRST;
|
||||||
|
|
||||||
|
for (displayIndex = 0; ; displayIndex++)
|
||||||
|
{
|
||||||
|
ZeroMemory(&display, sizeof(display));
|
||||||
|
display.cb = sizeof(display);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i] &&
|
||||||
|
wcscmp(disconnected[i]->win32.displayName,
|
||||||
|
display.DeviceName) == 0)
|
||||||
|
{
|
||||||
|
disconnected[i] = NULL;
|
||||||
|
// handle may have changed, update
|
||||||
|
EnumDisplayMonitors(NULL, NULL, monitorCallback, (LPARAM) _glfw.monitors[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < disconnectedCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
monitor = createMonitor(&adapter, &display);
|
||||||
|
if (!monitor)
|
||||||
|
{
|
||||||
|
free(disconnected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||||
|
|
||||||
|
type = _GLFW_INSERT_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: If an active adapter does not have any display devices
|
||||||
|
// (as sometimes happens), add it directly as a monitor
|
||||||
|
if (displayIndex == 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i] &&
|
||||||
|
wcscmp(disconnected[i]->win32.adapterName,
|
||||||
|
adapter.DeviceName) == 0)
|
||||||
|
{
|
||||||
|
disconnected[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < disconnectedCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
monitor = createMonitor(&adapter, NULL);
|
||||||
|
if (!monitor)
|
||||||
|
{
|
||||||
|
free(disconnected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i])
|
||||||
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the current video mode
|
||||||
|
//
|
||||||
|
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
|
{
|
||||||
|
GLFWvidmode current;
|
||||||
|
const GLFWvidmode* best;
|
||||||
|
DEVMODEW dm;
|
||||||
|
LONG result;
|
||||||
|
|
||||||
|
best = _glfwChooseVideoMode(monitor, desired);
|
||||||
|
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||||
|
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
|
||||||
|
DM_DISPLAYFREQUENCY;
|
||||||
|
dm.dmPelsWidth = best->width;
|
||||||
|
dm.dmPelsHeight = best->height;
|
||||||
|
dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
|
||||||
|
dm.dmDisplayFrequency = best->refreshRate;
|
||||||
|
|
||||||
|
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
||||||
|
dm.dmBitsPerPel = 32;
|
||||||
|
|
||||||
|
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
|
&dm,
|
||||||
|
NULL,
|
||||||
|
CDS_FULLSCREEN,
|
||||||
|
NULL);
|
||||||
|
if (result == DISP_CHANGE_SUCCESSFUL)
|
||||||
|
monitor->win32.modeChanged = GLFW_TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char* description = "Unknown error";
|
||||||
|
|
||||||
|
if (result == DISP_CHANGE_BADDUALVIEW)
|
||||||
|
description = "The system uses DualView";
|
||||||
|
else if (result == DISP_CHANGE_BADFLAGS)
|
||||||
|
description = "Invalid flags";
|
||||||
|
else if (result == DISP_CHANGE_BADMODE)
|
||||||
|
description = "Graphics mode not supported";
|
||||||
|
else if (result == DISP_CHANGE_BADPARAM)
|
||||||
|
description = "Invalid parameter";
|
||||||
|
else if (result == DISP_CHANGE_FAILED)
|
||||||
|
description = "Graphics mode failed";
|
||||||
|
else if (result == DISP_CHANGE_NOTUPDATED)
|
||||||
|
description = "Failed to write to registry";
|
||||||
|
else if (result == DISP_CHANGE_RESTART)
|
||||||
|
description = "Computer restart required";
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to set video mode: %s",
|
||||||
|
description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the previously saved (original) video mode
|
||||||
|
//
|
||||||
|
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
if (monitor->win32.modeChanged)
|
||||||
|
{
|
||||||
|
ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
|
NULL, NULL, CDS_FULLSCREEN, NULL);
|
||||||
|
monitor->win32.modeChanged = GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
UINT xdpi, ydpi;
|
||||||
|
|
||||||
|
if (xscale)
|
||||||
|
*xscale = 0.f;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = 0.f;
|
||||||
|
|
||||||
|
if (IsWindows8Point1OrGreater())
|
||||||
|
{
|
||||||
|
if (GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query monitor DPI");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const HDC dc = GetDC(NULL);
|
||||||
|
xdpi = GetDeviceCaps(dc, LOGPIXELSX);
|
||||||
|
ydpi = GetDeviceCaps(dc, LOGPIXELSY);
|
||||||
|
ReleaseDC(NULL, dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xscale)
|
||||||
|
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
|
{
|
||||||
|
DEVMODEW dm;
|
||||||
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
|
||||||
|
EnumDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
|
ENUM_CURRENT_SETTINGS,
|
||||||
|
&dm,
|
||||||
|
EDS_ROTATEDMODE);
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = dm.dmPosition.x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = dm.dmPosition.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
_glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||||
|
int* xpos, int* ypos,
|
||||||
|
int* width, int* height)
|
||||||
|
{
|
||||||
|
MONITORINFO mi = { sizeof(mi) };
|
||||||
|
GetMonitorInfoW(monitor->win32.handle, &mi);
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = mi.rcWork.left;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = mi.rcWork.top;
|
||||||
|
if (width)
|
||||||
|
*width = mi.rcWork.right - mi.rcWork.left;
|
||||||
|
if (height)
|
||||||
|
*height = mi.rcWork.bottom - mi.rcWork.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||||
|
{
|
||||||
|
int modeIndex = 0, size = 0;
|
||||||
|
GLFWvidmode* result = NULL;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
GLFWvidmode mode;
|
||||||
|
DEVMODEW dm;
|
||||||
|
|
||||||
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
|
||||||
|
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
|
||||||
|
break;
|
||||||
|
|
||||||
|
modeIndex++;
|
||||||
|
|
||||||
|
// Skip modes with less than 15 BPP
|
||||||
|
if (dm.dmBitsPerPel < 15)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mode.width = dm.dmPelsWidth;
|
||||||
|
mode.height = dm.dmPelsHeight;
|
||||||
|
mode.refreshRate = dm.dmDisplayFrequency;
|
||||||
|
_glfwSplitBPP(dm.dmBitsPerPel,
|
||||||
|
&mode.redBits,
|
||||||
|
&mode.greenBits,
|
||||||
|
&mode.blueBits);
|
||||||
|
|
||||||
|
for (i = 0; i < *count; i++)
|
||||||
|
{
|
||||||
|
if (_glfwCompareVideoModes(result + i, &mode) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip duplicate modes
|
||||||
|
if (i < *count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (monitor->win32.modesPruned)
|
||||||
|
{
|
||||||
|
// Skip modes not supported by the connected displays
|
||||||
|
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
|
&dm,
|
||||||
|
NULL,
|
||||||
|
CDS_TEST,
|
||||||
|
NULL) != DISP_CHANGE_SUCCESSFUL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*count == size)
|
||||||
|
{
|
||||||
|
size += 128;
|
||||||
|
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
|
||||||
|
}
|
||||||
|
|
||||||
|
(*count)++;
|
||||||
|
result[*count - 1] = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*count)
|
||||||
|
{
|
||||||
|
// HACK: Report the current mode if no valid modes were found
|
||||||
|
result = calloc(1, sizeof(GLFWvidmode));
|
||||||
|
_glfwPlatformGetVideoMode(monitor, result);
|
||||||
|
*count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
|
{
|
||||||
|
DEVMODEW dm;
|
||||||
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
|
||||||
|
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
|
||||||
|
|
||||||
|
mode->width = dm.dmPelsWidth;
|
||||||
|
mode->height = dm.dmPelsHeight;
|
||||||
|
mode->refreshRate = dm.dmDisplayFrequency;
|
||||||
|
_glfwSplitBPP(dm.dmBitsPerPel,
|
||||||
|
&mode->redBits,
|
||||||
|
&mode->greenBits,
|
||||||
|
&mode->blueBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
HDC dc;
|
||||||
|
WORD values[3][256];
|
||||||
|
|
||||||
|
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||||
|
GetDeviceGammaRamp(dc, values);
|
||||||
|
DeleteDC(dc);
|
||||||
|
|
||||||
|
_glfwAllocGammaArrays(ramp, 256);
|
||||||
|
|
||||||
|
memcpy(ramp->red, values[0], sizeof(values[0]));
|
||||||
|
memcpy(ramp->green, values[1], sizeof(values[1]));
|
||||||
|
memcpy(ramp->blue, values[2], sizeof(values[2]));
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
HDC dc;
|
||||||
|
WORD values[3][256];
|
||||||
|
|
||||||
|
if (ramp->size != 256)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Gamma ramp size must be 256");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(values[0], ramp->red, sizeof(values[0]));
|
||||||
|
memcpy(values[1], ramp->green, sizeof(values[1]));
|
||||||
|
memcpy(values[2], ramp->blue, sizeof(values[2]));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
458
external/glfw-3.3.8/src/win32_platform.h
vendored
Normal file
458
external/glfw-3.3.8/src/win32_platform.h
vendored
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
// 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_KHR_debug 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
|
||||||
|
|
||||||
|
// GLFW uses OEM cursor resources
|
||||||
|
#define OEMRESOURCE
|
||||||
|
|
||||||
|
#include <wctype.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <dinput.h>
|
||||||
|
#include <xinput.h>
|
||||||
|
#include <dbt.h>
|
||||||
|
|
||||||
|
// 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_DWMCOLORIZATIONCOLORCHANGED
|
||||||
|
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
|
||||||
|
#endif
|
||||||
|
#ifndef WM_COPYGLOBALDATA
|
||||||
|
#define WM_COPYGLOBALDATA 0x0049
|
||||||
|
#endif
|
||||||
|
#ifndef WM_UNICHAR
|
||||||
|
#define WM_UNICHAR 0x0109
|
||||||
|
#endif
|
||||||
|
#ifndef UNICODE_NOCHAR
|
||||||
|
#define UNICODE_NOCHAR 0xFFFF
|
||||||
|
#endif
|
||||||
|
#ifndef WM_DPICHANGED
|
||||||
|
#define WM_DPICHANGED 0x02E0
|
||||||
|
#endif
|
||||||
|
#ifndef GET_XBUTTON_WPARAM
|
||||||
|
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
|
||||||
|
#endif
|
||||||
|
#ifndef EDS_ROTATEDMODE
|
||||||
|
#define EDS_ROTATEDMODE 0x00000004
|
||||||
|
#endif
|
||||||
|
#ifndef DISPLAY_DEVICE_ACTIVE
|
||||||
|
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN32_WINNT_WINBLUE
|
||||||
|
#define _WIN32_WINNT_WINBLUE 0x0603
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN32_WINNT_WIN8
|
||||||
|
#define _WIN32_WINNT_WIN8 0x0602
|
||||||
|
#endif
|
||||||
|
#ifndef WM_GETDPISCALEDSIZE
|
||||||
|
#define WM_GETDPISCALEDSIZE 0x02e4
|
||||||
|
#endif
|
||||||
|
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||||
|
#define USER_DEFAULT_SCREEN_DPI 96
|
||||||
|
#endif
|
||||||
|
#ifndef OCR_HAND
|
||||||
|
#define OCR_HAND 32649
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WINVER < 0x0601
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD cbSize;
|
||||||
|
DWORD ExtStatus;
|
||||||
|
} CHANGEFILTERSTRUCT;
|
||||||
|
#ifndef MSGFLT_ALLOW
|
||||||
|
#define MSGFLT_ALLOW 1
|
||||||
|
#endif
|
||||||
|
#endif /*Windows 7*/
|
||||||
|
|
||||||
|
#if WINVER < 0x0600
|
||||||
|
#define DWM_BB_ENABLE 0x00000001
|
||||||
|
#define DWM_BB_BLURREGION 0x00000002
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
BOOL fEnable;
|
||||||
|
HRGN hRgnBlur;
|
||||||
|
BOOL fTransitionOnMaximized;
|
||||||
|
} DWM_BLURBEHIND;
|
||||||
|
#else
|
||||||
|
#include <dwmapi.h>
|
||||||
|
#endif /*Windows Vista*/
|
||||||
|
|
||||||
|
#ifndef DPI_ENUMS_DECLARED
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PROCESS_DPI_UNAWARE = 0,
|
||||||
|
PROCESS_SYSTEM_DPI_AWARE = 1,
|
||||||
|
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||||
|
} PROCESS_DPI_AWARENESS;
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MDT_EFFECTIVE_DPI = 0,
|
||||||
|
MDT_ANGULAR_DPI = 1,
|
||||||
|
MDT_RAW_DPI = 2,
|
||||||
|
MDT_DEFAULT = MDT_EFFECTIVE_DPI
|
||||||
|
} MONITOR_DPI_TYPE;
|
||||||
|
#endif /*DPI_ENUMS_DECLARED*/
|
||||||
|
|
||||||
|
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||||
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
|
||||||
|
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
||||||
|
|
||||||
|
// Replacement for versionhelpers.h macros, as we cannot rely on the
|
||||||
|
// application having a correct embedded manifest
|
||||||
|
//
|
||||||
|
#define IsWindowsXPOrGreater() \
|
||||||
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WINXP), 0)
|
||||||
|
#define IsWindowsVistaOrGreater() \
|
||||||
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||||
|
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||||
|
#define IsWindows7OrGreater() \
|
||||||
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
||||||
|
#define IsWindows8OrGreater() \
|
||||||
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
||||||
|
#define IsWindows8Point1OrGreater() \
|
||||||
|
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
||||||
|
|
||||||
|
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
|
||||||
|
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
||||||
|
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
|
||||||
|
_glfwIsWindows10BuildOrGreaterWin32(15063)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// xinput.dll function pointer typedefs
|
||||||
|
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
|
||||||
|
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
||||||
|
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
|
||||||
|
#define XInputGetState _glfw.win32.xinput.GetState
|
||||||
|
|
||||||
|
// dinput8.dll function pointer typedefs
|
||||||
|
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
|
||||||
|
#define DirectInput8Create _glfw.win32.dinput8.Create
|
||||||
|
|
||||||
|
// user32.dll function pointer typedefs
|
||||||
|
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||||
|
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
||||||
|
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
||||||
|
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
|
||||||
|
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
||||||
|
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
||||||
|
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
|
||||||
|
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||||
|
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||||
|
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
||||||
|
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
||||||
|
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
||||||
|
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
||||||
|
#define GetSystemMetricsForDpi _glfw.win32.user32.GetSystemMetricsForDpi_
|
||||||
|
|
||||||
|
// dwmapi.dll function pointer typedefs
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
|
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
||||||
|
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
|
||||||
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
|
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
|
||||||
|
|
||||||
|
// shcore.dll function pointer typedefs
|
||||||
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
|
typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
|
||||||
|
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
|
||||||
|
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
|
||||||
|
|
||||||
|
// ntdll.dll function pointer typedefs
|
||||||
|
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
|
||||||
|
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
|
||||||
|
|
||||||
|
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkWin32SurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkWin32SurfaceCreateFlagsKHR flags;
|
||||||
|
HINSTANCE hinstance;
|
||||||
|
HWND hwnd;
|
||||||
|
} VkWin32SurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
|
||||||
|
|
||||||
|
#include "win32_joystick.h"
|
||||||
|
#include "wgl_context.h"
|
||||||
|
#include "egl_context.h"
|
||||||
|
#include "osmesa_context.h"
|
||||||
|
|
||||||
|
#if !defined(_GLFW_WNDCLASSNAME)
|
||||||
|
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) LoadLibraryA(name)
|
||||||
|
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||||
|
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||||
|
|
||||||
|
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
|
||||||
|
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
|
||||||
|
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
|
||||||
|
|
||||||
|
|
||||||
|
// Win32-specific per-window data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWwindowWin32
|
||||||
|
{
|
||||||
|
HWND handle;
|
||||||
|
HICON bigIcon;
|
||||||
|
HICON smallIcon;
|
||||||
|
|
||||||
|
GLFWbool cursorTracked;
|
||||||
|
GLFWbool frameAction;
|
||||||
|
GLFWbool iconified;
|
||||||
|
GLFWbool maximized;
|
||||||
|
// Whether to enable framebuffer transparency on DWM
|
||||||
|
GLFWbool transparent;
|
||||||
|
GLFWbool scaleToMonitor;
|
||||||
|
|
||||||
|
// Cached size used to filter out duplicate events
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
// The last received cursor position, regardless of source
|
||||||
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
// The last recevied high surrogate when decoding pairs of UTF-16 messages
|
||||||
|
WCHAR highSurrogate;
|
||||||
|
} _GLFWwindowWin32;
|
||||||
|
|
||||||
|
// Win32-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryWin32
|
||||||
|
{
|
||||||
|
HINSTANCE instance;
|
||||||
|
HWND helperWindowHandle;
|
||||||
|
HDEVNOTIFY deviceNotificationHandle;
|
||||||
|
DWORD foregroundLockTimeout;
|
||||||
|
int acquiredMonitorCount;
|
||||||
|
char* clipboardString;
|
||||||
|
short int keycodes[512];
|
||||||
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
|
// Where to place the cursor when re-enabled
|
||||||
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
|
// The window whose disabled cursor mode is active
|
||||||
|
_GLFWwindow* disabledCursorWindow;
|
||||||
|
RAWINPUT* rawInput;
|
||||||
|
int rawInputSize;
|
||||||
|
UINT mouseTrailSize;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_DirectInput8Create Create;
|
||||||
|
IDirectInput8W* api;
|
||||||
|
} dinput8;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_XInputGetCapabilities GetCapabilities;
|
||||||
|
PFN_XInputGetState GetState;
|
||||||
|
} xinput;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
||||||
|
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
||||||
|
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
|
||||||
|
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
||||||
|
PFN_GetDpiForWindow GetDpiForWindow_;
|
||||||
|
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
||||||
|
PFN_GetSystemMetricsForDpi GetSystemMetricsForDpi_;
|
||||||
|
} user32;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
||||||
|
PFN_DwmFlush Flush;
|
||||||
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
|
PFN_DwmGetColorizationColor GetColorizationColor;
|
||||||
|
} dwmapi;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
|
||||||
|
PFN_GetDpiForMonitor GetDpiForMonitor_;
|
||||||
|
} shcore;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
||||||
|
} ntdll;
|
||||||
|
} _GLFWlibraryWin32;
|
||||||
|
|
||||||
|
// Win32-specific per-monitor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmonitorWin32
|
||||||
|
{
|
||||||
|
HMONITOR handle;
|
||||||
|
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
||||||
|
WCHAR adapterName[32];
|
||||||
|
WCHAR displayName[32];
|
||||||
|
char publicAdapterName[32];
|
||||||
|
char publicDisplayName[32];
|
||||||
|
GLFWbool modesPruned;
|
||||||
|
GLFWbool modeChanged;
|
||||||
|
} _GLFWmonitorWin32;
|
||||||
|
|
||||||
|
// Win32-specific per-cursor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcursorWin32
|
||||||
|
{
|
||||||
|
HCURSOR handle;
|
||||||
|
} _GLFWcursorWin32;
|
||||||
|
|
||||||
|
// Win32-specific global timer data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWtimerWin32
|
||||||
|
{
|
||||||
|
uint64_t frequency;
|
||||||
|
} _GLFWtimerWin32;
|
||||||
|
|
||||||
|
// Win32-specific thread local storage data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWtlsWin32
|
||||||
|
{
|
||||||
|
GLFWbool allocated;
|
||||||
|
DWORD index;
|
||||||
|
} _GLFWtlsWin32;
|
||||||
|
|
||||||
|
// Win32-specific mutex data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmutexWin32
|
||||||
|
{
|
||||||
|
GLFWbool allocated;
|
||||||
|
CRITICAL_SECTION section;
|
||||||
|
} _GLFWmutexWin32;
|
||||||
|
|
||||||
|
|
||||||
|
GLFWbool _glfwRegisterWindowClassWin32(void);
|
||||||
|
void _glfwUnregisterWindowClassWin32(void);
|
||||||
|
|
||||||
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
||||||
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
||||||
|
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
||||||
|
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
|
||||||
|
void _glfwInputErrorWin32(int error, const char* description);
|
||||||
|
void _glfwUpdateKeyNamesWin32(void);
|
||||||
|
|
||||||
|
void _glfwInitTimerWin32(void);
|
||||||
|
|
||||||
|
void _glfwPollMonitorsWin32(void);
|
||||||
|
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
|
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
||||||
|
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
|
||||||
|
|
99
external/glfw-3.3.8/src/win32_thread.c
vendored
Normal file
99
external/glfw-3.3.8/src/win32_thread.c
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||||
|
{
|
||||||
|
assert(tls->win32.allocated == GLFW_FALSE);
|
||||||
|
|
||||||
|
tls->win32.index = TlsAlloc();
|
||||||
|
if (tls->win32.index == TLS_OUT_OF_INDEXES)
|
||||||
|
{
|
||||||
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to allocate TLS index");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tls->win32.allocated = GLFW_TRUE;
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||||
|
{
|
||||||
|
if (tls->win32.allocated)
|
||||||
|
TlsFree(tls->win32.index);
|
||||||
|
memset(tls, 0, sizeof(_GLFWtls));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
||||||
|
{
|
||||||
|
assert(tls->win32.allocated == GLFW_TRUE);
|
||||||
|
return TlsGetValue(tls->win32.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
||||||
|
{
|
||||||
|
assert(tls->win32.allocated == GLFW_TRUE);
|
||||||
|
TlsSetValue(tls->win32.index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
assert(mutex->win32.allocated == GLFW_FALSE);
|
||||||
|
InitializeCriticalSection(&mutex->win32.section);
|
||||||
|
return mutex->win32.allocated = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
if (mutex->win32.allocated)
|
||||||
|
DeleteCriticalSection(&mutex->win32.section);
|
||||||
|
memset(mutex, 0, sizeof(_GLFWmutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
assert(mutex->win32.allocated == GLFW_TRUE);
|
||||||
|
EnterCriticalSection(&mutex->win32.section);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
||||||
|
{
|
||||||
|
assert(mutex->win32.allocated == GLFW_TRUE);
|
||||||
|
LeaveCriticalSection(&mutex->win32.section);
|
||||||
|
}
|
||||||
|
|
60
external/glfw-3.3.8/src/win32_time.c
vendored
Normal file
60
external/glfw-3.3.8/src/win32_time.c
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Win32 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// Please use C89 style variable declarations in this file because VS 2010
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Initialise timer
|
||||||
|
//
|
||||||
|
void _glfwInitTimerWin32(void)
|
||||||
|
{
|
||||||
|
QueryPerformanceFrequency((LARGE_INTEGER*) &_glfw.timer.win32.frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerValue(void)
|
||||||
|
{
|
||||||
|
uint64_t value;
|
||||||
|
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||||
|
{
|
||||||
|
return _glfw.timer.win32.frequency;
|
||||||
|
}
|
||||||
|
|
2396
external/glfw-3.3.8/src/win32_window.c
vendored
Normal file
2396
external/glfw-3.3.8/src/win32_window.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1101
external/glfw-3.3.8/src/window.c
vendored
Normal file
1101
external/glfw-3.3.8/src/window.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
595
external/glfw-3.3.8/src/wl_init.c
vendored
Normal file
595
external/glfw-3.3.8/src/wl_init.c
vendored
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Wayland - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
|
||||||
|
static void wmBaseHandlePing(void* userData,
|
||||||
|
struct xdg_wm_base* wmBase,
|
||||||
|
uint32_t serial)
|
||||||
|
{
|
||||||
|
xdg_wm_base_pong(wmBase, serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdg_wm_base_listener wmBaseListener =
|
||||||
|
{
|
||||||
|
wmBaseHandlePing
|
||||||
|
};
|
||||||
|
|
||||||
|
static void registryHandleGlobal(void* userData,
|
||||||
|
struct wl_registry* registry,
|
||||||
|
uint32_t name,
|
||||||
|
const char* interface,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
if (strcmp(interface, "wl_compositor") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.compositorVersion = _glfw_min(3, version);
|
||||||
|
_glfw.wl.compositor =
|
||||||
|
wl_registry_bind(registry, name, &wl_compositor_interface,
|
||||||
|
_glfw.wl.compositorVersion);
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "wl_subcompositor") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.subcompositor =
|
||||||
|
wl_registry_bind(registry, name, &wl_subcompositor_interface, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "wl_shm") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.shm =
|
||||||
|
wl_registry_bind(registry, name, &wl_shm_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.seatVersion = _glfw_min(4, version);
|
||||||
|
_glfw.wl.seat =
|
||||||
|
wl_registry_bind(registry, name, &wl_seat_interface,
|
||||||
|
_glfw.wl.seatVersion);
|
||||||
|
_glfwAddSeatListenerWayland(_glfw.wl.seat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "wl_data_device_manager") == 0)
|
||||||
|
{
|
||||||
|
if (!_glfw.wl.dataDeviceManager)
|
||||||
|
{
|
||||||
|
_glfw.wl.dataDeviceManager =
|
||||||
|
wl_registry_bind(registry, name,
|
||||||
|
&wl_data_device_manager_interface, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "xdg_wm_base") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.wmBase =
|
||||||
|
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
||||||
|
xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL);
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.decorationManager =
|
||||||
|
wl_registry_bind(registry, name,
|
||||||
|
&zxdg_decoration_manager_v1_interface,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "wp_viewporter") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.viewporter =
|
||||||
|
wl_registry_bind(registry, name, &wp_viewporter_interface, 1);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
|
||||||
|
{
|
||||||
|
_glfw.wl.idleInhibitManager =
|
||||||
|
wl_registry_bind(registry, name,
|
||||||
|
&zwp_idle_inhibit_manager_v1_interface,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registryHandleGlobalRemove(void* userData,
|
||||||
|
struct wl_registry* registry,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.monitorCount; ++i)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = _glfw.monitors[i];
|
||||||
|
if (monitor->wl.name == name)
|
||||||
|
{
|
||||||
|
_glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct wl_registry_listener registryListener =
|
||||||
|
{
|
||||||
|
registryHandleGlobal,
|
||||||
|
registryHandleGlobalRemove
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create key code translation tables
|
||||||
|
//
|
||||||
|
static void createKeyTables(void)
|
||||||
|
{
|
||||||
|
int scancode;
|
||||||
|
|
||||||
|
memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes));
|
||||||
|
memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));
|
||||||
|
|
||||||
|
_glfw.wl.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT;
|
||||||
|
_glfw.wl.keycodes[KEY_1] = GLFW_KEY_1;
|
||||||
|
_glfw.wl.keycodes[KEY_2] = GLFW_KEY_2;
|
||||||
|
_glfw.wl.keycodes[KEY_3] = GLFW_KEY_3;
|
||||||
|
_glfw.wl.keycodes[KEY_4] = GLFW_KEY_4;
|
||||||
|
_glfw.wl.keycodes[KEY_5] = GLFW_KEY_5;
|
||||||
|
_glfw.wl.keycodes[KEY_6] = GLFW_KEY_6;
|
||||||
|
_glfw.wl.keycodes[KEY_7] = GLFW_KEY_7;
|
||||||
|
_glfw.wl.keycodes[KEY_8] = GLFW_KEY_8;
|
||||||
|
_glfw.wl.keycodes[KEY_9] = GLFW_KEY_9;
|
||||||
|
_glfw.wl.keycodes[KEY_0] = GLFW_KEY_0;
|
||||||
|
_glfw.wl.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
|
||||||
|
_glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
|
||||||
|
_glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
|
||||||
|
_glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q;
|
||||||
|
_glfw.wl.keycodes[KEY_W] = GLFW_KEY_W;
|
||||||
|
_glfw.wl.keycodes[KEY_E] = GLFW_KEY_E;
|
||||||
|
_glfw.wl.keycodes[KEY_R] = GLFW_KEY_R;
|
||||||
|
_glfw.wl.keycodes[KEY_T] = GLFW_KEY_T;
|
||||||
|
_glfw.wl.keycodes[KEY_Y] = GLFW_KEY_Y;
|
||||||
|
_glfw.wl.keycodes[KEY_U] = GLFW_KEY_U;
|
||||||
|
_glfw.wl.keycodes[KEY_I] = GLFW_KEY_I;
|
||||||
|
_glfw.wl.keycodes[KEY_O] = GLFW_KEY_O;
|
||||||
|
_glfw.wl.keycodes[KEY_P] = GLFW_KEY_P;
|
||||||
|
_glfw.wl.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET;
|
||||||
|
_glfw.wl.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
|
||||||
|
_glfw.wl.keycodes[KEY_A] = GLFW_KEY_A;
|
||||||
|
_glfw.wl.keycodes[KEY_S] = GLFW_KEY_S;
|
||||||
|
_glfw.wl.keycodes[KEY_D] = GLFW_KEY_D;
|
||||||
|
_glfw.wl.keycodes[KEY_F] = GLFW_KEY_F;
|
||||||
|
_glfw.wl.keycodes[KEY_G] = GLFW_KEY_G;
|
||||||
|
_glfw.wl.keycodes[KEY_H] = GLFW_KEY_H;
|
||||||
|
_glfw.wl.keycodes[KEY_J] = GLFW_KEY_J;
|
||||||
|
_glfw.wl.keycodes[KEY_K] = GLFW_KEY_K;
|
||||||
|
_glfw.wl.keycodes[KEY_L] = GLFW_KEY_L;
|
||||||
|
_glfw.wl.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON;
|
||||||
|
_glfw.wl.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
|
||||||
|
_glfw.wl.keycodes[KEY_Z] = GLFW_KEY_Z;
|
||||||
|
_glfw.wl.keycodes[KEY_X] = GLFW_KEY_X;
|
||||||
|
_glfw.wl.keycodes[KEY_C] = GLFW_KEY_C;
|
||||||
|
_glfw.wl.keycodes[KEY_V] = GLFW_KEY_V;
|
||||||
|
_glfw.wl.keycodes[KEY_B] = GLFW_KEY_B;
|
||||||
|
_glfw.wl.keycodes[KEY_N] = GLFW_KEY_N;
|
||||||
|
_glfw.wl.keycodes[KEY_M] = GLFW_KEY_M;
|
||||||
|
_glfw.wl.keycodes[KEY_COMMA] = GLFW_KEY_COMMA;
|
||||||
|
_glfw.wl.keycodes[KEY_DOT] = GLFW_KEY_PERIOD;
|
||||||
|
_glfw.wl.keycodes[KEY_SLASH] = GLFW_KEY_SLASH;
|
||||||
|
_glfw.wl.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH;
|
||||||
|
_glfw.wl.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE;
|
||||||
|
_glfw.wl.keycodes[KEY_TAB] = GLFW_KEY_TAB;
|
||||||
|
_glfw.wl.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT;
|
||||||
|
_glfw.wl.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
|
||||||
|
_glfw.wl.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL;
|
||||||
|
_glfw.wl.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
_glfw.wl.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT;
|
||||||
|
_glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
|
||||||
|
_glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
|
||||||
|
_glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
|
||||||
|
_glfw.wl.keycodes[KEY_COMPOSE] = GLFW_KEY_MENU;
|
||||||
|
_glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
|
||||||
|
_glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
|
||||||
|
_glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
|
||||||
|
_glfw.wl.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
|
||||||
|
_glfw.wl.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE;
|
||||||
|
_glfw.wl.keycodes[KEY_DELETE] = GLFW_KEY_DELETE;
|
||||||
|
_glfw.wl.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE;
|
||||||
|
_glfw.wl.keycodes[KEY_ENTER] = GLFW_KEY_ENTER;
|
||||||
|
_glfw.wl.keycodes[KEY_HOME] = GLFW_KEY_HOME;
|
||||||
|
_glfw.wl.keycodes[KEY_END] = GLFW_KEY_END;
|
||||||
|
_glfw.wl.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP;
|
||||||
|
_glfw.wl.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN;
|
||||||
|
_glfw.wl.keycodes[KEY_INSERT] = GLFW_KEY_INSERT;
|
||||||
|
_glfw.wl.keycodes[KEY_LEFT] = GLFW_KEY_LEFT;
|
||||||
|
_glfw.wl.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT;
|
||||||
|
_glfw.wl.keycodes[KEY_DOWN] = GLFW_KEY_DOWN;
|
||||||
|
_glfw.wl.keycodes[KEY_UP] = GLFW_KEY_UP;
|
||||||
|
_glfw.wl.keycodes[KEY_F1] = GLFW_KEY_F1;
|
||||||
|
_glfw.wl.keycodes[KEY_F2] = GLFW_KEY_F2;
|
||||||
|
_glfw.wl.keycodes[KEY_F3] = GLFW_KEY_F3;
|
||||||
|
_glfw.wl.keycodes[KEY_F4] = GLFW_KEY_F4;
|
||||||
|
_glfw.wl.keycodes[KEY_F5] = GLFW_KEY_F5;
|
||||||
|
_glfw.wl.keycodes[KEY_F6] = GLFW_KEY_F6;
|
||||||
|
_glfw.wl.keycodes[KEY_F7] = GLFW_KEY_F7;
|
||||||
|
_glfw.wl.keycodes[KEY_F8] = GLFW_KEY_F8;
|
||||||
|
_glfw.wl.keycodes[KEY_F9] = GLFW_KEY_F9;
|
||||||
|
_glfw.wl.keycodes[KEY_F10] = GLFW_KEY_F10;
|
||||||
|
_glfw.wl.keycodes[KEY_F11] = GLFW_KEY_F11;
|
||||||
|
_glfw.wl.keycodes[KEY_F12] = GLFW_KEY_F12;
|
||||||
|
_glfw.wl.keycodes[KEY_F13] = GLFW_KEY_F13;
|
||||||
|
_glfw.wl.keycodes[KEY_F14] = GLFW_KEY_F14;
|
||||||
|
_glfw.wl.keycodes[KEY_F15] = GLFW_KEY_F15;
|
||||||
|
_glfw.wl.keycodes[KEY_F16] = GLFW_KEY_F16;
|
||||||
|
_glfw.wl.keycodes[KEY_F17] = GLFW_KEY_F17;
|
||||||
|
_glfw.wl.keycodes[KEY_F18] = GLFW_KEY_F18;
|
||||||
|
_glfw.wl.keycodes[KEY_F19] = GLFW_KEY_F19;
|
||||||
|
_glfw.wl.keycodes[KEY_F20] = GLFW_KEY_F20;
|
||||||
|
_glfw.wl.keycodes[KEY_F21] = GLFW_KEY_F21;
|
||||||
|
_glfw.wl.keycodes[KEY_F22] = GLFW_KEY_F22;
|
||||||
|
_glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23;
|
||||||
|
_glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24;
|
||||||
|
_glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
|
||||||
|
_glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY;
|
||||||
|
_glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
|
||||||
|
_glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
|
||||||
|
_glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
|
||||||
|
_glfw.wl.keycodes[KEY_KP1] = GLFW_KEY_KP_1;
|
||||||
|
_glfw.wl.keycodes[KEY_KP2] = GLFW_KEY_KP_2;
|
||||||
|
_glfw.wl.keycodes[KEY_KP3] = GLFW_KEY_KP_3;
|
||||||
|
_glfw.wl.keycodes[KEY_KP4] = GLFW_KEY_KP_4;
|
||||||
|
_glfw.wl.keycodes[KEY_KP5] = GLFW_KEY_KP_5;
|
||||||
|
_glfw.wl.keycodes[KEY_KP6] = GLFW_KEY_KP_6;
|
||||||
|
_glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
|
||||||
|
_glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
|
||||||
|
_glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
|
||||||
|
_glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_DECIMAL;
|
||||||
|
_glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
|
||||||
|
_glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
|
||||||
|
_glfw.wl.keycodes[KEY_102ND] = GLFW_KEY_WORLD_2;
|
||||||
|
|
||||||
|
for (scancode = 0; scancode < 256; scancode++)
|
||||||
|
{
|
||||||
|
if (_glfw.wl.keycodes[scancode] > 0)
|
||||||
|
_glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int _glfwPlatformInit(void)
|
||||||
|
{
|
||||||
|
const char* cursorTheme;
|
||||||
|
const char* cursorSizeStr;
|
||||||
|
char* cursorSizeEnd;
|
||||||
|
long cursorSizeLong;
|
||||||
|
int cursorSize;
|
||||||
|
|
||||||
|
// These must be set before any failure checks
|
||||||
|
_glfw.wl.timerfd = -1;
|
||||||
|
_glfw.wl.cursorTimerfd = -1;
|
||||||
|
|
||||||
|
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
|
||||||
|
if (!_glfw.wl.cursor.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to load libwayland-cursor");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
|
||||||
|
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
|
||||||
|
_glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
|
||||||
|
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
|
||||||
|
_glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
|
||||||
|
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
|
||||||
|
_glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
|
||||||
|
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
|
||||||
|
|
||||||
|
_glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
|
||||||
|
if (!_glfw.wl.egl.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to load libwayland-egl");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
|
||||||
|
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
|
||||||
|
_glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
|
||||||
|
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
|
||||||
|
_glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
|
||||||
|
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");
|
||||||
|
|
||||||
|
_glfw.wl.xkb.handle = _glfw_dlopen("libxkbcommon.so.0");
|
||||||
|
if (!_glfw.wl.xkb.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to load libxkbcommon");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.xkb.context_new = (PFN_xkb_context_new)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_new");
|
||||||
|
_glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_unref");
|
||||||
|
_glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
|
||||||
|
_glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_unref");
|
||||||
|
_glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
|
||||||
|
_glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
|
||||||
|
_glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level");
|
||||||
|
_glfw.wl.xkb.state_new = (PFN_xkb_state_new)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_new");
|
||||||
|
_glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_unref");
|
||||||
|
_glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
|
||||||
|
_glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask");
|
||||||
|
_glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_layout");
|
||||||
|
_glfw.wl.xkb.state_mod_index_is_active = (PFN_xkb_state_mod_index_is_active)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_mod_index_is_active");
|
||||||
|
|
||||||
|
_glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
|
||||||
|
_glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
|
||||||
|
_glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_new");
|
||||||
|
_glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
|
||||||
|
_glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
|
||||||
|
_glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
|
||||||
|
_glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
|
||||||
|
_glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
|
||||||
|
|
||||||
|
_glfw.wl.display = wl_display_connect(NULL);
|
||||||
|
if (!_glfw.wl.display)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to connect to display");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||||
|
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||||
|
|
||||||
|
createKeyTables();
|
||||||
|
|
||||||
|
_glfw.wl.xkb.context = xkb_context_new(0);
|
||||||
|
if (!_glfw.wl.xkb.context)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to initialize xkb context");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync so we got all registry objects
|
||||||
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
|
||||||
|
// Sync so we got all initial output events
|
||||||
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
if (!_glfwInitJoysticksLinux())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
|
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
||||||
|
if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
||||||
|
_glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!_glfw.wl.wmBase)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to find xdg-shell in your compositor");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.pointer && _glfw.wl.shm)
|
||||||
|
{
|
||||||
|
cursorTheme = getenv("XCURSOR_THEME");
|
||||||
|
cursorSizeStr = getenv("XCURSOR_SIZE");
|
||||||
|
cursorSize = 32;
|
||||||
|
if (cursorSizeStr)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
|
||||||
|
if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
|
||||||
|
cursorSize = (int)cursorSizeLong;
|
||||||
|
}
|
||||||
|
_glfw.wl.cursorTheme =
|
||||||
|
wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
|
||||||
|
if (!_glfw.wl.cursorTheme)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to load default cursor theme");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
// If this happens to be NULL, we just fallback to the scale=1 version.
|
||||||
|
_glfw.wl.cursorThemeHiDPI =
|
||||||
|
wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
|
||||||
|
_glfw.wl.cursorSurface =
|
||||||
|
wl_compositor_create_surface(_glfw.wl.compositor);
|
||||||
|
_glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
|
||||||
|
{
|
||||||
|
_glfw.wl.dataDevice =
|
||||||
|
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
||||||
|
_glfw.wl.seat);
|
||||||
|
_glfwAddDataDeviceListenerWayland(_glfw.wl.dataDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformTerminate(void)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
_glfwTerminateJoysticksLinux();
|
||||||
|
#endif
|
||||||
|
_glfwTerminateEGL();
|
||||||
|
_glfwTerminateOSMesa();
|
||||||
|
|
||||||
|
if (_glfw.wl.egl.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.wl.egl.handle);
|
||||||
|
_glfw.wl.egl.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.xkb.composeState)
|
||||||
|
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
||||||
|
if (_glfw.wl.xkb.keymap)
|
||||||
|
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||||
|
if (_glfw.wl.xkb.state)
|
||||||
|
xkb_state_unref(_glfw.wl.xkb.state);
|
||||||
|
if (_glfw.wl.xkb.context)
|
||||||
|
xkb_context_unref(_glfw.wl.xkb.context);
|
||||||
|
if (_glfw.wl.xkb.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.wl.xkb.handle);
|
||||||
|
_glfw.wl.xkb.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.cursorTheme)
|
||||||
|
wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
|
||||||
|
if (_glfw.wl.cursorThemeHiDPI)
|
||||||
|
wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
|
||||||
|
if (_glfw.wl.cursor.handle)
|
||||||
|
{
|
||||||
|
_glfw_dlclose(_glfw.wl.cursor.handle);
|
||||||
|
_glfw.wl.cursor.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
|
||||||
|
wl_data_offer_destroy(_glfw.wl.offers[i].offer);
|
||||||
|
|
||||||
|
free(_glfw.wl.offers);
|
||||||
|
|
||||||
|
if (_glfw.wl.cursorSurface)
|
||||||
|
wl_surface_destroy(_glfw.wl.cursorSurface);
|
||||||
|
if (_glfw.wl.subcompositor)
|
||||||
|
wl_subcompositor_destroy(_glfw.wl.subcompositor);
|
||||||
|
if (_glfw.wl.compositor)
|
||||||
|
wl_compositor_destroy(_glfw.wl.compositor);
|
||||||
|
if (_glfw.wl.shm)
|
||||||
|
wl_shm_destroy(_glfw.wl.shm);
|
||||||
|
if (_glfw.wl.viewporter)
|
||||||
|
wp_viewporter_destroy(_glfw.wl.viewporter);
|
||||||
|
if (_glfw.wl.decorationManager)
|
||||||
|
zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager);
|
||||||
|
if (_glfw.wl.wmBase)
|
||||||
|
xdg_wm_base_destroy(_glfw.wl.wmBase);
|
||||||
|
if (_glfw.wl.selectionOffer)
|
||||||
|
wl_data_offer_destroy(_glfw.wl.selectionOffer);
|
||||||
|
if (_glfw.wl.dragOffer)
|
||||||
|
wl_data_offer_destroy(_glfw.wl.dragOffer);
|
||||||
|
if (_glfw.wl.selectionSource)
|
||||||
|
wl_data_source_destroy(_glfw.wl.selectionSource);
|
||||||
|
if (_glfw.wl.dataDevice)
|
||||||
|
wl_data_device_destroy(_glfw.wl.dataDevice);
|
||||||
|
if (_glfw.wl.dataDeviceManager)
|
||||||
|
wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager);
|
||||||
|
if (_glfw.wl.pointer)
|
||||||
|
wl_pointer_destroy(_glfw.wl.pointer);
|
||||||
|
if (_glfw.wl.keyboard)
|
||||||
|
wl_keyboard_destroy(_glfw.wl.keyboard);
|
||||||
|
if (_glfw.wl.seat)
|
||||||
|
wl_seat_destroy(_glfw.wl.seat);
|
||||||
|
if (_glfw.wl.relativePointerManager)
|
||||||
|
zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
|
||||||
|
if (_glfw.wl.pointerConstraints)
|
||||||
|
zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints);
|
||||||
|
if (_glfw.wl.idleInhibitManager)
|
||||||
|
zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager);
|
||||||
|
if (_glfw.wl.registry)
|
||||||
|
wl_registry_destroy(_glfw.wl.registry);
|
||||||
|
if (_glfw.wl.display)
|
||||||
|
{
|
||||||
|
wl_display_flush(_glfw.wl.display);
|
||||||
|
wl_display_disconnect(_glfw.wl.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.wl.timerfd >= 0)
|
||||||
|
close(_glfw.wl.timerfd);
|
||||||
|
if (_glfw.wl.cursorTimerfd >= 0)
|
||||||
|
close(_glfw.wl.cursorTimerfd);
|
||||||
|
|
||||||
|
free(_glfw.wl.clipboardString);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
|
{
|
||||||
|
return _GLFW_VERSION_NUMBER " Wayland EGL OSMesa"
|
||||||
|
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||||
|
" clock_gettime"
|
||||||
|
#else
|
||||||
|
" gettimeofday"
|
||||||
|
#endif
|
||||||
|
" evdev"
|
||||||
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
|
" shared"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
}
|
271
external/glfw-3.3.8/src/wl_monitor.c
vendored
Normal file
271
external/glfw-3.3.8/src/wl_monitor.c
vendored
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Wayland - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void outputHandleGeometry(void* userData,
|
||||||
|
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 = userData;
|
||||||
|
|
||||||
|
monitor->wl.x = x;
|
||||||
|
monitor->wl.y = y;
|
||||||
|
monitor->widthMM = physicalWidth;
|
||||||
|
monitor->heightMM = physicalHeight;
|
||||||
|
|
||||||
|
if (strlen(monitor->name) == 0)
|
||||||
|
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outputHandleMode(void* userData,
|
||||||
|
struct wl_output* output,
|
||||||
|
uint32_t flags,
|
||||||
|
int32_t width,
|
||||||
|
int32_t height,
|
||||||
|
int32_t refresh)
|
||||||
|
{
|
||||||
|
struct _GLFWmonitor* monitor = userData;
|
||||||
|
GLFWvidmode mode;
|
||||||
|
|
||||||
|
mode.width = width;
|
||||||
|
mode.height = height;
|
||||||
|
mode.redBits = 8;
|
||||||
|
mode.greenBits = 8;
|
||||||
|
mode.blueBits = 8;
|
||||||
|
mode.refreshRate = (int) round(refresh / 1000.0);
|
||||||
|
|
||||||
|
monitor->modeCount++;
|
||||||
|
monitor->modes =
|
||||||
|
realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
|
||||||
|
monitor->modes[monitor->modeCount - 1] = mode;
|
||||||
|
|
||||||
|
if (flags & WL_OUTPUT_MODE_CURRENT)
|
||||||
|
monitor->wl.currentMode = monitor->modeCount - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outputHandleDone(void* userData, struct wl_output* output)
|
||||||
|
{
|
||||||
|
struct _GLFWmonitor* monitor = userData;
|
||||||
|
|
||||||
|
if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
|
||||||
|
{
|
||||||
|
// If Wayland does not provide a physical size, assume the default 96 DPI
|
||||||
|
const GLFWvidmode* mode = &monitor->modes[monitor->wl.currentMode];
|
||||||
|
monitor->widthMM = (int) (mode->width * 25.4f / 96.f);
|
||||||
|
monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
{
|
||||||
|
if (_glfw.monitors[i] == monitor)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outputHandleScale(void* userData,
|
||||||
|
struct wl_output* output,
|
||||||
|
int32_t factor)
|
||||||
|
{
|
||||||
|
struct _GLFWmonitor* monitor = userData;
|
||||||
|
|
||||||
|
monitor->wl.scale = factor;
|
||||||
|
|
||||||
|
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < window->wl.monitorsCount; i++)
|
||||||
|
{
|
||||||
|
if (window->wl.monitors[i] == monitor)
|
||||||
|
{
|
||||||
|
_glfwUpdateContentScaleWayland(window);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
||||||
|
|
||||||
|
void outputHandleName(void* userData, struct wl_output* wl_output, const char* name)
|
||||||
|
{
|
||||||
|
struct _GLFWmonitor* monitor = userData;
|
||||||
|
|
||||||
|
strncpy(monitor->name, name, sizeof(monitor->name) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputHandleDescription(void* userData,
|
||||||
|
struct wl_output* wl_output,
|
||||||
|
const char* description)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WL_OUTPUT_NAME_SINCE_VERSION
|
||||||
|
|
||||||
|
static const struct wl_output_listener outputListener =
|
||||||
|
{
|
||||||
|
outputHandleGeometry,
|
||||||
|
outputHandleMode,
|
||||||
|
outputHandleDone,
|
||||||
|
outputHandleScale,
|
||||||
|
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
||||||
|
outputHandleName,
|
||||||
|
outputHandleDescription,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
||||||
|
{
|
||||||
|
if (version < 2)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Unsupported output interface version");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
||||||
|
version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
|
||||||
|
#else
|
||||||
|
version = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
|
||||||
|
name,
|
||||||
|
&wl_output_interface,
|
||||||
|
version);
|
||||||
|
if (!output)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The actual name of this output will be set in the geometry handler
|
||||||
|
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
|
||||||
|
monitor->wl.scale = 1;
|
||||||
|
monitor->wl.output = output;
|
||||||
|
monitor->wl.name = name;
|
||||||
|
|
||||||
|
wl_output_add_listener(output, &outputListener, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
if (monitor->wl.output)
|
||||||
|
wl_output_destroy(monitor->wl.output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
|
{
|
||||||
|
if (xpos)
|
||||||
|
*xpos = monitor->wl.x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = monitor->wl.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
if (xscale)
|
||||||
|
*xscale = (float) monitor->wl.scale;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = (float) monitor->wl.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||||
|
int* xpos, int* ypos,
|
||||||
|
int* width, int* height)
|
||||||
|
{
|
||||||
|
if (xpos)
|
||||||
|
*xpos = monitor->wl.x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = monitor->wl.y;
|
||||||
|
if (width)
|
||||||
|
*width = monitor->modes[monitor->wl.currentMode].width;
|
||||||
|
if (height)
|
||||||
|
*height = monitor->modes[monitor->wl.currentMode].height;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||||
|
{
|
||||||
|
*found = monitor->modeCount;
|
||||||
|
return monitor->modes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
|
{
|
||||||
|
*mode = monitor->modes[monitor->wl.currentMode];
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Gamma ramp access is not available");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
|
||||||
|
const GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Gamma ramp access is not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW native API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return monitor->wl.output;
|
||||||
|
}
|
||||||
|
|
373
external/glfw-3.3.8/src/wl_platform.h
vendored
Normal file
373
external/glfw-3.3.8/src/wl_platform.h
vendored
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 Wayland - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkWaylandSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkWaylandSurfaceCreateFlagsKHR flags;
|
||||||
|
struct wl_display* display;
|
||||||
|
struct wl_surface* surface;
|
||||||
|
} VkWaylandSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
|
||||||
|
|
||||||
|
#include "posix_thread.h"
|
||||||
|
#include "posix_time.h"
|
||||||
|
#ifdef __linux__
|
||||||
|
#include "linux_joystick.h"
|
||||||
|
#else
|
||||||
|
#include "null_joystick.h"
|
||||||
|
#endif
|
||||||
|
#include "xkb_unicode.h"
|
||||||
|
#include "egl_context.h"
|
||||||
|
#include "osmesa_context.h"
|
||||||
|
|
||||||
|
#include "wayland-xdg-shell-client-protocol.h"
|
||||||
|
#include "wayland-xdg-decoration-client-protocol.h"
|
||||||
|
#include "wayland-viewporter-client-protocol.h"
|
||||||
|
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||||
|
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||||
|
#include "wayland-idle-inhibit-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.egl.window)
|
||||||
|
#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 struct { int dummyContext; }
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
|
||||||
|
|
||||||
|
struct wl_cursor_image {
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t hotspot_x;
|
||||||
|
uint32_t hotspot_y;
|
||||||
|
uint32_t delay;
|
||||||
|
};
|
||||||
|
struct wl_cursor {
|
||||||
|
unsigned int image_count;
|
||||||
|
struct wl_cursor_image** images;
|
||||||
|
char* name;
|
||||||
|
};
|
||||||
|
typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*);
|
||||||
|
typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*);
|
||||||
|
typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*);
|
||||||
|
typedef struct wl_buffer* (* PFN_wl_cursor_image_get_buffer)(struct wl_cursor_image*);
|
||||||
|
#define wl_cursor_theme_load _glfw.wl.cursor.theme_load
|
||||||
|
#define wl_cursor_theme_destroy _glfw.wl.cursor.theme_destroy
|
||||||
|
#define wl_cursor_theme_get_cursor _glfw.wl.cursor.theme_get_cursor
|
||||||
|
#define wl_cursor_image_get_buffer _glfw.wl.cursor.image_get_buffer
|
||||||
|
|
||||||
|
typedef struct wl_egl_window* (* PFN_wl_egl_window_create)(struct wl_surface*, int, int);
|
||||||
|
typedef void (* PFN_wl_egl_window_destroy)(struct wl_egl_window*);
|
||||||
|
typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int, int);
|
||||||
|
#define wl_egl_window_create _glfw.wl.egl.window_create
|
||||||
|
#define wl_egl_window_destroy _glfw.wl.egl.window_destroy
|
||||||
|
#define wl_egl_window_resize _glfw.wl.egl.window_resize
|
||||||
|
|
||||||
|
typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags);
|
||||||
|
typedef void (* PFN_xkb_context_unref)(struct xkb_context*);
|
||||||
|
typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
|
||||||
|
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
|
||||||
|
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
|
||||||
|
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
|
||||||
|
typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**);
|
||||||
|
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
|
||||||
|
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
|
||||||
|
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
|
||||||
|
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
|
||||||
|
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
|
||||||
|
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
|
||||||
|
#define xkb_context_new _glfw.wl.xkb.context_new
|
||||||
|
#define xkb_context_unref _glfw.wl.xkb.context_unref
|
||||||
|
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
|
||||||
|
#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
|
||||||
|
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
|
||||||
|
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
|
||||||
|
#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
|
||||||
|
#define xkb_state_new _glfw.wl.xkb.state_new
|
||||||
|
#define xkb_state_unref _glfw.wl.xkb.state_unref
|
||||||
|
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
|
||||||
|
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
|
||||||
|
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
|
||||||
|
#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
|
||||||
|
|
||||||
|
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
|
||||||
|
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
|
||||||
|
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
|
||||||
|
typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*);
|
||||||
|
typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t);
|
||||||
|
typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*);
|
||||||
|
typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*);
|
||||||
|
#define xkb_compose_table_new_from_locale _glfw.wl.xkb.compose_table_new_from_locale
|
||||||
|
#define xkb_compose_table_unref _glfw.wl.xkb.compose_table_unref
|
||||||
|
#define xkb_compose_state_new _glfw.wl.xkb.compose_state_new
|
||||||
|
#define xkb_compose_state_unref _glfw.wl.xkb.compose_state_unref
|
||||||
|
#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
|
||||||
|
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
|
||||||
|
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
|
||||||
|
|
||||||
|
typedef enum _GLFWdecorationSideWayland
|
||||||
|
{
|
||||||
|
mainWindow,
|
||||||
|
topDecoration,
|
||||||
|
leftDecoration,
|
||||||
|
rightDecoration,
|
||||||
|
bottomDecoration,
|
||||||
|
} _GLFWdecorationSideWayland;
|
||||||
|
|
||||||
|
typedef struct _GLFWdecorationWayland
|
||||||
|
{
|
||||||
|
struct wl_surface* surface;
|
||||||
|
struct wl_subsurface* subsurface;
|
||||||
|
struct wp_viewport* viewport;
|
||||||
|
} _GLFWdecorationWayland;
|
||||||
|
|
||||||
|
typedef struct _GLFWofferWayland
|
||||||
|
{
|
||||||
|
struct wl_data_offer* offer;
|
||||||
|
GLFWbool text_plain_utf8;
|
||||||
|
GLFWbool text_uri_list;
|
||||||
|
} _GLFWofferWayland;
|
||||||
|
|
||||||
|
// Wayland-specific per-window data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWwindowWayland
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
GLFWbool visible;
|
||||||
|
GLFWbool maximized;
|
||||||
|
GLFWbool activated;
|
||||||
|
GLFWbool fullscreen;
|
||||||
|
GLFWbool hovered;
|
||||||
|
GLFWbool transparent;
|
||||||
|
struct wl_surface* surface;
|
||||||
|
struct wl_callback* callback;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_egl_window* window;
|
||||||
|
} egl;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int width, height;
|
||||||
|
GLFWbool maximized;
|
||||||
|
GLFWbool iconified;
|
||||||
|
GLFWbool activated;
|
||||||
|
GLFWbool fullscreen;
|
||||||
|
} pending;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct xdg_surface* surface;
|
||||||
|
struct xdg_toplevel* toplevel;
|
||||||
|
struct zxdg_toplevel_decoration_v1* decoration;
|
||||||
|
uint32_t decorationMode;
|
||||||
|
} xdg;
|
||||||
|
|
||||||
|
_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;
|
||||||
|
|
||||||
|
struct zwp_idle_inhibitor_v1* idleInhibitor;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_buffer* buffer;
|
||||||
|
_GLFWdecorationWayland top, left, right, bottom;
|
||||||
|
_GLFWdecorationSideWayland focus;
|
||||||
|
} decorations;
|
||||||
|
} _GLFWwindowWayland;
|
||||||
|
|
||||||
|
// Wayland-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryWayland
|
||||||
|
{
|
||||||
|
struct wl_display* display;
|
||||||
|
struct wl_registry* registry;
|
||||||
|
struct wl_compositor* compositor;
|
||||||
|
struct wl_subcompositor* subcompositor;
|
||||||
|
struct wl_shm* shm;
|
||||||
|
struct wl_seat* seat;
|
||||||
|
struct wl_pointer* pointer;
|
||||||
|
struct wl_keyboard* keyboard;
|
||||||
|
struct wl_data_device_manager* dataDeviceManager;
|
||||||
|
struct wl_data_device* dataDevice;
|
||||||
|
struct xdg_wm_base* wmBase;
|
||||||
|
struct zxdg_decoration_manager_v1* decorationManager;
|
||||||
|
struct wp_viewporter* viewporter;
|
||||||
|
struct zwp_relative_pointer_manager_v1* relativePointerManager;
|
||||||
|
struct zwp_pointer_constraints_v1* pointerConstraints;
|
||||||
|
struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
|
||||||
|
|
||||||
|
_GLFWofferWayland* offers;
|
||||||
|
unsigned int offerCount;
|
||||||
|
|
||||||
|
struct wl_data_offer* selectionOffer;
|
||||||
|
struct wl_data_source* selectionSource;
|
||||||
|
|
||||||
|
struct wl_data_offer* dragOffer;
|
||||||
|
_GLFWwindow* dragFocus;
|
||||||
|
uint32_t dragSerial;
|
||||||
|
|
||||||
|
int compositorVersion;
|
||||||
|
int seatVersion;
|
||||||
|
|
||||||
|
struct wl_cursor_theme* cursorTheme;
|
||||||
|
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||||
|
struct wl_surface* cursorSurface;
|
||||||
|
const char* cursorPreviousName;
|
||||||
|
int cursorTimerfd;
|
||||||
|
uint32_t serial;
|
||||||
|
uint32_t pointerEnterSerial;
|
||||||
|
|
||||||
|
int32_t keyboardRepeatRate;
|
||||||
|
int32_t keyboardRepeatDelay;
|
||||||
|
int keyboardLastKey;
|
||||||
|
int keyboardLastScancode;
|
||||||
|
char* clipboardString;
|
||||||
|
int timerfd;
|
||||||
|
short int keycodes[256];
|
||||||
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
struct xkb_context* context;
|
||||||
|
struct xkb_keymap* keymap;
|
||||||
|
struct xkb_state* state;
|
||||||
|
struct xkb_compose_state* composeState;
|
||||||
|
|
||||||
|
xkb_mod_index_t controlIndex;
|
||||||
|
xkb_mod_index_t altIndex;
|
||||||
|
xkb_mod_index_t shiftIndex;
|
||||||
|
xkb_mod_index_t superIndex;
|
||||||
|
xkb_mod_index_t capsLockIndex;
|
||||||
|
xkb_mod_index_t numLockIndex;
|
||||||
|
unsigned int modifiers;
|
||||||
|
|
||||||
|
PFN_xkb_context_new context_new;
|
||||||
|
PFN_xkb_context_unref context_unref;
|
||||||
|
PFN_xkb_keymap_new_from_string keymap_new_from_string;
|
||||||
|
PFN_xkb_keymap_unref keymap_unref;
|
||||||
|
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
|
||||||
|
PFN_xkb_keymap_key_repeats keymap_key_repeats;
|
||||||
|
PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level;
|
||||||
|
PFN_xkb_state_new state_new;
|
||||||
|
PFN_xkb_state_unref state_unref;
|
||||||
|
PFN_xkb_state_key_get_syms state_key_get_syms;
|
||||||
|
PFN_xkb_state_update_mask state_update_mask;
|
||||||
|
PFN_xkb_state_key_get_layout state_key_get_layout;
|
||||||
|
PFN_xkb_state_mod_index_is_active state_mod_index_is_active;
|
||||||
|
|
||||||
|
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
|
||||||
|
PFN_xkb_compose_table_unref compose_table_unref;
|
||||||
|
PFN_xkb_compose_state_new compose_state_new;
|
||||||
|
PFN_xkb_compose_state_unref compose_state_unref;
|
||||||
|
PFN_xkb_compose_state_feed compose_state_feed;
|
||||||
|
PFN_xkb_compose_state_get_status compose_state_get_status;
|
||||||
|
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
|
||||||
|
} xkb;
|
||||||
|
|
||||||
|
_GLFWwindow* pointerFocus;
|
||||||
|
_GLFWwindow* keyboardFocus;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
|
||||||
|
PFN_wl_cursor_theme_load theme_load;
|
||||||
|
PFN_wl_cursor_theme_destroy theme_destroy;
|
||||||
|
PFN_wl_cursor_theme_get_cursor theme_get_cursor;
|
||||||
|
PFN_wl_cursor_image_get_buffer image_get_buffer;
|
||||||
|
} cursor;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
|
||||||
|
PFN_wl_egl_window_create window_create;
|
||||||
|
PFN_wl_egl_window_destroy window_destroy;
|
||||||
|
PFN_wl_egl_window_resize window_resize;
|
||||||
|
} egl;
|
||||||
|
} _GLFWlibraryWayland;
|
||||||
|
|
||||||
|
// Wayland-specific per-monitor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmonitorWayland
|
||||||
|
{
|
||||||
|
struct wl_output* output;
|
||||||
|
uint32_t name;
|
||||||
|
int currentMode;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int scale;
|
||||||
|
} _GLFWmonitorWayland;
|
||||||
|
|
||||||
|
// Wayland-specific per-cursor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcursorWayland
|
||||||
|
{
|
||||||
|
struct wl_cursor* cursor;
|
||||||
|
struct wl_cursor* cursorHiDPI;
|
||||||
|
struct wl_buffer* buffer;
|
||||||
|
int width, height;
|
||||||
|
int xhot, yhot;
|
||||||
|
int currentImage;
|
||||||
|
} _GLFWcursorWayland;
|
||||||
|
|
||||||
|
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||||
|
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
|
||||||
|
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode);
|
||||||
|
|
||||||
|
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
|
||||||
|
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);
|
||||||
|
|
2794
external/glfw-3.3.8/src/wl_window.c
vendored
Normal file
2794
external/glfw-3.3.8/src/wl_window.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1274
external/glfw-3.3.8/src/x11_init.c
vendored
Normal file
1274
external/glfw-3.3.8/src/x11_init.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
614
external/glfw-3.3.8/src/x11_monitor.c
vendored
Normal file
614
external/glfw-3.3.8/src/x11_monitor.c
vendored
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 X11 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Check whether the display mode should be included in enumeration
|
||||||
|
//
|
||||||
|
static GLFWbool modeIsGood(const XRRModeInfo* mi)
|
||||||
|
{
|
||||||
|
return (mi->modeFlags & RR_Interlace) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculates the refresh rate, in Hz, from the specified RandR mode info
|
||||||
|
//
|
||||||
|
static int calculateRefreshRate(const XRRModeInfo* mi)
|
||||||
|
{
|
||||||
|
if (mi->hTotal && mi->vTotal)
|
||||||
|
return (int) round((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)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sr->nmode; i++)
|
||||||
|
{
|
||||||
|
if (sr->modes[i].id == id)
|
||||||
|
return sr->modes + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert RandR mode info to GLFW video mode
|
||||||
|
//
|
||||||
|
static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
|
||||||
|
const XRRCrtcInfo* ci)
|
||||||
|
{
|
||||||
|
GLFWvidmode mode;
|
||||||
|
|
||||||
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
|
{
|
||||||
|
mode.width = mi->height;
|
||||||
|
mode.height = mi->width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode.width = mi->width;
|
||||||
|
mode.height = mi->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode.refreshRate = calculateRefreshRate(mi);
|
||||||
|
|
||||||
|
_glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen),
|
||||||
|
&mode.redBits, &mode.greenBits, &mode.blueBits);
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsX11(void)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
int disconnectedCount, screenCount = 0;
|
||||||
|
_GLFWmonitor** disconnected = NULL;
|
||||||
|
XineramaScreenInfo* screens = NULL;
|
||||||
|
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||||
|
_glfw.x11.root);
|
||||||
|
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
||||||
|
_glfw.x11.root);
|
||||||
|
|
||||||
|
if (_glfw.x11.xinerama.available)
|
||||||
|
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
||||||
|
|
||||||
|
disconnectedCount = _glfw.monitorCount;
|
||||||
|
if (disconnectedCount)
|
||||||
|
{
|
||||||
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
|
memcpy(disconnected,
|
||||||
|
_glfw.monitors,
|
||||||
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < sr->noutput; i++)
|
||||||
|
{
|
||||||
|
int j, type, widthMM, heightMM;
|
||||||
|
|
||||||
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||||
|
if (oi->connection != RR_Connected || oi->crtc == None)
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < disconnectedCount; j++)
|
||||||
|
{
|
||||||
|
if (disconnected[j] &&
|
||||||
|
disconnected[j]->x11.output == sr->outputs[i])
|
||||||
|
{
|
||||||
|
disconnected[j] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < disconnectedCount)
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||||
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
|
{
|
||||||
|
widthMM = oi->mm_height;
|
||||||
|
heightMM = oi->mm_width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widthMM = oi->mm_width;
|
||||||
|
heightMM = oi->mm_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widthMM <= 0 || heightMM <= 0)
|
||||||
|
{
|
||||||
|
// HACK: If RandR does not provide a physical size, assume the
|
||||||
|
// X11 default 96 DPI and calculate from the CRTC viewport
|
||||||
|
// NOTE: These members are affected by rotation, unlike the mode
|
||||||
|
// info and output info members
|
||||||
|
widthMM = (int) (ci->width * 25.4f / 96.f);
|
||||||
|
heightMM = (int) (ci->height * 25.4f / 96.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||||
|
monitor->x11.output = sr->outputs[i];
|
||||||
|
monitor->x11.crtc = oi->crtc;
|
||||||
|
|
||||||
|
for (j = 0; j < screenCount; j++)
|
||||||
|
{
|
||||||
|
if (screens[j].x_org == ci->x &&
|
||||||
|
screens[j].y_org == ci->y &&
|
||||||
|
screens[j].width == ci->width &&
|
||||||
|
screens[j].height == ci->height)
|
||||||
|
{
|
||||||
|
monitor->x11.index = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor->x11.output == primary)
|
||||||
|
type = _GLFW_INSERT_FIRST;
|
||||||
|
else
|
||||||
|
type = _GLFW_INSERT_LAST;
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||||
|
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources(sr);
|
||||||
|
|
||||||
|
if (screens)
|
||||||
|
XFree(screens);
|
||||||
|
|
||||||
|
for (int i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i])
|
||||||
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(disconnected);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
|
||||||
|
_glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM),
|
||||||
|
GLFW_CONNECTED,
|
||||||
|
_GLFW_INSERT_FIRST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the current video mode for the specified monitor
|
||||||
|
//
|
||||||
|
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
GLFWvidmode current;
|
||||||
|
RRMode native = None;
|
||||||
|
|
||||||
|
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||||
|
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||||
|
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XRRScreenResources* sr =
|
||||||
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||||
|
|
||||||
|
for (int 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the saved (original) video mode for the specified monitor
|
||||||
|
//
|
||||||
|
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
if (monitor->x11.oldMode == None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XRRScreenResources* sr =
|
||||||
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
|
XRRSetCrtcConfig(_glfw.x11.display,
|
||||||
|
sr, monitor->x11.crtc,
|
||||||
|
CurrentTime,
|
||||||
|
ci->x, ci->y,
|
||||||
|
monitor->x11.oldMode,
|
||||||
|
ci->rotation,
|
||||||
|
ci->outputs,
|
||||||
|
ci->noutput);
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
XRRFreeScreenResources(sr);
|
||||||
|
|
||||||
|
monitor->x11.oldMode = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
XRRScreenResources* sr =
|
||||||
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
|
if (ci)
|
||||||
|
{
|
||||||
|
if (xpos)
|
||||||
|
*xpos = ci->x;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = ci->y;
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources(sr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||||
|
float* xscale, float* yscale)
|
||||||
|
{
|
||||||
|
if (xscale)
|
||||||
|
*xscale = _glfw.x11.contentScaleX;
|
||||||
|
if (yscale)
|
||||||
|
*yscale = _glfw.x11.contentScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
|
||||||
|
{
|
||||||
|
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
|
||||||
|
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
XRRScreenResources* sr =
|
||||||
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
|
areaX = ci->x;
|
||||||
|
areaY = ci->y;
|
||||||
|
|
||||||
|
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||||
|
|
||||||
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
|
{
|
||||||
|
areaWidth = mi->height;
|
||||||
|
areaHeight = mi->width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
areaWidth = mi->width;
|
||||||
|
areaHeight = mi->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
XRRFreeScreenResources(sr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP)
|
||||||
|
{
|
||||||
|
Atom* extents = NULL;
|
||||||
|
Atom* desktop = NULL;
|
||||||
|
const unsigned long extentCount =
|
||||||
|
_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||||
|
_glfw.x11.NET_WORKAREA,
|
||||||
|
XA_CARDINAL,
|
||||||
|
(unsigned char**) &extents);
|
||||||
|
|
||||||
|
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||||
|
_glfw.x11.NET_CURRENT_DESKTOP,
|
||||||
|
XA_CARDINAL,
|
||||||
|
(unsigned char**) &desktop) > 0)
|
||||||
|
{
|
||||||
|
if (extentCount >= 4 && *desktop < extentCount / 4)
|
||||||
|
{
|
||||||
|
const int globalX = extents[*desktop * 4 + 0];
|
||||||
|
const int globalY = extents[*desktop * 4 + 1];
|
||||||
|
const int globalWidth = extents[*desktop * 4 + 2];
|
||||||
|
const int globalHeight = extents[*desktop * 4 + 3];
|
||||||
|
|
||||||
|
if (areaX < globalX)
|
||||||
|
{
|
||||||
|
areaWidth -= globalX - areaX;
|
||||||
|
areaX = globalX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areaY < globalY)
|
||||||
|
{
|
||||||
|
areaHeight -= globalY - areaY;
|
||||||
|
areaY = globalY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areaX + areaWidth > globalX + globalWidth)
|
||||||
|
areaWidth = globalX - areaX + globalWidth;
|
||||||
|
if (areaY + areaHeight > globalY + globalHeight)
|
||||||
|
areaHeight = globalY - areaY + globalHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extents)
|
||||||
|
XFree(extents);
|
||||||
|
if (desktop)
|
||||||
|
XFree(desktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xpos)
|
||||||
|
*xpos = areaX;
|
||||||
|
if (ypos)
|
||||||
|
*ypos = areaY;
|
||||||
|
if (width)
|
||||||
|
*width = areaWidth;
|
||||||
|
if (height)
|
||||||
|
*height = areaHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||||
|
{
|
||||||
|
GLFWvidmode* result;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
XRRScreenResources* sr =
|
||||||
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||||
|
|
||||||
|
result = calloc(oi->nmode, sizeof(GLFWvidmode));
|
||||||
|
|
||||||
|
for (int i = 0; i < oi->nmode; i++)
|
||||||
|
{
|
||||||
|
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||||
|
if (!modeIsGood(mi))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
|
||||||
|
int j;
|
||||||
|
|
||||||
|
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 =
|
||||||
|
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||||
|
|
||||||
|
if (ci)
|
||||||
|
{
|
||||||
|
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||||
|
if (mi) // mi can be NULL if the monitor has been disconnected
|
||||||
|
*mode = vidmodeFromModeInfo(mi, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _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);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Gamma ramp access not supported by server");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||||
|
{
|
||||||
|
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Gamma ramp size must match current ramp size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size);
|
||||||
|
|
||||||
|
memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short));
|
||||||
|
memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short));
|
||||||
|
memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short));
|
||||||
|
|
||||||
|
XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
|
||||||
|
XRRFreeGamma(gamma);
|
||||||
|
}
|
||||||
|
else if (_glfw.x11.vidmode.available)
|
||||||
|
{
|
||||||
|
XF86VidModeSetGammaRamp(_glfw.x11.display,
|
||||||
|
_glfw.x11.screen,
|
||||||
|
ramp->size,
|
||||||
|
(unsigned short*) ramp->red,
|
||||||
|
(unsigned short*) ramp->green,
|
||||||
|
(unsigned short*) ramp->blue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: Gamma ramp access not supported by server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// 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;
|
||||||
|
}
|
||||||
|
|
450
external/glfw-3.3.8/src/x11_platform.h
vendored
Normal file
450
external/glfw-3.3.8/src/x11_platform.h
vendored
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW 3.3 X11 - www.glfw.org
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
|
||||||
|
// The XRandR extension provides mode setting and gamma control
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
|
||||||
|
// The Xkb extension provides improved keyboard support
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
|
// The Xinerama extension provides legacy monitor indices
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
|
||||||
|
// The XInput extension provides raw mouse motion input
|
||||||
|
#include <X11/extensions/XInput2.h>
|
||||||
|
|
||||||
|
typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
|
||||||
|
typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
|
||||||
|
typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
|
||||||
|
typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*);
|
||||||
|
typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*);
|
||||||
|
typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc);
|
||||||
|
typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc);
|
||||||
|
typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc);
|
||||||
|
typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput);
|
||||||
|
typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window);
|
||||||
|
typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window);
|
||||||
|
typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*);
|
||||||
|
typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*);
|
||||||
|
typedef void (* PFN_XRRSelectInput)(Display*,Window,int);
|
||||||
|
typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int);
|
||||||
|
typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*);
|
||||||
|
typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
|
||||||
|
#define XRRAllocGamma _glfw.x11.randr.AllocGamma
|
||||||
|
#define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo
|
||||||
|
#define XRRFreeGamma _glfw.x11.randr.FreeGamma
|
||||||
|
#define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo
|
||||||
|
#define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources
|
||||||
|
#define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma
|
||||||
|
#define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize
|
||||||
|
#define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo
|
||||||
|
#define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo
|
||||||
|
#define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary
|
||||||
|
#define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
|
||||||
|
#define XRRQueryExtension _glfw.x11.randr.QueryExtension
|
||||||
|
#define XRRQueryVersion _glfw.x11.randr.QueryVersion
|
||||||
|
#define XRRSelectInput _glfw.x11.randr.SelectInput
|
||||||
|
#define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig
|
||||||
|
#define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma
|
||||||
|
#define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration
|
||||||
|
|
||||||
|
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
|
||||||
|
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
|
||||||
|
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
|
||||||
|
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
|
||||||
|
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
|
||||||
|
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
|
||||||
|
|
||||||
|
typedef Bool (* PFN_XineramaIsActive)(Display*);
|
||||||
|
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
|
||||||
|
typedef XineramaScreenInfo* (* PFN_XineramaQueryScreens)(Display*,int*);
|
||||||
|
#define XineramaIsActive _glfw.x11.xinerama.IsActive
|
||||||
|
#define XineramaQueryExtension _glfw.x11.xinerama.QueryExtension
|
||||||
|
#define XineramaQueryScreens _glfw.x11.xinerama.QueryScreens
|
||||||
|
|
||||||
|
typedef XID xcb_window_t;
|
||||||
|
typedef XID xcb_visualid_t;
|
||||||
|
typedef struct xcb_connection_t xcb_connection_t;
|
||||||
|
typedef xcb_connection_t* (* PFN_XGetXCBConnection)(Display*);
|
||||||
|
#define XGetXCBConnection _glfw.x11.x11xcb.GetXCBConnection
|
||||||
|
|
||||||
|
typedef Bool (* PFN_XF86VidModeQueryExtension)(Display*,int*,int*);
|
||||||
|
typedef Bool (* PFN_XF86VidModeGetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
|
||||||
|
typedef Bool (* PFN_XF86VidModeSetGammaRamp)(Display*,int,int,unsigned short*,unsigned short*,unsigned short*);
|
||||||
|
typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*);
|
||||||
|
#define XF86VidModeQueryExtension _glfw.x11.vidmode.QueryExtension
|
||||||
|
#define XF86VidModeGetGammaRamp _glfw.x11.vidmode.GetGammaRamp
|
||||||
|
#define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp
|
||||||
|
#define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize
|
||||||
|
|
||||||
|
typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*);
|
||||||
|
typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
|
||||||
|
#define XIQueryVersion _glfw.x11.xi.QueryVersion
|
||||||
|
#define XISelectEvents _glfw.x11.xi.SelectEvents
|
||||||
|
|
||||||
|
typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*);
|
||||||
|
typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*);
|
||||||
|
typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*);
|
||||||
|
#define XRenderQueryExtension _glfw.x11.xrender.QueryExtension
|
||||||
|
#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
|
||||||
|
#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
|
||||||
|
|
||||||
|
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||||
|
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
|
typedef struct VkXlibSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkXlibSurfaceCreateFlagsKHR flags;
|
||||||
|
Display* dpy;
|
||||||
|
Window window;
|
||||||
|
} VkXlibSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef struct VkXcbSurfaceCreateInfoKHR
|
||||||
|
{
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkXcbSurfaceCreateFlagsKHR flags;
|
||||||
|
xcb_connection_t* connection;
|
||||||
|
xcb_window_t window;
|
||||||
|
} VkXcbSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateXlibSurfaceKHR)(VkInstance,const VkXlibSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice,uint32_t,Display*,VisualID);
|
||||||
|
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
|
||||||
|
|
||||||
|
#include "posix_thread.h"
|
||||||
|
#include "posix_time.h"
|
||||||
|
#include "xkb_unicode.h"
|
||||||
|
#include "glx_context.h"
|
||||||
|
#include "egl_context.h"
|
||||||
|
#include "osmesa_context.h"
|
||||||
|
#if defined(__linux__)
|
||||||
|
#include "linux_joystick.h"
|
||||||
|
#else
|
||||||
|
#include "null_joystick.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
|
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle)
|
||||||
|
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
||||||
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11
|
||||||
|
|
||||||
|
|
||||||
|
// X11-specific per-window data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWwindowX11
|
||||||
|
{
|
||||||
|
Colormap colormap;
|
||||||
|
Window handle;
|
||||||
|
Window parent;
|
||||||
|
XIC ic;
|
||||||
|
|
||||||
|
GLFWbool overrideRedirect;
|
||||||
|
GLFWbool iconified;
|
||||||
|
GLFWbool maximized;
|
||||||
|
|
||||||
|
// Whether the visual supports framebuffer transparency
|
||||||
|
GLFWbool transparent;
|
||||||
|
|
||||||
|
// Cached position and size used to filter out duplicate events
|
||||||
|
int width, height;
|
||||||
|
int xpos, ypos;
|
||||||
|
|
||||||
|
// The last received cursor position, regardless of source
|
||||||
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
// The last position the cursor was warped to by GLFW
|
||||||
|
int warpCursorPosX, warpCursorPosY;
|
||||||
|
|
||||||
|
// The time of the last KeyPress event per keycode, for discarding
|
||||||
|
// duplicate key events generated for some keys by ibus
|
||||||
|
Time keyPressTimes[256];
|
||||||
|
} _GLFWwindowX11;
|
||||||
|
|
||||||
|
// X11-specific global data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWlibraryX11
|
||||||
|
{
|
||||||
|
Display* display;
|
||||||
|
int screen;
|
||||||
|
Window root;
|
||||||
|
|
||||||
|
// System content scale
|
||||||
|
float contentScaleX, contentScaleY;
|
||||||
|
// Helper window for IPC
|
||||||
|
Window helperWindowHandle;
|
||||||
|
// Invisible cursor for hidden cursor mode
|
||||||
|
Cursor hiddenCursorHandle;
|
||||||
|
// Context for mapping window XIDs to _GLFWwindow pointers
|
||||||
|
XContext context;
|
||||||
|
// XIM input method
|
||||||
|
XIM im;
|
||||||
|
// The previous X error handler, to be restored later
|
||||||
|
XErrorHandler errorHandler;
|
||||||
|
// Most recent error code received by X error handler
|
||||||
|
int errorCode;
|
||||||
|
// Primary selection string (while the primary selection is owned)
|
||||||
|
char* primarySelectionString;
|
||||||
|
// Clipboard string (while the selection is owned)
|
||||||
|
char* clipboardString;
|
||||||
|
// Key name string
|
||||||
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
|
// X11 keycode to GLFW key LUT
|
||||||
|
short int keycodes[256];
|
||||||
|
// GLFW key to X11 keycode LUT
|
||||||
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
// Where to place the cursor when re-enabled
|
||||||
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
|
// The window whose disabled cursor mode is active
|
||||||
|
_GLFWwindow* disabledCursorWindow;
|
||||||
|
int emptyEventPipe[2];
|
||||||
|
|
||||||
|
// Window manager atoms
|
||||||
|
Atom NET_SUPPORTED;
|
||||||
|
Atom NET_SUPPORTING_WM_CHECK;
|
||||||
|
Atom WM_PROTOCOLS;
|
||||||
|
Atom WM_STATE;
|
||||||
|
Atom WM_DELETE_WINDOW;
|
||||||
|
Atom NET_WM_NAME;
|
||||||
|
Atom NET_WM_ICON_NAME;
|
||||||
|
Atom NET_WM_ICON;
|
||||||
|
Atom NET_WM_PID;
|
||||||
|
Atom NET_WM_PING;
|
||||||
|
Atom NET_WM_WINDOW_TYPE;
|
||||||
|
Atom NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
|
Atom NET_WM_STATE;
|
||||||
|
Atom NET_WM_STATE_ABOVE;
|
||||||
|
Atom NET_WM_STATE_FULLSCREEN;
|
||||||
|
Atom NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
|
Atom NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
|
Atom NET_WM_STATE_DEMANDS_ATTENTION;
|
||||||
|
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||||
|
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||||
|
Atom NET_WM_WINDOW_OPACITY;
|
||||||
|
Atom NET_WM_CM_Sx;
|
||||||
|
Atom NET_WORKAREA;
|
||||||
|
Atom NET_CURRENT_DESKTOP;
|
||||||
|
Atom NET_ACTIVE_WINDOW;
|
||||||
|
Atom NET_FRAME_EXTENTS;
|
||||||
|
Atom NET_REQUEST_FRAME_EXTENTS;
|
||||||
|
Atom MOTIF_WM_HINTS;
|
||||||
|
|
||||||
|
// Xdnd (drag and drop) atoms
|
||||||
|
Atom XdndAware;
|
||||||
|
Atom XdndEnter;
|
||||||
|
Atom XdndPosition;
|
||||||
|
Atom XdndStatus;
|
||||||
|
Atom XdndActionCopy;
|
||||||
|
Atom XdndDrop;
|
||||||
|
Atom XdndFinished;
|
||||||
|
Atom XdndSelection;
|
||||||
|
Atom XdndTypeList;
|
||||||
|
Atom text_uri_list;
|
||||||
|
|
||||||
|
// Selection (clipboard) atoms
|
||||||
|
Atom TARGETS;
|
||||||
|
Atom MULTIPLE;
|
||||||
|
Atom INCR;
|
||||||
|
Atom CLIPBOARD;
|
||||||
|
Atom PRIMARY;
|
||||||
|
Atom CLIPBOARD_MANAGER;
|
||||||
|
Atom SAVE_TARGETS;
|
||||||
|
Atom NULL_;
|
||||||
|
Atom UTF8_STRING;
|
||||||
|
Atom COMPOUND_STRING;
|
||||||
|
Atom ATOM_PAIR;
|
||||||
|
Atom GLFW_SELECTION;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
GLFWbool gammaBroken;
|
||||||
|
GLFWbool monitorBroken;
|
||||||
|
PFN_XRRAllocGamma AllocGamma;
|
||||||
|
PFN_XRRFreeCrtcInfo FreeCrtcInfo;
|
||||||
|
PFN_XRRFreeGamma FreeGamma;
|
||||||
|
PFN_XRRFreeOutputInfo FreeOutputInfo;
|
||||||
|
PFN_XRRFreeScreenResources FreeScreenResources;
|
||||||
|
PFN_XRRGetCrtcGamma GetCrtcGamma;
|
||||||
|
PFN_XRRGetCrtcGammaSize GetCrtcGammaSize;
|
||||||
|
PFN_XRRGetCrtcInfo GetCrtcInfo;
|
||||||
|
PFN_XRRGetOutputInfo GetOutputInfo;
|
||||||
|
PFN_XRRGetOutputPrimary GetOutputPrimary;
|
||||||
|
PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent;
|
||||||
|
PFN_XRRQueryExtension QueryExtension;
|
||||||
|
PFN_XRRQueryVersion QueryVersion;
|
||||||
|
PFN_XRRSelectInput SelectInput;
|
||||||
|
PFN_XRRSetCrtcConfig SetCrtcConfig;
|
||||||
|
PFN_XRRSetCrtcGamma SetCrtcGamma;
|
||||||
|
PFN_XRRUpdateConfiguration UpdateConfiguration;
|
||||||
|
} randr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
GLFWbool detectable;
|
||||||
|
int majorOpcode;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
unsigned int group;
|
||||||
|
} xkb;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int count;
|
||||||
|
int timeout;
|
||||||
|
int interval;
|
||||||
|
int blanking;
|
||||||
|
int exposure;
|
||||||
|
} saver;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int version;
|
||||||
|
Window source;
|
||||||
|
Atom format;
|
||||||
|
} xdnd;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
PFN_XcursorImageCreate ImageCreate;
|
||||||
|
PFN_XcursorImageDestroy ImageDestroy;
|
||||||
|
PFN_XcursorImageLoadCursor ImageLoadCursor;
|
||||||
|
} xcursor;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
PFN_XineramaIsActive IsActive;
|
||||||
|
PFN_XineramaQueryExtension QueryExtension;
|
||||||
|
PFN_XineramaQueryScreens QueryScreens;
|
||||||
|
} xinerama;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
PFN_XGetXCBConnection GetXCBConnection;
|
||||||
|
} x11xcb;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
PFN_XF86VidModeQueryExtension QueryExtension;
|
||||||
|
PFN_XF86VidModeGetGammaRamp GetGammaRamp;
|
||||||
|
PFN_XF86VidModeSetGammaRamp SetGammaRamp;
|
||||||
|
PFN_XF86VidModeGetGammaRampSize GetGammaRampSize;
|
||||||
|
} vidmode;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int majorOpcode;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
PFN_XIQueryVersion QueryVersion;
|
||||||
|
PFN_XISelectEvents SelectEvents;
|
||||||
|
} xi;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
PFN_XRenderQueryExtension QueryExtension;
|
||||||
|
PFN_XRenderQueryVersion QueryVersion;
|
||||||
|
PFN_XRenderFindVisualFormat FindVisualFormat;
|
||||||
|
} xrender;
|
||||||
|
} _GLFWlibraryX11;
|
||||||
|
|
||||||
|
// X11-specific per-monitor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWmonitorX11
|
||||||
|
{
|
||||||
|
RROutput output;
|
||||||
|
RRCrtc crtc;
|
||||||
|
RRMode oldMode;
|
||||||
|
|
||||||
|
// Index of corresponding Xinerama screen,
|
||||||
|
// for EWMH full screen window placement
|
||||||
|
int index;
|
||||||
|
} _GLFWmonitorX11;
|
||||||
|
|
||||||
|
// X11-specific per-cursor data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWcursorX11
|
||||||
|
{
|
||||||
|
Cursor handle;
|
||||||
|
} _GLFWcursorX11;
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwPollMonitorsX11(void);
|
||||||
|
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
|
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot);
|
||||||
|
|
||||||
|
unsigned long _glfwGetWindowPropertyX11(Window window,
|
||||||
|
Atom property,
|
||||||
|
Atom type,
|
||||||
|
unsigned char** value);
|
||||||
|
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
|
||||||
|
|
||||||
|
void _glfwGrabErrorHandlerX11(void);
|
||||||
|
void _glfwReleaseErrorHandlerX11(void);
|
||||||
|
void _glfwInputErrorX11(int error, const char* message);
|
||||||
|
|
||||||
|
void _glfwPushSelectionToManagerX11(void);
|
||||||
|
|
3174
external/glfw-3.3.8/src/x11_window.c
vendored
Normal file
3174
external/glfw-3.3.8/src/x11_window.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user