Compare commits
No commits in common. "main" and "rust" have entirely different histories.
118
.gitignore
vendored
118
.gitignore
vendored
@ -1,117 +1 @@
|
|||||||
# Created by https://www.toptal.com/developers/gitignore/api/clion
|
/target
|
||||||
# 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
|
|
||||||
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
@ -1,2 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
<module type="CPP_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -1,9 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
<component name="MarkdownSettingsMigration">
|
||||||
<component name="CidrRootsConfiguration">
|
<option name="stateVersion" value="1" />
|
||||||
<libraryRoots>
|
|
||||||
<file path="$PROJECT_DIR$/external" />
|
|
||||||
</libraryRoots>
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,30 +0,0 @@
|
|||||||
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)
|
|
2435
Cargo.lock
generated
Normal file
2435
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
Cargo.toml
Normal file
30
Cargo.toml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
[package]
|
||||||
|
name = "mcalc"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
glium = "0.32.1"
|
||||||
|
imgui-glium-renderer = "0.11.0"
|
||||||
|
imgui-winit-support = "0.11.0"
|
||||||
|
rfd = "0.11.3"
|
||||||
|
serde_json = "1.0.96"
|
||||||
|
thousands = "0.2.0"
|
||||||
|
|
||||||
|
[dependencies.serde]
|
||||||
|
version = "1.0.160"
|
||||||
|
features = ["derive"]
|
||||||
|
|
||||||
|
[dependencies.lalrpop-util]
|
||||||
|
version = "0.19.12"
|
||||||
|
features = ["lexer"]
|
||||||
|
|
||||||
|
[dependencies.imgui]
|
||||||
|
version = "0.11.0"
|
||||||
|
features = ["docking", "tables-api"]
|
||||||
|
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
lalrpop = "0.19.12"
|
5
build.rs
Normal file
5
build.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extern crate lalrpop;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
lalrpop::process_root().unwrap();
|
||||||
|
}
|
32
external/CMakeLists.txt
vendored
32
external/CMakeLists.txt
vendored
@ -1,32 +0,0 @@
|
|||||||
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
311
external/glad/KHR/khrplatform.h
vendored
@ -1,311 +0,0 @@
|
|||||||
#ifndef __khrplatform_h_
|
|
||||||
#define __khrplatform_h_
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
|
||||||
**
|
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
** copy of this software and/or associated documentation files (the
|
|
||||||
** "Materials"), to deal in the Materials without restriction, including
|
|
||||||
** without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
** permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
** the following conditions:
|
|
||||||
**
|
|
||||||
** The above copyright notice and this permission notice shall be included
|
|
||||||
** in all copies or substantial portions of the Materials.
|
|
||||||
**
|
|
||||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Khronos platform-specific types and definitions.
|
|
||||||
*
|
|
||||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
|
||||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
|
||||||
* The last semantic modification to khrplatform.h was at commit ID:
|
|
||||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
|
||||||
*
|
|
||||||
* Adopters may modify this file to suit their platform. Adopters are
|
|
||||||
* encouraged to submit platform specific modifications to the Khronos
|
|
||||||
* group so that they can be included in future versions of this file.
|
|
||||||
* Please submit changes by filing pull requests or issues on
|
|
||||||
* the EGL Registry repository linked above.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* See the Implementer's Guidelines for information about where this file
|
|
||||||
* should be located on your system and for more details of its use:
|
|
||||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
|
||||||
*
|
|
||||||
* This file should be included as
|
|
||||||
* #include <KHR/khrplatform.h>
|
|
||||||
* by Khronos client API header files that use its types and defines.
|
|
||||||
*
|
|
||||||
* The types in khrplatform.h should only be used to define API-specific types.
|
|
||||||
*
|
|
||||||
* Types defined in khrplatform.h:
|
|
||||||
* khronos_int8_t signed 8 bit
|
|
||||||
* khronos_uint8_t unsigned 8 bit
|
|
||||||
* khronos_int16_t signed 16 bit
|
|
||||||
* khronos_uint16_t unsigned 16 bit
|
|
||||||
* khronos_int32_t signed 32 bit
|
|
||||||
* khronos_uint32_t unsigned 32 bit
|
|
||||||
* khronos_int64_t signed 64 bit
|
|
||||||
* khronos_uint64_t unsigned 64 bit
|
|
||||||
* khronos_intptr_t signed same number of bits as a pointer
|
|
||||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
|
||||||
* khronos_ssize_t signed size
|
|
||||||
* khronos_usize_t unsigned size
|
|
||||||
* khronos_float_t signed 32 bit floating point
|
|
||||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
|
||||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
|
||||||
* nanoseconds
|
|
||||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
|
||||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
|
||||||
* only be used as a base type when a client API's boolean type is
|
|
||||||
* an enum. Client APIs which use an integer or other type for
|
|
||||||
* booleans cannot use this as the base type for their boolean.
|
|
||||||
*
|
|
||||||
* Tokens defined in khrplatform.h:
|
|
||||||
*
|
|
||||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
|
||||||
*
|
|
||||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
|
||||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
|
||||||
*
|
|
||||||
* Calling convention macros defined in this file:
|
|
||||||
* KHRONOS_APICALL
|
|
||||||
* KHRONOS_APIENTRY
|
|
||||||
* KHRONOS_APIATTRIBUTES
|
|
||||||
*
|
|
||||||
* These may be used in function prototypes as:
|
|
||||||
*
|
|
||||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
|
||||||
* int arg1,
|
|
||||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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
2532
external/glad/glad.c
vendored
File diff suppressed because it is too large
Load Diff
5169
external/glad/glad/glad.h
vendored
5169
external/glad/glad/glad.h
vendored
File diff suppressed because it is too large
Load Diff
48
external/glfw-3.3.8/CMake/GenerateMappings.cmake
vendored
48
external/glfw-3.3.8/CMake/GenerateMappings.cmake
vendored
@ -1,48 +0,0 @@
|
|||||||
# 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}")
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
<?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>
|
|
@ -1,13 +0,0 @@
|
|||||||
# 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
13
external/glfw-3.3.8/CMake/i686-w64-mingw32.cmake
vendored
@ -1,13 +0,0 @@
|
|||||||
# 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)
|
|
@ -1,17 +0,0 @@
|
|||||||
# 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)
|
|
@ -1,18 +0,0 @@
|
|||||||
# 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 ()
|
|
@ -1,26 +0,0 @@
|
|||||||
find_package(PkgConfig)
|
|
||||||
|
|
||||||
pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION})
|
|
||||||
|
|
||||||
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols
|
|
||||||
OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR
|
|
||||||
RESULT_VARIABLE _pkgconfig_failed)
|
|
||||||
if (_pkgconfig_failed)
|
|
||||||
message(FATAL_ERROR "Missing wayland-protocols pkgdatadir")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}")
|
|
||||||
|
|
||||||
find_package_handle_standard_args(WaylandProtocols
|
|
||||||
FOUND_VAR
|
|
||||||
WaylandProtocols_FOUND
|
|
||||||
REQUIRED_VARS
|
|
||||||
WaylandProtocols_PKGDATADIR
|
|
||||||
VERSION_VAR
|
|
||||||
WaylandProtocols_VERSION
|
|
||||||
HANDLE_COMPONENTS
|
|
||||||
)
|
|
||||||
|
|
||||||
set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND})
|
|
||||||
set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR})
|
|
||||||
set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION})
|
|
@ -1,34 +0,0 @@
|
|||||||
# - Try to find XKBCommon
|
|
||||||
# Once done, this will define
|
|
||||||
#
|
|
||||||
# XKBCOMMON_FOUND - System has XKBCommon
|
|
||||||
# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories
|
|
||||||
# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon
|
|
||||||
# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
|
||||||
pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon)
|
|
||||||
set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER})
|
|
||||||
|
|
||||||
find_path(XKBCOMMON_INCLUDE_DIR
|
|
||||||
NAMES xkbcommon/xkbcommon.h
|
|
||||||
HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(XKBCOMMON_LIBRARY
|
|
||||||
NAMES xkbcommon
|
|
||||||
HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY})
|
|
||||||
set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS})
|
|
||||||
set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR})
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(XKBCommon DEFAULT_MSG
|
|
||||||
XKBCOMMON_LIBRARY
|
|
||||||
XKBCOMMON_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR)
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
# 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)
|
|
@ -1,13 +0,0 @@
|
|||||||
# 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
372
external/glfw-3.3.8/CMakeLists.txt
vendored
@ -1,372 +0,0 @@
|
|||||||
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
29
external/glfw-3.3.8/cmake_uninstall.cmake.in
vendored
@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
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
230
external/glfw-3.3.8/deps/getopt.c
vendored
@ -1,230 +0,0 @@
|
|||||||
/* 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
57
external/glfw-3.3.8/deps/getopt.h
vendored
@ -1,57 +0,0 @@
|
|||||||
/* 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
3840
external/glfw-3.3.8/deps/glad/gl.h
vendored
File diff suppressed because it is too large
Load Diff
282
external/glfw-3.3.8/deps/glad/khrplatform.h
vendored
282
external/glfw-3.3.8/deps/glad/khrplatform.h
vendored
@ -1,282 +0,0 @@
|
|||||||
#ifndef __khrplatform_h_
|
|
||||||
#define __khrplatform_h_
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
|
||||||
**
|
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
** copy of this software and/or associated documentation files (the
|
|
||||||
** "Materials"), to deal in the Materials without restriction, including
|
|
||||||
** without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
|
||||||
** permit persons to whom the Materials are furnished to do so, subject to
|
|
||||||
** the following conditions:
|
|
||||||
**
|
|
||||||
** The above copyright notice and this permission notice shall be included
|
|
||||||
** in all copies or substantial portions of the Materials.
|
|
||||||
**
|
|
||||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Khronos platform-specific types and definitions.
|
|
||||||
*
|
|
||||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
|
||||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
|
||||||
* The last semantic modification to khrplatform.h was at commit ID:
|
|
||||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
|
||||||
*
|
|
||||||
* Adopters may modify this file to suit their platform. Adopters are
|
|
||||||
* encouraged to submit platform specific modifications to the Khronos
|
|
||||||
* group so that they can be included in future versions of this file.
|
|
||||||
* Please submit changes by filing pull requests or issues on
|
|
||||||
* the EGL Registry repository linked above.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* See the Implementer's Guidelines for information about where this file
|
|
||||||
* should be located on your system and for more details of its use:
|
|
||||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
|
||||||
*
|
|
||||||
* This file should be included as
|
|
||||||
* #include <KHR/khrplatform.h>
|
|
||||||
* by Khronos client API header files that use its types and defines.
|
|
||||||
*
|
|
||||||
* The types in khrplatform.h should only be used to define API-specific types.
|
|
||||||
*
|
|
||||||
* Types defined in khrplatform.h:
|
|
||||||
* khronos_int8_t signed 8 bit
|
|
||||||
* khronos_uint8_t unsigned 8 bit
|
|
||||||
* khronos_int16_t signed 16 bit
|
|
||||||
* khronos_uint16_t unsigned 16 bit
|
|
||||||
* khronos_int32_t signed 32 bit
|
|
||||||
* khronos_uint32_t unsigned 32 bit
|
|
||||||
* khronos_int64_t signed 64 bit
|
|
||||||
* khronos_uint64_t unsigned 64 bit
|
|
||||||
* khronos_intptr_t signed same number of bits as a pointer
|
|
||||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
|
||||||
* khronos_ssize_t signed size
|
|
||||||
* khronos_usize_t unsigned size
|
|
||||||
* khronos_float_t signed 32 bit floating point
|
|
||||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
|
||||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
|
||||||
* nanoseconds
|
|
||||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
|
||||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
|
||||||
* only be used as a base type when a client API's boolean type is
|
|
||||||
* an enum. Client APIs which use an integer or other type for
|
|
||||||
* booleans cannot use this as the base type for their boolean.
|
|
||||||
*
|
|
||||||
* Tokens defined in khrplatform.h:
|
|
||||||
*
|
|
||||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
|
||||||
*
|
|
||||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
|
||||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
|
||||||
*
|
|
||||||
* Calling convention macros defined in this file:
|
|
||||||
* KHRONOS_APICALL
|
|
||||||
* KHRONOS_APIENTRY
|
|
||||||
* KHRONOS_APIATTRIBUTES
|
|
||||||
*
|
|
||||||
* These may be used in function prototypes as:
|
|
||||||
*
|
|
||||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
|
||||||
* int arg1,
|
|
||||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APICALL
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This precedes the return type of the function in the function prototype.
|
|
||||||
*/
|
|
||||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
|
||||||
# define KHRONOS_APICALL __declspec(dllimport)
|
|
||||||
#elif defined (__SYMBIAN32__)
|
|
||||||
# define KHRONOS_APICALL IMPORT_C
|
|
||||||
#elif defined(__ANDROID__)
|
|
||||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
|
||||||
#else
|
|
||||||
# define KHRONOS_APICALL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APIENTRY
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This follows the return type of the function and precedes the function
|
|
||||||
* name in the function prototype.
|
|
||||||
*/
|
|
||||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
|
||||||
/* Win32 but not WinCE */
|
|
||||||
# define KHRONOS_APIENTRY __stdcall
|
|
||||||
#else
|
|
||||||
# define KHRONOS_APIENTRY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Definition of KHRONOS_APIATTRIBUTES
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
* This follows the closing parenthesis of the function prototype arguments.
|
|
||||||
*/
|
|
||||||
#if defined (__ARMCC_2__)
|
|
||||||
#define KHRONOS_APIATTRIBUTES __softfp
|
|
||||||
#else
|
|
||||||
#define KHRONOS_APIATTRIBUTES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* basic type definitions
|
|
||||||
*-----------------------------------------------------------------------*/
|
|
||||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using <stdint.h>
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(__VMS ) || defined(__sgi)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Using <inttypes.h>
|
|
||||||
*/
|
|
||||||
#include <inttypes.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Win32
|
|
||||||
*/
|
|
||||||
typedef __int32 khronos_int32_t;
|
|
||||||
typedef unsigned __int32 khronos_uint32_t;
|
|
||||||
typedef __int64 khronos_int64_t;
|
|
||||||
typedef unsigned __int64 khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif defined(__sun__) || defined(__digital__)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sun or Digital
|
|
||||||
*/
|
|
||||||
typedef int khronos_int32_t;
|
|
||||||
typedef unsigned int khronos_uint32_t;
|
|
||||||
#if defined(__arch64__) || defined(_LP64)
|
|
||||||
typedef long int khronos_int64_t;
|
|
||||||
typedef unsigned long int khronos_uint64_t;
|
|
||||||
#else
|
|
||||||
typedef long long int khronos_int64_t;
|
|
||||||
typedef unsigned long long int khronos_uint64_t;
|
|
||||||
#endif /* __arch64__ */
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#elif 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hypothetical platform with no float or int64 support
|
|
||||||
*/
|
|
||||||
typedef int khronos_int32_t;
|
|
||||||
typedef unsigned int khronos_uint32_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 0
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 0
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic fallback
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int32_t khronos_int32_t;
|
|
||||||
typedef uint32_t khronos_uint32_t;
|
|
||||||
typedef int64_t khronos_int64_t;
|
|
||||||
typedef uint64_t khronos_uint64_t;
|
|
||||||
#define KHRONOS_SUPPORT_INT64 1
|
|
||||||
#define KHRONOS_SUPPORT_FLOAT 1
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types that are (so far) the same on all platforms
|
|
||||||
*/
|
|
||||||
typedef signed char khronos_int8_t;
|
|
||||||
typedef unsigned char khronos_uint8_t;
|
|
||||||
typedef signed short int khronos_int16_t;
|
|
||||||
typedef unsigned short int khronos_uint16_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
|
||||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
|
||||||
* to be the only LLP64 architecture in current use.
|
|
||||||
*/
|
|
||||||
#ifdef _WIN64
|
|
||||||
typedef signed long long int khronos_intptr_t;
|
|
||||||
typedef unsigned long long int khronos_uintptr_t;
|
|
||||||
typedef signed long long int khronos_ssize_t;
|
|
||||||
typedef unsigned long long int khronos_usize_t;
|
|
||||||
#else
|
|
||||||
typedef signed long int khronos_intptr_t;
|
|
||||||
typedef unsigned long int khronos_uintptr_t;
|
|
||||||
typedef signed long int khronos_ssize_t;
|
|
||||||
typedef unsigned long int khronos_usize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_FLOAT
|
|
||||||
/*
|
|
||||||
* Float type
|
|
||||||
*/
|
|
||||||
typedef float khronos_float_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_INT64
|
|
||||||
/* Time types
|
|
||||||
*
|
|
||||||
* These types can be used to represent a time interval in nanoseconds or
|
|
||||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
|
||||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
|
||||||
* time the system booted). The Unadjusted System Time is an unsigned
|
|
||||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
|
||||||
* may be either signed or unsigned.
|
|
||||||
*/
|
|
||||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
|
||||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dummy value used to pad enum types to 32 bits.
|
|
||||||
*/
|
|
||||||
#ifndef KHRONOS_MAX_ENUM
|
|
||||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enumerated boolean type
|
|
||||||
*
|
|
||||||
* Values other than zero should be considered to be true. Therefore
|
|
||||||
* comparisons should not be made against KHRONOS_TRUE.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
KHRONOS_FALSE = 0,
|
|
||||||
KHRONOS_TRUE = 1,
|
|
||||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
|
||||||
} khronos_boolean_enum_t;
|
|
||||||
|
|
||||||
#endif /* __khrplatform_h_ */
|
|
84
external/glfw-3.3.8/deps/glad/vk_platform.h
vendored
84
external/glfw-3.3.8/deps/glad/vk_platform.h
vendored
@ -1,84 +0,0 @@
|
|||||||
/* */
|
|
||||||
/* 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
5508
external/glfw-3.3.8/deps/glad/vulkan.h
vendored
File diff suppressed because it is too large
Load Diff
1791
external/glfw-3.3.8/deps/glad_gl.c
vendored
1791
external/glfw-3.3.8/deps/glad_gl.c
vendored
File diff suppressed because it is too large
Load Diff
733
external/glfw-3.3.8/deps/glad_vulkan.c
vendored
733
external/glfw-3.3.8/deps/glad_vulkan.c
vendored
@ -1,733 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <glad/vulkan.h>
|
|
||||||
|
|
||||||
#ifndef GLAD_IMPL_UTIL_C_
|
|
||||||
#define GLAD_IMPL_UTIL_C_
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
|
|
||||||
#else
|
|
||||||
#define GLAD_IMPL_UTIL_SSCANF sscanf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* GLAD_IMPL_UTIL_C_ */
|
|
||||||
|
|
||||||
#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
574
external/glfw-3.3.8/deps/linmath.h
vendored
@ -1,574 +0,0 @@
|
|||||||
#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
117
external/glfw-3.3.8/deps/mingw/_mingw_dxhelper.h
vendored
@ -1,117 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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
2467
external/glfw-3.3.8/deps/mingw/dinput.h
vendored
File diff suppressed because it is too large
Load Diff
239
external/glfw-3.3.8/deps/mingw/xinput.h
vendored
239
external/glfw-3.3.8/deps/mingw/xinput.h
vendored
@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
25539
external/glfw-3.3.8/deps/nuklear.h
vendored
File diff suppressed because it is too large
Load Diff
381
external/glfw-3.3.8/deps/nuklear_glfw_gl2.h
vendored
381
external/glfw-3.3.8/deps/nuklear_glfw_gl2.h
vendored
@ -1,381 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
1724
external/glfw-3.3.8/deps/stb_image_write.h
vendored
File diff suppressed because it is too large
Load Diff
594
external/glfw-3.3.8/deps/tinycthread.c
vendored
594
external/glfw-3.3.8/deps/tinycthread.c
vendored
@ -1,594 +0,0 @@
|
|||||||
/* -*- 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
443
external/glfw-3.3.8/deps/tinycthread.h
vendored
@ -1,443 +0,0 @@
|
|||||||
/* -*- 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
247
external/glfw-3.3.8/deps/vs2008/stdint.h
vendored
@ -1,247 +0,0 @@
|
|||||||
// 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
5912
external/glfw-3.3.8/include/GLFW/glfw3.h
vendored
File diff suppressed because it is too large
Load Diff
628
external/glfw-3.3.8/include/GLFW/glfw3native.h
vendored
628
external/glfw-3.3.8/include/GLFW/glfw3native.h
vendored
@ -1,628 +0,0 @@
|
|||||||
/*************************************************************************
|
|
||||||
* 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
195
external/glfw-3.3.8/src/CMakeLists.txt
vendored
@ -1,195 +0,0 @@
|
|||||||
|
|
||||||
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
633
external/glfw-3.3.8/src/cocoa_init.m
vendored
@ -1,633 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
51
external/glfw-3.3.8/src/cocoa_joystick.h
vendored
@ -1,51 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
488
external/glfw-3.3.8/src/cocoa_joystick.m
vendored
@ -1,488 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
627
external/glfw-3.3.8/src/cocoa_monitor.m
vendored
@ -1,627 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
220
external/glfw-3.3.8/src/cocoa_platform.h
vendored
@ -1,220 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
62
external/glfw-3.3.8/src/cocoa_time.c
vendored
@ -1,62 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
1934
external/glfw-3.3.8/src/cocoa_window.m
vendored
File diff suppressed because it is too large
Load Diff
758
external/glfw-3.3.8/src/context.c
vendored
758
external/glfw-3.3.8/src/context.c
vendored
@ -1,758 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
809
external/glfw-3.3.8/src/egl_context.c
vendored
@ -1,809 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
217
external/glfw-3.3.8/src/egl_context.h
vendored
@ -1,217 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
13
external/glfw-3.3.8/src/glfw3.pc.in
vendored
@ -1,13 +0,0 @@
|
|||||||
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
1
external/glfw-3.3.8/src/glfw3Config.cmake.in
vendored
@ -1 +0,0 @@
|
|||||||
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")
|
|
58
external/glfw-3.3.8/src/glfw_config.h.in
vendored
58
external/glfw-3.3.8/src/glfw_config.h.in
vendored
@ -1,58 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
701
external/glfw-3.3.8/src/glx_context.c
vendored
@ -1,701 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
179
external/glfw-3.3.8/src/glx_context.h
vendored
@ -1,179 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
420
external/glfw-3.3.8/src/init.c
vendored
@ -1,420 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
1380
external/glfw-3.3.8/src/input.c
vendored
File diff suppressed because it is too large
Load Diff
786
external/glfw-3.3.8/src/internal.h
vendored
786
external/glfw-3.3.8/src/internal.h
vendored
@ -1,786 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
433
external/glfw-3.3.8/src/linux_joystick.c
vendored
@ -1,433 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
63
external/glfw-3.3.8/src/linux_joystick.h
vendored
@ -1,63 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
1001
external/glfw-3.3.8/src/mappings.h
vendored
File diff suppressed because it is too large
Load Diff
82
external/glfw-3.3.8/src/mappings.h.in
vendored
82
external/glfw-3.3.8/src/mappings.h.in
vendored
@ -1,82 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
542
external/glfw-3.3.8/src/monitor.c
vendored
@ -1,542 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
66
external/glfw-3.3.8/src/nsgl_context.h
vendored
@ -1,66 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
376
external/glfw-3.3.8/src/nsgl_context.m
vendored
@ -1,376 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
52
external/glfw-3.3.8/src/null_init.c
vendored
@ -1,52 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
44
external/glfw-3.3.8/src/null_joystick.c
vendored
@ -1,44 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
31
external/glfw-3.3.8/src/null_joystick.h
vendored
@ -1,31 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
77
external/glfw-3.3.8/src/null_monitor.c
vendored
@ -1,77 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
62
external/glfw-3.3.8/src/null_platform.h
vendored
@ -1,62 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
335
external/glfw-3.3.8/src/null_window.c
vendored
@ -1,335 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
386
external/glfw-3.3.8/src/osmesa_context.c
vendored
@ -1,386 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
92
external/glfw-3.3.8/src/osmesa_context.h
vendored
@ -1,92 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
105
external/glfw-3.3.8/src/posix_thread.c
vendored
@ -1,105 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
49
external/glfw-3.3.8/src/posix_thread.h
vendored
@ -1,49 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
87
external/glfw-3.3.8/src/posix_time.c
vendored
@ -1,87 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
43
external/glfw-3.3.8/src/posix_time.h
vendored
@ -1,43 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
334
external/glfw-3.3.8/src/vulkan.c
vendored
@ -1,334 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
798
external/glfw-3.3.8/src/wgl_context.c
vendored
@ -1,798 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
158
external/glfw-3.3.8/src/wgl_context.h
vendored
@ -1,158 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
638
external/glfw-3.3.8/src/win32_init.c
vendored
@ -1,638 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
755
external/glfw-3.3.8/src/win32_joystick.c
vendored
@ -1,755 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
57
external/glfw-3.3.8/src/win32_joystick.h
vendored
@ -1,57 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
548
external/glfw-3.3.8/src/win32_monitor.c
vendored
@ -1,548 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
458
external/glfw-3.3.8/src/win32_platform.h
vendored
@ -1,458 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
99
external/glfw-3.3.8/src/win32_thread.c
vendored
@ -1,99 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
60
external/glfw-3.3.8/src/win32_time.c
vendored
@ -1,60 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
2396
external/glfw-3.3.8/src/win32_window.c
vendored
File diff suppressed because it is too large
Load Diff
1101
external/glfw-3.3.8/src/window.c
vendored
1101
external/glfw-3.3.8/src/window.c
vendored
File diff suppressed because it is too large
Load Diff
595
external/glfw-3.3.8/src/wl_init.c
vendored
595
external/glfw-3.3.8/src/wl_init.c
vendored
@ -1,595 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
271
external/glfw-3.3.8/src/wl_monitor.c
vendored
@ -1,271 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
373
external/glfw-3.3.8/src/wl_platform.h
vendored
@ -1,373 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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
2794
external/glfw-3.3.8/src/wl_window.c
vendored
File diff suppressed because it is too large
Load Diff
1274
external/glfw-3.3.8/src/x11_init.c
vendored
1274
external/glfw-3.3.8/src/x11_init.c
vendored
File diff suppressed because it is too large
Load Diff
614
external/glfw-3.3.8/src/x11_monitor.c
vendored
614
external/glfw-3.3.8/src/x11_monitor.c
vendored
@ -1,614 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user