init
This commit is contained in:
commit
e1f0406449
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
build
|
84
CMakeLists.txt
Normal file
84
CMakeLists.txt
Normal file
@ -0,0 +1,84 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(MyProject)
|
||||
|
||||
# Set the C++ standard
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
|
||||
add_compile_options(-O2)
|
||||
|
||||
add_library(sqlite3
|
||||
sqlite3/sqlite3.c
|
||||
)
|
||||
|
||||
target_compile_definitions(sqlite3 PRIVATE
|
||||
SQLITE_DQS=0
|
||||
SQLITE_DEFAULT_MEMSTATUS=0
|
||||
SQLITE_DEFAULT_WAL_SYNCHRONOUS=1
|
||||
SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
SQLITE_MAX_EXPR_DEPTH=0
|
||||
SQLITE_OMIT_DECLTYPE
|
||||
SQLITE_OMIT_DEPRECATED
|
||||
SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
SQLITE_OMIT_SHARED_CACHE
|
||||
SQLITE_USE_ALLOCA
|
||||
SQLITE_OMIT_AUTOINIT
|
||||
SQLITE_STRICT_SUBTYPE=1
|
||||
SQLITE_THREADSAFE=2
|
||||
)
|
||||
|
||||
add_library(imgui
|
||||
imgui/imgui_demo.cpp
|
||||
imgui/imgui_draw.cpp
|
||||
imgui/imgui_tables.cpp
|
||||
imgui/imgui_widgets.cpp
|
||||
imgui/imgui.cpp
|
||||
imgui_raylib/rlImGui.cpp
|
||||
)
|
||||
|
||||
target_include_directories(imgui PRIVATE raylib/ imgui/)
|
||||
|
||||
|
||||
add_library(raylib
|
||||
raylib/rcore.c
|
||||
raylib/rshapes.c
|
||||
raylib/rtextures.c
|
||||
raylib/rtext.c
|
||||
raylib/utils.c
|
||||
raylib/rglfw.c
|
||||
raylib/rmodels.c
|
||||
raylib/raudio.c
|
||||
)
|
||||
|
||||
target_compile_definitions(raylib PUBLIC
|
||||
_GNU_SOURCE
|
||||
PLATFORM_DESKTOP_GLFW
|
||||
GRAPHICS_API_OPENGL_33
|
||||
_GLFW_X11
|
||||
)
|
||||
|
||||
target_include_directories(raylib PRIVATE
|
||||
raylib/
|
||||
raylib/external/glfw/include
|
||||
)
|
||||
|
||||
set(public_headers
|
||||
raylib/raylib.h
|
||||
raylib/rlgl.h
|
||||
raylib/raymath.h
|
||||
|
||||
sqlite3/sqlite3.h
|
||||
|
||||
imgui/imgui.h
|
||||
imgui/imconfig.h
|
||||
|
||||
imgui_raylib/rlImGui.h
|
||||
imgui_raylib/rlImGuiColors.h
|
||||
imgui_raylib/IconsFontAwesome6.h
|
||||
)
|
||||
|
||||
file(COPY ${public_headers} DESTINATION "include")
|
||||
|
142
imgui/imconfig.h
Normal file
142
imgui/imconfig.h
Normal file
@ -0,0 +1,142 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
||||
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
||||
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||
|
||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg.
|
||||
// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions.
|
||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||
}
|
||||
*/
|
22831
imgui/imgui.cpp
Normal file
22831
imgui/imgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4001
imgui/imgui.h
Normal file
4001
imgui/imgui.h
Normal file
File diff suppressed because it is too large
Load Diff
10740
imgui/imgui_demo.cpp
Normal file
10740
imgui/imgui_demo.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4866
imgui/imgui_draw.cpp
Normal file
4866
imgui/imgui_draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3918
imgui/imgui_internal.h
Normal file
3918
imgui/imgui_internal.h
Normal file
File diff suppressed because it is too large
Load Diff
4501
imgui/imgui_tables.cpp
Normal file
4501
imgui/imgui_tables.cpp
Normal file
File diff suppressed because it is too large
Load Diff
10517
imgui/imgui_widgets.cpp
Normal file
10517
imgui/imgui_widgets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
627
imgui/imstb_rectpack.h
Normal file
627
imgui/imstb_rectpack.h
Normal file
@ -0,0 +1,627 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
//
|
||||
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Before #including,
|
||||
//
|
||||
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||
//
|
||||
// in the file that you want to have the implementation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
typedef int stbrp_coord;
|
||||
|
||||
#define STBRP__MAXVAL 0x7fffffff
|
||||
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
context->extra[1].y = (1<<30);
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
1469
imgui/imstb_textedit.h
Normal file
1469
imgui/imstb_textedit.h
Normal file
File diff suppressed because it is too large
Load Diff
5085
imgui/imstb_truetype.h
Normal file
5085
imgui/imstb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
4973
imgui_raylib/FA6FreeSolidFontData.h
Normal file
4973
imgui_raylib/FA6FreeSolidFontData.h
Normal file
File diff suppressed because it is too large
Load Diff
34
imgui_raylib/FontAwsome_LICENSE.txt
Normal file
34
imgui_raylib/FontAwsome_LICENSE.txt
Normal file
@ -0,0 +1,34 @@
|
||||
Font Awesome Free License
|
||||
-------------------------
|
||||
|
||||
Font Awesome Free is free, open source, and GPL friendly. You can use it for
|
||||
commercial projects, open source projects, or really almost whatever you want.
|
||||
Full Font Awesome Free license: https://fontawesome.com/license/free.
|
||||
|
||||
# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
|
||||
In the Font Awesome Free download, the CC BY 4.0 license applies to all icons
|
||||
packaged as SVG and JS file types.
|
||||
|
||||
# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)
|
||||
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||
packaged as web and desktop font files.
|
||||
|
||||
# Code: MIT License (https://opensource.org/licenses/MIT)
|
||||
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||
non-icon files.
|
||||
|
||||
# Attribution
|
||||
Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
|
||||
Awesome Free files already contain embedded comments with sufficient
|
||||
attribution, so you shouldn't need to do anything additional when using these
|
||||
files normally.
|
||||
|
||||
We've kept attribution comments terse, so we ask that you do not actively work
|
||||
to remove them from files, especially code. They're a great way for folks to
|
||||
learn about Font Awesome.
|
||||
|
||||
# Brand Icons
|
||||
All brand icons are trademarks of their respective owners. The use of these
|
||||
trademarks does not indicate endorsement of the trademark holder by Font
|
||||
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
|
||||
to represent the company, product, or service to which they refer.**
|
1396
imgui_raylib/IconsFontAwesome6.h
Normal file
1396
imgui_raylib/IconsFontAwesome6.h
Normal file
File diff suppressed because it is too large
Load Diff
54
imgui_raylib/imgui_impl_raylib.h
Normal file
54
imgui_raylib/imgui_impl_raylib.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylibExtras * Utilities and Shared Components for Raylib
|
||||
*
|
||||
* rlImGui * basic ImGui integration
|
||||
*
|
||||
* LICENSE: ZLIB
|
||||
*
|
||||
* Copyright (c) 2024 Jeffery Myers
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
// dear imgui: Platform Backend for Raylib
|
||||
// (Info: Raylib is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc. using OpenGL)
|
||||
// This is is the low level ImGui backend for raylib, a higher level API that matches the raylib API can be found in rlImGui.h
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplRaylib_Init(void);
|
||||
IMGUI_IMPL_API void ImGui_ImplRaylib_BuildFontAtlas(void);
|
||||
IMGUI_IMPL_API void ImGui_ImplRaylib_Shutdown(void);
|
||||
IMGUI_IMPL_API void ImGui_ImplRaylib_NewFrame(void);
|
||||
IMGUI_IMPL_API void ImGui_ImplRaylib_RenderDrawData(ImDrawData* draw_data);
|
||||
IMGUI_IMPL_API bool ImGui_ImplRaylib_ProcessEvents(void);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
799
imgui_raylib/rlImGui.cpp
Normal file
799
imgui_raylib/rlImGui.cpp
Normal file
@ -0,0 +1,799 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylibExtras * Utilities and Shared Components for Raylib
|
||||
*
|
||||
* rlImGui * basic ImGui integration
|
||||
*
|
||||
* LICENSE: ZLIB
|
||||
*
|
||||
* Copyright (c) 2024 Jeffery Myers
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
#include "rlImGui.h"
|
||||
|
||||
#include "imgui_impl_raylib.h"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "rlgl.h"
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <map>
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
|
||||
#ifndef NO_FONT_AWESOME
|
||||
#include "FA6FreeSolidFontData.h"
|
||||
#endif
|
||||
|
||||
static ImGuiMouseCursor CurrentMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
static MouseCursor MouseCursorMap[ImGuiMouseCursor_COUNT];
|
||||
|
||||
ImGuiContext *GlobalContext = nullptr;
|
||||
|
||||
static std::map<KeyboardKey, ImGuiKey> RaylibKeyMap;
|
||||
|
||||
static bool LastFrameFocused = false;
|
||||
|
||||
static bool LastControlPressed = false;
|
||||
static bool LastShiftPressed = false;
|
||||
static bool LastAltPressed = false;
|
||||
static bool LastSuperPressed = false;
|
||||
|
||||
// internal only functions
|
||||
bool rlImGuiIsControlDown() { return IsKeyDown(KEY_RIGHT_CONTROL) || IsKeyDown(KEY_LEFT_CONTROL); }
|
||||
bool rlImGuiIsShiftDown() { return IsKeyDown(KEY_RIGHT_SHIFT) || IsKeyDown(KEY_LEFT_SHIFT); }
|
||||
bool rlImGuiIsAltDown() { return IsKeyDown(KEY_RIGHT_ALT) || IsKeyDown(KEY_LEFT_ALT); }
|
||||
bool rlImGuiIsSuperDown() { return IsKeyDown(KEY_RIGHT_SUPER) || IsKeyDown(KEY_LEFT_SUPER); }
|
||||
|
||||
void ReloadFonts(void)
|
||||
{
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
unsigned char *pixels = nullptr;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, nullptr);
|
||||
Image image = GenImageColor(width, height, BLANK);
|
||||
memcpy(image.data, pixels, width * height * 4);
|
||||
|
||||
Texture2D *fontTexture = (Texture2D *)io.Fonts->TexID;
|
||||
if (fontTexture && fontTexture->id != 0)
|
||||
{
|
||||
UnloadTexture(*fontTexture);
|
||||
MemFree(fontTexture);
|
||||
}
|
||||
|
||||
fontTexture = (Texture2D *)MemAlloc(sizeof(Texture2D));
|
||||
*fontTexture = LoadTextureFromImage(image);
|
||||
UnloadImage(image);
|
||||
io.Fonts->TexID = (ImTextureID)fontTexture;
|
||||
}
|
||||
|
||||
static const char *GetClipTextCallback(ImGuiContext *)
|
||||
{
|
||||
return GetClipboardText();
|
||||
}
|
||||
|
||||
static void SetClipTextCallback(ImGuiContext *, const char *text)
|
||||
{
|
||||
SetClipboardText(text);
|
||||
}
|
||||
|
||||
static void ImGuiNewFrame(float deltaTime)
|
||||
{
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
Vector2 resolutionScale = GetWindowScaleDPI();
|
||||
|
||||
#ifndef PLATFORM_DRM
|
||||
if (IsWindowFullscreen())
|
||||
{
|
||||
int monitor = GetCurrentMonitor();
|
||||
io.DisplaySize.x = float(GetMonitorWidth(monitor));
|
||||
io.DisplaySize.y = float(GetMonitorHeight(monitor));
|
||||
}
|
||||
else
|
||||
{
|
||||
io.DisplaySize.x = float(GetScreenWidth());
|
||||
io.DisplaySize.y = float(GetScreenHeight());
|
||||
}
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
if (!IsWindowState(FLAG_WINDOW_HIGHDPI))
|
||||
resolutionScale = Vector2{1, 1};
|
||||
#endif
|
||||
#else
|
||||
io.DisplaySize.x = float(GetScreenWidth());
|
||||
io.DisplaySize.y = float(GetScreenHeight());
|
||||
#endif
|
||||
|
||||
io.DisplayFramebufferScale = ImVec2(resolutionScale.x, resolutionScale.y);
|
||||
|
||||
if (deltaTime <= 0)
|
||||
deltaTime = 0.001f;
|
||||
|
||||
io.DeltaTime = deltaTime;
|
||||
|
||||
if (ImGui::GetIO().BackendFlags & ImGuiBackendFlags_HasMouseCursors)
|
||||
{
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) == 0)
|
||||
{
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (imgui_cursor != CurrentMouseCursor || io.MouseDrawCursor)
|
||||
{
|
||||
CurrentMouseCursor = imgui_cursor;
|
||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
|
||||
{
|
||||
HideCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCursor();
|
||||
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange))
|
||||
{
|
||||
SetMouseCursor((imgui_cursor > -1 && imgui_cursor < ImGuiMouseCursor_COUNT) ? MouseCursorMap[imgui_cursor] : MOUSE_CURSOR_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGuiTriangleVert(ImDrawVert &idx_vert)
|
||||
{
|
||||
Color *c;
|
||||
c = (Color *)&idx_vert.col;
|
||||
rlColor4ub(c->r, c->g, c->b, c->a);
|
||||
rlTexCoord2f(idx_vert.uv.x, idx_vert.uv.y);
|
||||
rlVertex2f(idx_vert.pos.x, idx_vert.pos.y);
|
||||
}
|
||||
|
||||
static void ImGuiRenderTriangles(unsigned int count, int indexStart, const ImVector<ImDrawIdx> &indexBuffer, const ImVector<ImDrawVert> &vertBuffer, void *texturePtr)
|
||||
{
|
||||
if (count < 3)
|
||||
return;
|
||||
|
||||
Texture *texture = (Texture *)texturePtr;
|
||||
|
||||
unsigned int textureId = (texture == nullptr) ? 0 : texture->id;
|
||||
|
||||
rlBegin(RL_TRIANGLES);
|
||||
rlSetTexture(textureId);
|
||||
|
||||
for (unsigned int i = 0; i <= (count - 3); i += 3)
|
||||
{
|
||||
ImDrawIdx indexA = indexBuffer[indexStart + i];
|
||||
ImDrawIdx indexB = indexBuffer[indexStart + i + 1];
|
||||
ImDrawIdx indexC = indexBuffer[indexStart + i + 2];
|
||||
|
||||
ImDrawVert vertexA = vertBuffer[indexA];
|
||||
ImDrawVert vertexB = vertBuffer[indexB];
|
||||
ImDrawVert vertexC = vertBuffer[indexC];
|
||||
|
||||
ImGuiTriangleVert(vertexA);
|
||||
ImGuiTriangleVert(vertexB);
|
||||
ImGuiTriangleVert(vertexC);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
static void EnableScissor(float x, float y, float width, float height)
|
||||
{
|
||||
rlEnableScissorTest();
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
ImVec2 scale = io.DisplayFramebufferScale;
|
||||
#if !defined(__APPLE__)
|
||||
if (!IsWindowState(FLAG_WINDOW_HIGHDPI))
|
||||
{
|
||||
scale.x = 1;
|
||||
scale.y = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
rlScissor((int)(x * scale.x),
|
||||
int((io.DisplaySize.y - (int)(y + height)) * scale.y),
|
||||
(int)(width * scale.x),
|
||||
(int)(height * scale.y));
|
||||
}
|
||||
|
||||
static void SetupMouseCursors(void)
|
||||
{
|
||||
MouseCursorMap[ImGuiMouseCursor_Arrow] = MOUSE_CURSOR_ARROW;
|
||||
MouseCursorMap[ImGuiMouseCursor_TextInput] = MOUSE_CURSOR_IBEAM;
|
||||
MouseCursorMap[ImGuiMouseCursor_Hand] = MOUSE_CURSOR_POINTING_HAND;
|
||||
MouseCursorMap[ImGuiMouseCursor_ResizeAll] = MOUSE_CURSOR_RESIZE_ALL;
|
||||
MouseCursorMap[ImGuiMouseCursor_ResizeEW] = MOUSE_CURSOR_RESIZE_EW;
|
||||
MouseCursorMap[ImGuiMouseCursor_ResizeNESW] = MOUSE_CURSOR_RESIZE_NESW;
|
||||
MouseCursorMap[ImGuiMouseCursor_ResizeNS] = MOUSE_CURSOR_RESIZE_NS;
|
||||
MouseCursorMap[ImGuiMouseCursor_ResizeNWSE] = MOUSE_CURSOR_RESIZE_NWSE;
|
||||
MouseCursorMap[ImGuiMouseCursor_NotAllowed] = MOUSE_CURSOR_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
void SetupFontAwesome(void)
|
||||
{
|
||||
#ifndef NO_FONT_AWESOME
|
||||
static const ImWchar icons_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0};
|
||||
ImFontConfig icons_config;
|
||||
icons_config.MergeMode = true;
|
||||
icons_config.PixelSnapH = true;
|
||||
icons_config.FontDataOwnedByAtlas = false;
|
||||
|
||||
icons_config.GlyphMaxAdvanceX = std::numeric_limits<float>::max();
|
||||
icons_config.RasterizerMultiply = 1.0f;
|
||||
icons_config.OversampleH = 2;
|
||||
icons_config.OversampleV = 1;
|
||||
|
||||
icons_config.GlyphRanges = icons_ranges;
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
io.Fonts->AddFontFromMemoryCompressedTTF((void *)fa_solid_900_compressed_data, fa_solid_900_compressed_size, FONT_AWESOME_ICON_SIZE, &icons_config, icons_ranges);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetupBackend(void)
|
||||
{
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.BackendPlatformName = "imgui_impl_raylib";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_HasSetMousePos;
|
||||
|
||||
#ifndef PLATFORM_DRM
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||
#endif
|
||||
|
||||
io.MousePos = ImVec2(0, 0);
|
||||
|
||||
ImGuiPlatformIO &platformIO = ImGui::GetPlatformIO();
|
||||
|
||||
platformIO.Platform_SetClipboardTextFn = SetClipTextCallback;
|
||||
platformIO.Platform_GetClipboardTextFn = GetClipTextCallback;
|
||||
|
||||
platformIO.Platform_ClipboardUserData = nullptr;
|
||||
}
|
||||
|
||||
void rlImGuiEndInitImGui(void)
|
||||
{
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
SetupFontAwesome();
|
||||
|
||||
SetupMouseCursors();
|
||||
|
||||
SetupBackend();
|
||||
|
||||
ReloadFonts();
|
||||
}
|
||||
|
||||
static void SetupKeymap(void)
|
||||
{
|
||||
if (!RaylibKeyMap.empty())
|
||||
return;
|
||||
|
||||
// build up a map of raylib keys to ImGuiKeys
|
||||
RaylibKeyMap[KEY_APOSTROPHE] = ImGuiKey_Apostrophe;
|
||||
RaylibKeyMap[KEY_COMMA] = ImGuiKey_Comma;
|
||||
RaylibKeyMap[KEY_MINUS] = ImGuiKey_Minus;
|
||||
RaylibKeyMap[KEY_PERIOD] = ImGuiKey_Period;
|
||||
RaylibKeyMap[KEY_SLASH] = ImGuiKey_Slash;
|
||||
RaylibKeyMap[KEY_ZERO] = ImGuiKey_0;
|
||||
RaylibKeyMap[KEY_ONE] = ImGuiKey_1;
|
||||
RaylibKeyMap[KEY_TWO] = ImGuiKey_2;
|
||||
RaylibKeyMap[KEY_THREE] = ImGuiKey_3;
|
||||
RaylibKeyMap[KEY_FOUR] = ImGuiKey_4;
|
||||
RaylibKeyMap[KEY_FIVE] = ImGuiKey_5;
|
||||
RaylibKeyMap[KEY_SIX] = ImGuiKey_6;
|
||||
RaylibKeyMap[KEY_SEVEN] = ImGuiKey_7;
|
||||
RaylibKeyMap[KEY_EIGHT] = ImGuiKey_8;
|
||||
RaylibKeyMap[KEY_NINE] = ImGuiKey_9;
|
||||
RaylibKeyMap[KEY_SEMICOLON] = ImGuiKey_Semicolon;
|
||||
RaylibKeyMap[KEY_EQUAL] = ImGuiKey_Equal;
|
||||
RaylibKeyMap[KEY_A] = ImGuiKey_A;
|
||||
RaylibKeyMap[KEY_B] = ImGuiKey_B;
|
||||
RaylibKeyMap[KEY_C] = ImGuiKey_C;
|
||||
RaylibKeyMap[KEY_D] = ImGuiKey_D;
|
||||
RaylibKeyMap[KEY_E] = ImGuiKey_E;
|
||||
RaylibKeyMap[KEY_F] = ImGuiKey_F;
|
||||
RaylibKeyMap[KEY_G] = ImGuiKey_G;
|
||||
RaylibKeyMap[KEY_H] = ImGuiKey_H;
|
||||
RaylibKeyMap[KEY_I] = ImGuiKey_I;
|
||||
RaylibKeyMap[KEY_J] = ImGuiKey_J;
|
||||
RaylibKeyMap[KEY_K] = ImGuiKey_K;
|
||||
RaylibKeyMap[KEY_L] = ImGuiKey_L;
|
||||
RaylibKeyMap[KEY_M] = ImGuiKey_M;
|
||||
RaylibKeyMap[KEY_N] = ImGuiKey_N;
|
||||
RaylibKeyMap[KEY_O] = ImGuiKey_O;
|
||||
RaylibKeyMap[KEY_P] = ImGuiKey_P;
|
||||
RaylibKeyMap[KEY_Q] = ImGuiKey_Q;
|
||||
RaylibKeyMap[KEY_R] = ImGuiKey_R;
|
||||
RaylibKeyMap[KEY_S] = ImGuiKey_S;
|
||||
RaylibKeyMap[KEY_T] = ImGuiKey_T;
|
||||
RaylibKeyMap[KEY_U] = ImGuiKey_U;
|
||||
RaylibKeyMap[KEY_V] = ImGuiKey_V;
|
||||
RaylibKeyMap[KEY_W] = ImGuiKey_W;
|
||||
RaylibKeyMap[KEY_X] = ImGuiKey_X;
|
||||
RaylibKeyMap[KEY_Y] = ImGuiKey_Y;
|
||||
RaylibKeyMap[KEY_Z] = ImGuiKey_Z;
|
||||
RaylibKeyMap[KEY_SPACE] = ImGuiKey_Space;
|
||||
RaylibKeyMap[KEY_ESCAPE] = ImGuiKey_Escape;
|
||||
RaylibKeyMap[KEY_ENTER] = ImGuiKey_Enter;
|
||||
RaylibKeyMap[KEY_TAB] = ImGuiKey_Tab;
|
||||
RaylibKeyMap[KEY_BACKSPACE] = ImGuiKey_Backspace;
|
||||
RaylibKeyMap[KEY_INSERT] = ImGuiKey_Insert;
|
||||
RaylibKeyMap[KEY_DELETE] = ImGuiKey_Delete;
|
||||
RaylibKeyMap[KEY_RIGHT] = ImGuiKey_RightArrow;
|
||||
RaylibKeyMap[KEY_LEFT] = ImGuiKey_LeftArrow;
|
||||
RaylibKeyMap[KEY_DOWN] = ImGuiKey_DownArrow;
|
||||
RaylibKeyMap[KEY_UP] = ImGuiKey_UpArrow;
|
||||
RaylibKeyMap[KEY_PAGE_UP] = ImGuiKey_PageUp;
|
||||
RaylibKeyMap[KEY_PAGE_DOWN] = ImGuiKey_PageDown;
|
||||
RaylibKeyMap[KEY_HOME] = ImGuiKey_Home;
|
||||
RaylibKeyMap[KEY_END] = ImGuiKey_End;
|
||||
RaylibKeyMap[KEY_CAPS_LOCK] = ImGuiKey_CapsLock;
|
||||
RaylibKeyMap[KEY_SCROLL_LOCK] = ImGuiKey_ScrollLock;
|
||||
RaylibKeyMap[KEY_NUM_LOCK] = ImGuiKey_NumLock;
|
||||
RaylibKeyMap[KEY_PRINT_SCREEN] = ImGuiKey_PrintScreen;
|
||||
RaylibKeyMap[KEY_PAUSE] = ImGuiKey_Pause;
|
||||
RaylibKeyMap[KEY_F1] = ImGuiKey_F1;
|
||||
RaylibKeyMap[KEY_F2] = ImGuiKey_F2;
|
||||
RaylibKeyMap[KEY_F3] = ImGuiKey_F3;
|
||||
RaylibKeyMap[KEY_F4] = ImGuiKey_F4;
|
||||
RaylibKeyMap[KEY_F5] = ImGuiKey_F5;
|
||||
RaylibKeyMap[KEY_F6] = ImGuiKey_F6;
|
||||
RaylibKeyMap[KEY_F7] = ImGuiKey_F7;
|
||||
RaylibKeyMap[KEY_F8] = ImGuiKey_F8;
|
||||
RaylibKeyMap[KEY_F9] = ImGuiKey_F9;
|
||||
RaylibKeyMap[KEY_F10] = ImGuiKey_F10;
|
||||
RaylibKeyMap[KEY_F11] = ImGuiKey_F11;
|
||||
RaylibKeyMap[KEY_F12] = ImGuiKey_F12;
|
||||
RaylibKeyMap[KEY_LEFT_SHIFT] = ImGuiKey_LeftShift;
|
||||
RaylibKeyMap[KEY_LEFT_CONTROL] = ImGuiKey_LeftCtrl;
|
||||
RaylibKeyMap[KEY_LEFT_ALT] = ImGuiKey_LeftAlt;
|
||||
RaylibKeyMap[KEY_LEFT_SUPER] = ImGuiKey_LeftSuper;
|
||||
RaylibKeyMap[KEY_RIGHT_SHIFT] = ImGuiKey_RightShift;
|
||||
RaylibKeyMap[KEY_RIGHT_CONTROL] = ImGuiKey_RightCtrl;
|
||||
RaylibKeyMap[KEY_RIGHT_ALT] = ImGuiKey_RightAlt;
|
||||
RaylibKeyMap[KEY_RIGHT_SUPER] = ImGuiKey_RightSuper;
|
||||
RaylibKeyMap[KEY_KB_MENU] = ImGuiKey_Menu;
|
||||
RaylibKeyMap[KEY_LEFT_BRACKET] = ImGuiKey_LeftBracket;
|
||||
RaylibKeyMap[KEY_BACKSLASH] = ImGuiKey_Backslash;
|
||||
RaylibKeyMap[KEY_RIGHT_BRACKET] = ImGuiKey_RightBracket;
|
||||
RaylibKeyMap[KEY_GRAVE] = ImGuiKey_GraveAccent;
|
||||
RaylibKeyMap[KEY_KP_0] = ImGuiKey_Keypad0;
|
||||
RaylibKeyMap[KEY_KP_1] = ImGuiKey_Keypad1;
|
||||
RaylibKeyMap[KEY_KP_2] = ImGuiKey_Keypad2;
|
||||
RaylibKeyMap[KEY_KP_3] = ImGuiKey_Keypad3;
|
||||
RaylibKeyMap[KEY_KP_4] = ImGuiKey_Keypad4;
|
||||
RaylibKeyMap[KEY_KP_5] = ImGuiKey_Keypad5;
|
||||
RaylibKeyMap[KEY_KP_6] = ImGuiKey_Keypad6;
|
||||
RaylibKeyMap[KEY_KP_7] = ImGuiKey_Keypad7;
|
||||
RaylibKeyMap[KEY_KP_8] = ImGuiKey_Keypad8;
|
||||
RaylibKeyMap[KEY_KP_9] = ImGuiKey_Keypad9;
|
||||
RaylibKeyMap[KEY_KP_DECIMAL] = ImGuiKey_KeypadDecimal;
|
||||
RaylibKeyMap[KEY_KP_DIVIDE] = ImGuiKey_KeypadDivide;
|
||||
RaylibKeyMap[KEY_KP_MULTIPLY] = ImGuiKey_KeypadMultiply;
|
||||
RaylibKeyMap[KEY_KP_SUBTRACT] = ImGuiKey_KeypadSubtract;
|
||||
RaylibKeyMap[KEY_KP_ADD] = ImGuiKey_KeypadAdd;
|
||||
RaylibKeyMap[KEY_KP_ENTER] = ImGuiKey_KeypadEnter;
|
||||
RaylibKeyMap[KEY_KP_EQUAL] = ImGuiKey_KeypadEqual;
|
||||
}
|
||||
|
||||
static void SetupGlobals(void)
|
||||
{
|
||||
LastFrameFocused = IsWindowFocused();
|
||||
LastControlPressed = false;
|
||||
LastShiftPressed = false;
|
||||
LastAltPressed = false;
|
||||
LastSuperPressed = false;
|
||||
}
|
||||
|
||||
void rlImGuiBeginInitImGui(void)
|
||||
{
|
||||
SetupGlobals();
|
||||
if (GlobalContext == nullptr)
|
||||
GlobalContext = ImGui::CreateContext(nullptr);
|
||||
SetupKeymap();
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.Fonts->AddFontDefault();
|
||||
}
|
||||
|
||||
void rlImGuiSetup(bool dark)
|
||||
{
|
||||
rlImGuiBeginInitImGui();
|
||||
|
||||
if (dark)
|
||||
ImGui::StyleColorsDark();
|
||||
else
|
||||
ImGui::StyleColorsLight();
|
||||
|
||||
rlImGuiEndInitImGui();
|
||||
}
|
||||
|
||||
void rlImGuiReloadFonts(void)
|
||||
{
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ReloadFonts();
|
||||
}
|
||||
|
||||
void rlImGuiBegin(void)
|
||||
{
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
rlImGuiBeginDelta(GetFrameTime());
|
||||
}
|
||||
|
||||
void rlImGuiBeginDelta(float deltaTime)
|
||||
{
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ImGuiNewFrame(deltaTime);
|
||||
ImGui_ImplRaylib_ProcessEvents();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void rlImGuiEnd(void)
|
||||
{
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
ImGui::Render();
|
||||
ImGui_ImplRaylib_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void rlImGuiShutdown(void)
|
||||
{
|
||||
if (GlobalContext == nullptr)
|
||||
return;
|
||||
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
ImGui_ImplRaylib_Shutdown();
|
||||
|
||||
ImGui::DestroyContext(GlobalContext);
|
||||
GlobalContext = nullptr;
|
||||
}
|
||||
|
||||
void rlImGuiImage(const Texture *image)
|
||||
{
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ImGui::Image((ImTextureID)image, ImVec2(float(image->width), float(image->height)));
|
||||
}
|
||||
|
||||
bool rlImGuiImageButton(const char *name, const Texture *image)
|
||||
{
|
||||
if (!image)
|
||||
return false;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
return ImGui::ImageButton(name, (ImTextureID)image, ImVec2(float(image->width), float(image->height)));
|
||||
}
|
||||
|
||||
bool rlImGuiImageButtonSize(const char *name, const Texture *image, ImVec2 size)
|
||||
{
|
||||
if (!image)
|
||||
return false;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
return ImGui::ImageButton(name, (ImTextureID)image, size);
|
||||
}
|
||||
|
||||
void rlImGuiImageSize(const Texture *image, int width, int height)
|
||||
{
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ImGui::Image((ImTextureID)image, ImVec2(float(width), float(height)));
|
||||
}
|
||||
|
||||
void rlImGuiImageSizeV(const Texture *image, Vector2 size)
|
||||
{
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ImGui::Image((ImTextureID)image, ImVec2(size.x, size.y));
|
||||
}
|
||||
|
||||
void rlImGuiImageRect(const Texture *image, int destWidth, int destHeight, Rectangle sourceRect)
|
||||
{
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ImVec2 uv0;
|
||||
ImVec2 uv1;
|
||||
|
||||
if (sourceRect.width < 0)
|
||||
{
|
||||
uv0.x = -((float)sourceRect.x / image->width);
|
||||
uv1.x = (uv0.x - (float)(fabs(sourceRect.width) / image->width));
|
||||
}
|
||||
else
|
||||
{
|
||||
uv0.x = (float)sourceRect.x / image->width;
|
||||
uv1.x = uv0.x + (float)(sourceRect.width / image->width);
|
||||
}
|
||||
|
||||
if (sourceRect.height < 0)
|
||||
{
|
||||
uv0.y = -((float)sourceRect.y / image->height);
|
||||
uv1.y = (uv0.y - (float)(fabs(sourceRect.height) / image->height));
|
||||
}
|
||||
else
|
||||
{
|
||||
uv0.y = (float)sourceRect.y / image->height;
|
||||
uv1.y = uv0.y + (float)(sourceRect.height / image->height);
|
||||
}
|
||||
|
||||
ImGui::Image((ImTextureID)image, ImVec2(float(destWidth), float(destHeight)), uv0, uv1);
|
||||
}
|
||||
|
||||
void rlImGuiImageRenderTexture(const RenderTexture *image)
|
||||
{
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
rlImGuiImageRect(&image->texture, image->texture.width, image->texture.height, Rectangle{0, 0, float(image->texture.width), -float(image->texture.height)});
|
||||
}
|
||||
|
||||
void rlImGuiImageRenderTextureFit(const RenderTexture *image, bool center)
|
||||
{
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
if (GlobalContext)
|
||||
ImGui::SetCurrentContext(GlobalContext);
|
||||
|
||||
ImVec2 area = ImGui::GetContentRegionAvail();
|
||||
|
||||
float scale = area.x / image->texture.width;
|
||||
|
||||
float y = image->texture.height * scale;
|
||||
if (y > area.y)
|
||||
{
|
||||
scale = area.y / image->texture.height;
|
||||
}
|
||||
|
||||
int sizeX = int(image->texture.width * scale);
|
||||
int sizeY = int(image->texture.height * scale);
|
||||
|
||||
if (center)
|
||||
{
|
||||
ImGui::SetCursorPosX(0);
|
||||
ImGui::SetCursorPosX(area.x / 2 - sizeX / 2);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (area.y / 2 - sizeY / 2));
|
||||
}
|
||||
|
||||
rlImGuiImageRect(&image->texture, sizeX, sizeY, Rectangle{0, 0, float(image->texture.width), -float(image->texture.height)});
|
||||
}
|
||||
|
||||
// raw ImGui backend API
|
||||
bool ImGui_ImplRaylib_Init(void)
|
||||
{
|
||||
SetupGlobals();
|
||||
|
||||
SetupKeymap();
|
||||
|
||||
SetupMouseCursors();
|
||||
|
||||
SetupBackend();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplRaylib_BuildFontAtlas(void)
|
||||
{
|
||||
ReloadFonts();
|
||||
}
|
||||
|
||||
void ImGui_ImplRaylib_Shutdown()
|
||||
{
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
Texture2D *fontTexture = (Texture2D *)io.Fonts->TexID;
|
||||
|
||||
if (fontTexture)
|
||||
{
|
||||
UnloadTexture(*fontTexture);
|
||||
MemFree(fontTexture);
|
||||
}
|
||||
|
||||
io.Fonts->TexID = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplRaylib_NewFrame(void)
|
||||
{
|
||||
ImGuiNewFrame(GetFrameTime());
|
||||
}
|
||||
|
||||
void ImGui_ImplRaylib_RenderDrawData(ImDrawData *draw_data)
|
||||
{
|
||||
rlDrawRenderBatchActive();
|
||||
rlDisableBackfaceCulling();
|
||||
|
||||
for (int l = 0; l < draw_data->CmdListsCount; ++l)
|
||||
{
|
||||
const ImDrawList *commandList = draw_data->CmdLists[l];
|
||||
|
||||
for (const auto &cmd : commandList->CmdBuffer)
|
||||
{
|
||||
EnableScissor(cmd.ClipRect.x - draw_data->DisplayPos.x, cmd.ClipRect.y - draw_data->DisplayPos.y, cmd.ClipRect.z - (cmd.ClipRect.x - draw_data->DisplayPos.x), cmd.ClipRect.w - (cmd.ClipRect.y - draw_data->DisplayPos.y));
|
||||
if (cmd.UserCallback != nullptr)
|
||||
{
|
||||
cmd.UserCallback(commandList, &cmd);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGuiRenderTriangles(cmd.ElemCount, cmd.IdxOffset, commandList->IdxBuffer, commandList->VtxBuffer, (Texture2D *)cmd.TextureId);
|
||||
rlDrawRenderBatchActive();
|
||||
}
|
||||
}
|
||||
|
||||
rlSetTexture(0);
|
||||
rlDisableScissorTest();
|
||||
rlEnableBackfaceCulling();
|
||||
}
|
||||
|
||||
void HandleGamepadButtonEvent(ImGuiIO &io, GamepadButton button, ImGuiKey key)
|
||||
{
|
||||
if (IsGamepadButtonPressed(0, button))
|
||||
io.AddKeyEvent(key, true);
|
||||
else if (IsGamepadButtonReleased(0, button))
|
||||
io.AddKeyEvent(key, false);
|
||||
}
|
||||
|
||||
void HandleGamepadStickEvent(ImGuiIO &io, GamepadAxis axis, ImGuiKey negKey, ImGuiKey posKey)
|
||||
{
|
||||
constexpr float deadZone = 0.20f;
|
||||
|
||||
float axisValue = GetGamepadAxisMovement(0, axis);
|
||||
|
||||
io.AddKeyAnalogEvent(negKey, axisValue < -deadZone, axisValue < -deadZone ? -axisValue : 0);
|
||||
io.AddKeyAnalogEvent(posKey, axisValue > deadZone, axisValue > deadZone ? axisValue : 0);
|
||||
}
|
||||
|
||||
bool ImGui_ImplRaylib_ProcessEvents(void)
|
||||
{
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
bool focused = IsWindowFocused();
|
||||
if (focused != LastFrameFocused)
|
||||
io.AddFocusEvent(focused);
|
||||
LastFrameFocused = focused;
|
||||
|
||||
// handle the modifyer key events so that shortcuts work
|
||||
bool ctrlDown = rlImGuiIsControlDown();
|
||||
if (ctrlDown != LastControlPressed)
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, ctrlDown);
|
||||
LastControlPressed = ctrlDown;
|
||||
|
||||
bool shiftDown = rlImGuiIsShiftDown();
|
||||
if (shiftDown != LastShiftPressed)
|
||||
io.AddKeyEvent(ImGuiMod_Shift, shiftDown);
|
||||
LastShiftPressed = shiftDown;
|
||||
|
||||
bool altDown = rlImGuiIsAltDown();
|
||||
if (altDown != LastAltPressed)
|
||||
io.AddKeyEvent(ImGuiMod_Alt, altDown);
|
||||
LastAltPressed = altDown;
|
||||
|
||||
bool superDown = rlImGuiIsSuperDown();
|
||||
if (superDown != LastSuperPressed)
|
||||
io.AddKeyEvent(ImGuiMod_Super, superDown);
|
||||
LastSuperPressed = superDown;
|
||||
|
||||
// walk the keymap and check for up and down events
|
||||
for (const auto keyItr : RaylibKeyMap)
|
||||
{
|
||||
if (IsKeyReleased(keyItr.first))
|
||||
io.AddKeyEvent(keyItr.second, false);
|
||||
else if (IsKeyPressed(keyItr.first))
|
||||
io.AddKeyEvent(keyItr.second, true);
|
||||
}
|
||||
|
||||
if (io.WantCaptureKeyboard)
|
||||
{
|
||||
// add the text input in order
|
||||
unsigned int pressed = GetCharPressed();
|
||||
while (pressed != 0)
|
||||
{
|
||||
io.AddInputCharacter(pressed);
|
||||
pressed = GetCharPressed();
|
||||
}
|
||||
}
|
||||
|
||||
if (!io.WantSetMousePos)
|
||||
{
|
||||
io.AddMousePosEvent((float)GetMouseX(), (float)GetMouseY());
|
||||
}
|
||||
|
||||
auto setMouseEvent = [&io](int rayMouse, int imGuiMouse)
|
||||
{
|
||||
if (IsMouseButtonPressed(rayMouse))
|
||||
io.AddMouseButtonEvent(imGuiMouse, true);
|
||||
else if (IsMouseButtonReleased(rayMouse))
|
||||
io.AddMouseButtonEvent(imGuiMouse, false);
|
||||
};
|
||||
|
||||
setMouseEvent(MOUSE_BUTTON_LEFT, ImGuiMouseButton_Left);
|
||||
setMouseEvent(MOUSE_BUTTON_RIGHT, ImGuiMouseButton_Right);
|
||||
setMouseEvent(MOUSE_BUTTON_MIDDLE, ImGuiMouseButton_Middle);
|
||||
setMouseEvent(MOUSE_BUTTON_FORWARD, ImGuiMouseButton_Middle + 1);
|
||||
setMouseEvent(MOUSE_BUTTON_BACK, ImGuiMouseButton_Middle + 2);
|
||||
|
||||
{
|
||||
Vector2 mouseWheel = GetMouseWheelMoveV();
|
||||
io.AddMouseWheelEvent(mouseWheel.x, mouseWheel.y);
|
||||
}
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad && IsGamepadAvailable(0))
|
||||
{
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_UP, ImGuiKey_GamepadDpadUp);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_RIGHT, ImGuiKey_GamepadDpadRight);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_DOWN, ImGuiKey_GamepadDpadDown);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_LEFT, ImGuiKey_GamepadDpadLeft);
|
||||
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_UP, ImGuiKey_GamepadFaceUp);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, ImGuiKey_GamepadFaceLeft);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_DOWN, ImGuiKey_GamepadFaceDown);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_LEFT, ImGuiKey_GamepadFaceRight);
|
||||
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_TRIGGER_1, ImGuiKey_GamepadL1);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_TRIGGER_2, ImGuiKey_GamepadL2);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_TRIGGER_1, ImGuiKey_GamepadR1);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_TRIGGER_2, ImGuiKey_GamepadR2);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_THUMB, ImGuiKey_GamepadL3);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_THUMB, ImGuiKey_GamepadR3);
|
||||
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_MIDDLE_LEFT, ImGuiKey_GamepadStart);
|
||||
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_MIDDLE_RIGHT, ImGuiKey_GamepadBack);
|
||||
|
||||
// left stick
|
||||
HandleGamepadStickEvent(io, GAMEPAD_AXIS_LEFT_X, ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight);
|
||||
HandleGamepadStickEvent(io, GAMEPAD_AXIS_LEFT_Y, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown);
|
||||
|
||||
// right stick
|
||||
HandleGamepadStickEvent(io, GAMEPAD_AXIS_RIGHT_X, ImGuiKey_GamepadRStickLeft, ImGuiKey_GamepadRStickRight);
|
||||
HandleGamepadStickEvent(io, GAMEPAD_AXIS_RIGHT_Y, ImGuiKey_GamepadRStickUp, ImGuiKey_GamepadRStickDown);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
200
imgui_raylib/rlImGui.h
Normal file
200
imgui_raylib/rlImGui.h
Normal file
@ -0,0 +1,200 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylibExtras * Utilities and Shared Components for Raylib
|
||||
*
|
||||
* rlImGui * basic ImGui integration
|
||||
*
|
||||
* LICENSE: ZLIB
|
||||
*
|
||||
* Copyright (c) 2024 Jeffery Myers
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
// Function specifiers in case library is build/used as a shared library
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
// NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden
|
||||
#if defined(_WIN32)
|
||||
#if defined(__TINYC__)
|
||||
#define __declspec(x) __attribute__((x))
|
||||
#endif
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RLIMGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
|
||||
#elif defined(USE_LIBTYPE_SHARED)
|
||||
#define RLIMGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
|
||||
#endif
|
||||
#else
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RLIMGUIAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RLIMGUIAPI
|
||||
#define RLIMGUIAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||
#endif
|
||||
|
||||
#ifndef NO_FONT_AWESOME
|
||||
#include "IconsFontAwesome6.h"
|
||||
#ifndef FONT_AWESOME_ICON_SIZE
|
||||
#define FONT_AWESOME_ICON_SIZE 11
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// High level API. This API is designed in the style of raylib and meant to work with reaylib code.
|
||||
// It will manage it's own ImGui context and call common ImGui functions (like NewFrame and Render) for you
|
||||
// for a lower level API that matches the other ImGui platforms, please see imgui_impl_raylib.h
|
||||
|
||||
/// <summary>
|
||||
/// Sets up ImGui, loads fonts and themes
|
||||
/// Calls ImGui_ImplRaylib_Init and sets the theme. Will install Font awesome by default
|
||||
/// </summary>
|
||||
/// <param name="darkTheme">when true(default) the dark theme is used, when false the light theme is used</param>
|
||||
RLIMGUIAPI void rlImGuiSetup(bool darkTheme);
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new ImGui Frame
|
||||
/// Calls ImGui_ImplRaylib_NewFrame, ImGui_ImplRaylib_ProcessEvents, and ImGui::NewFrame together
|
||||
/// </summary>
|
||||
RLIMGUIAPI void rlImGuiBegin(void);
|
||||
|
||||
/// <summary>
|
||||
/// Ends an ImGui frame and submits all ImGui drawing to raylib for processing.
|
||||
/// Calls ImGui:Render, an d ImGui_ImplRaylib_RenderDrawData to draw to the current raylib render target
|
||||
/// </summary>
|
||||
RLIMGUIAPI void rlImGuiEnd(void);
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup ImGui and unload font atlas
|
||||
/// Calls ImGui_ImplRaylib_Shutdown
|
||||
/// </summary>
|
||||
RLIMGUIAPI void rlImGuiShutdown(void);
|
||||
|
||||
// Advanced StartupAPI
|
||||
|
||||
/// <summary>
|
||||
/// Custom initialization. Not needed if you call rlImGuiSetup. Only needed if you want to add custom setup code.
|
||||
/// must be followed by rlImGuiEndInitImGui
|
||||
/// Called by ImGui_ImplRaylib_Init, and does the first part of setup, before fonts are rendered
|
||||
/// </summary>
|
||||
RLIMGUIAPI void rlImGuiBeginInitImGui(void);
|
||||
|
||||
/// <summary>
|
||||
/// End Custom initialization. Not needed if you call rlImGuiSetup. Only needed if you want to add custom setup code.
|
||||
/// must be proceeded by rlImGuiBeginInitImGui
|
||||
/// Called by ImGui_ImplRaylib_Init and does the second part of setup, and renders fonts.
|
||||
/// </summary>
|
||||
RLIMGUIAPI void rlImGuiEndInitImGui(void);
|
||||
|
||||
/// <summary>
|
||||
/// Forces the font texture atlas to be recomputed and re-cached
|
||||
/// </summary>
|
||||
RLIMGUIAPI void rlImGuiReloadFonts(void);
|
||||
|
||||
// Advanced Update API
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new ImGui Frame with a specified delta time
|
||||
/// </summary>
|
||||
/// <param name="dt">delta time, any value < 0 will use raylib GetFrameTime</param>
|
||||
RLIMGUIAPI void rlImGuiBeginDelta(float deltaTime);
|
||||
|
||||
// ImGui Image API extensions
|
||||
// Purely for convenience in working with raylib textures as images.
|
||||
// If you want to call ImGui image functions directly, simply pass them the pointer to the texture.
|
||||
|
||||
/// <summary>
|
||||
/// Draw a texture as an image in an ImGui Context
|
||||
/// Uses the current ImGui Cursor position and the full texture size.
|
||||
/// </summary>
|
||||
/// <param name="image">The raylib texture to draw</param>
|
||||
RLIMGUIAPI void rlImGuiImage(const Texture *image);
|
||||
|
||||
/// <summary>
|
||||
/// Draw a texture as an image in an ImGui Context at a specific size
|
||||
/// Uses the current ImGui Cursor position and the specified width and height
|
||||
/// The image will be scaled up or down to fit as needed
|
||||
/// </summary>
|
||||
/// <param name="image">The raylib texture to draw</param>
|
||||
/// <param name="width">The width of the drawn image</param>
|
||||
/// <param name="height">The height of the drawn image</param>
|
||||
RLIMGUIAPI void rlImGuiImageSize(const Texture *image, int width, int height);
|
||||
|
||||
/// <summary>
|
||||
/// Draw a texture as an image in an ImGui Context at a specific size
|
||||
/// Uses the current ImGui Cursor position and the specified size
|
||||
/// The image will be scaled up or down to fit as needed
|
||||
/// </summary>
|
||||
/// <param name="image">The raylib texture to draw</param>
|
||||
/// <param name="size">The size of drawn image</param>
|
||||
RLIMGUIAPI void rlImGuiImageSizeV(const Texture* image, Vector2 size);
|
||||
|
||||
/// <summary>
|
||||
/// Draw a portion texture as an image in an ImGui Context at a defined size
|
||||
/// Uses the current ImGui Cursor position and the specified size
|
||||
/// The image will be scaled up or down to fit as needed
|
||||
/// </summary>
|
||||
/// <param name="image">The raylib texture to draw</param>
|
||||
/// <param name="destWidth">The width of the drawn image</param>
|
||||
/// <param name="destHeight">The height of the drawn image</param>
|
||||
/// <param name="sourceRect">The portion of the texture to draw as an image. Negative values for the width and height will flip the image</param>
|
||||
RLIMGUIAPI void rlImGuiImageRect(const Texture* image, int destWidth, int destHeight, Rectangle sourceRect);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a render texture as an image an ImGui Context, automatically flipping the Y axis so it will show correctly on screen
|
||||
/// </summary>
|
||||
/// <param name="image">The render texture to draw</param>
|
||||
RLIMGUIAPI void rlImGuiImageRenderTexture(const RenderTexture* image);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a render texture as an image an ImGui Context, automatically flipping the Y axis so it will show correctly on screen
|
||||
/// Fits the render texture to the available content area
|
||||
/// </summary>
|
||||
/// <param name="image">The render texture to draw</param>
|
||||
/// <param name="center">When true the image will be centered in the content area</param>
|
||||
RLIMGUIAPI void rlImGuiImageRenderTextureFit(const RenderTexture* image, bool center);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a texture as an image button in an ImGui context. Uses the current ImGui cursor position and the full size of the texture
|
||||
/// </summary>
|
||||
/// <param name="name">The display name and ImGui ID for the button</param>
|
||||
/// <param name="image">The texture to draw</param>
|
||||
/// <returns>True if the button was clicked</returns>
|
||||
bool rlImGuiImageButton(const char* name, const Texture* image);
|
||||
|
||||
/// <summary>
|
||||
/// Draws a texture as an image button in an ImGui context. Uses the current ImGui cursor position and the specified size.
|
||||
/// </summary>
|
||||
/// <param name="name">The display name and ImGui ID for the button</param>
|
||||
/// <param name="image">The texture to draw</param>
|
||||
/// <param name="size">The size of the button</param>
|
||||
/// <returns>True if the button was clicked</returns>
|
||||
RLIMGUIAPI bool rlImGuiImageButtonSize(const char* name, const Texture* image, struct ImVec2 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
47
imgui_raylib/rlImGuiColors.h
Normal file
47
imgui_raylib/rlImGuiColors.h
Normal file
@ -0,0 +1,47 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylibExtras * Utilities and Shared Components for Raylib
|
||||
*
|
||||
* rlImGui * basic ImGui integration
|
||||
*
|
||||
* LICENSE: ZLIB
|
||||
*
|
||||
* Copyright (c) 2024 Jeffery Myers
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "raylib.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace rlImGuiColors
|
||||
{
|
||||
inline ImVec4 Convert(::Color color)
|
||||
{
|
||||
return ImVec4(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
|
||||
}
|
||||
|
||||
inline ::Color Convert(ImVec4 color)
|
||||
{
|
||||
return ::Color{ (unsigned char)(color.x * 255.0f), (unsigned char)(color.y * 255.0f), (unsigned char)(color.z * 255.0f), (unsigned char)(color.w * 255.0f) };
|
||||
}
|
||||
}
|
302
raylib/config.h
Normal file
302
raylib/config.h
Normal file
@ -0,0 +1,302 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib configuration flags
|
||||
*
|
||||
* This file defines all the configuration flags for the different raylib modules
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2018-2025 Ahmad Fatoum & Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module selection - Some modules could be avoided
|
||||
// Mandatory modules: rcore, rlgl, utils
|
||||
//------------------------------------------------------------------------------------
|
||||
#define SUPPORT_MODULE_RSHAPES 1
|
||||
#define SUPPORT_MODULE_RTEXTURES 1
|
||||
#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures
|
||||
#define SUPPORT_MODULE_RMODELS 1
|
||||
#define SUPPORT_MODULE_RAUDIO 1
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rcore - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
|
||||
#define SUPPORT_CAMERA_SYSTEM 1
|
||||
// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
|
||||
#define SUPPORT_GESTURES_SYSTEM 1
|
||||
// Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64
|
||||
#define SUPPORT_RPRAND_GENERATOR 1
|
||||
// Mouse gestures are directly mapped like touches and processed by gestures system
|
||||
#define SUPPORT_MOUSE_GESTURES 1
|
||||
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||
#define SUPPORT_WINMM_HIGHRES_TIMER 1
|
||||
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used
|
||||
//#define SUPPORT_BUSY_WAIT_LOOP 1
|
||||
// Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy
|
||||
#define SUPPORT_PARTIALBUSY_WAIT_LOOP 1
|
||||
// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
|
||||
#define SUPPORT_SCREEN_CAPTURE 1
|
||||
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
|
||||
#define SUPPORT_GIF_RECORDING 1
|
||||
// Support CompressData() and DecompressData() functions
|
||||
#define SUPPORT_COMPRESSION_API 1
|
||||
// Support automatic generated events, loading and recording of those events when required
|
||||
#define SUPPORT_AUTOMATION_EVENTS 1
|
||||
// Support custom frame control, only for advanced users
|
||||
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
|
||||
// Enabling this flag allows manual control of the frame processes, use at your own risk
|
||||
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1
|
||||
|
||||
// Support for clipboard image loading
|
||||
// NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows)
|
||||
#define SUPPORT_CLIPBOARD_IMAGE 1
|
||||
|
||||
// NOTE: Clipboard image loading requires support for some image file formats
|
||||
// TODO: Those defines should probably be removed from here, I prefer to let the user manage them
|
||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
||||
#ifndef SUPPORT_MODULE_RTEXTURES
|
||||
#define SUPPORT_MODULE_RTEXTURES 1
|
||||
#endif
|
||||
#ifndef STBI_REQUIRED
|
||||
#define STBI_REQUIRED
|
||||
#endif
|
||||
#ifndef SUPPORT_FILEFORMAT_BMP // For clipboard image on Windows
|
||||
#define SUPPORT_FILEFORMAT_BMP 1
|
||||
#endif
|
||||
#ifndef SUPPORT_FILEFORMAT_PNG // Wayland uses png for prints, at least it was on 22 LTS ubuntu
|
||||
#define SUPPORT_FILEFORMAT_PNG 1
|
||||
#endif
|
||||
#ifndef SUPPORT_FILEFORMAT_JPG
|
||||
#define SUPPORT_FILEFORMAT_JPG 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// rcore: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity
|
||||
#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
|
||||
|
||||
#define MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported
|
||||
#define MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported
|
||||
#define MAX_GAMEPADS 4 // Maximum number of gamepads supported
|
||||
#define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad)
|
||||
#define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad)
|
||||
#define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds
|
||||
#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported
|
||||
#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue
|
||||
#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue
|
||||
|
||||
#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB
|
||||
|
||||
#define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rlgl - Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Enable OpenGL Debug Context (only available on OpenGL 4.3)
|
||||
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1
|
||||
|
||||
// Show OpenGL extensions and capabilities detailed logs on init
|
||||
//#define RLGL_SHOW_GL_DETAILS_INFO 1
|
||||
|
||||
#define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs
|
||||
|
||||
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
|
||||
#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
|
||||
#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
|
||||
#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture())
|
||||
|
||||
#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack
|
||||
|
||||
#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
|
||||
|
||||
#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance
|
||||
#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance
|
||||
|
||||
// Default shader vertex attribute locations
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
||||
#if defined(RL_SUPPORT_MESH_GPU_SKINNING)
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
|
||||
#endif
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX 9
|
||||
|
||||
|
||||
// Default shader vertex attribute names to set location points
|
||||
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
||||
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rshapes - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Use QUADS instead of TRIANGLES for drawing when possible
|
||||
// Some lines-based shapes could still use lines
|
||||
#define SUPPORT_QUADS_DRAW_MODE 1
|
||||
|
||||
// rshapes: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define SPLINE_SEGMENT_DIVISIONS 24 // Spline segments subdivisions
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rtextures - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Selecte desired fileformats to be supported for image data loading
|
||||
#define SUPPORT_FILEFORMAT_PNG 1
|
||||
//#define SUPPORT_FILEFORMAT_BMP 1
|
||||
//#define SUPPORT_FILEFORMAT_TGA 1
|
||||
//#define SUPPORT_FILEFORMAT_JPG 1
|
||||
#define SUPPORT_FILEFORMAT_GIF 1
|
||||
#define SUPPORT_FILEFORMAT_QOI 1
|
||||
//#define SUPPORT_FILEFORMAT_PSD 1
|
||||
#define SUPPORT_FILEFORMAT_DDS 1
|
||||
//#define SUPPORT_FILEFORMAT_HDR 1
|
||||
//#define SUPPORT_FILEFORMAT_PIC 1
|
||||
//#define SUPPORT_FILEFORMAT_KTX 1
|
||||
//#define SUPPORT_FILEFORMAT_ASTC 1
|
||||
//#define SUPPORT_FILEFORMAT_PKM 1
|
||||
//#define SUPPORT_FILEFORMAT_PVR 1
|
||||
|
||||
// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi)
|
||||
#define SUPPORT_IMAGE_EXPORT 1
|
||||
// Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)
|
||||
#define SUPPORT_IMAGE_GENERATION 1
|
||||
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
|
||||
// If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT()
|
||||
#define SUPPORT_IMAGE_MANIPULATION 1
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rtext - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Default font is loaded on window initialization to be available for the user to render simple text
|
||||
// NOTE: If enabled, uses external module functions to load default raylib font
|
||||
#define SUPPORT_DEFAULT_FONT 1
|
||||
// Selected desired font fileformats to be supported for loading
|
||||
#define SUPPORT_FILEFORMAT_TTF 1
|
||||
#define SUPPORT_FILEFORMAT_FNT 1
|
||||
//#define SUPPORT_FILEFORMAT_BDF 1
|
||||
|
||||
// Support text management functions
|
||||
// If not defined, still some functions are supported: TextLength(), TextFormat()
|
||||
#define SUPPORT_TEXT_MANIPULATION 1
|
||||
|
||||
// On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle
|
||||
// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
|
||||
// drawing text and shapes with a single draw call [SetShapesTexture()].
|
||||
#define SUPPORT_FONT_ATLAS_WHITE_REC 1
|
||||
|
||||
// rtext: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
|
||||
// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
|
||||
#define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rmodels - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Selected desired model fileformats to be supported for loading
|
||||
#define SUPPORT_FILEFORMAT_OBJ 1
|
||||
#define SUPPORT_FILEFORMAT_MTL 1
|
||||
#define SUPPORT_FILEFORMAT_IQM 1
|
||||
#define SUPPORT_FILEFORMAT_GLTF 1
|
||||
#define SUPPORT_FILEFORMAT_VOX 1
|
||||
#define SUPPORT_FILEFORMAT_M3D 1
|
||||
// Support procedural mesh generation functions, uses external par_shapes.h library
|
||||
// NOTE: Some generated meshes DO NOT include generated texture coordinates
|
||||
#define SUPPORT_MESH_GENERATION 1
|
||||
|
||||
// rmodels: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
|
||||
|
||||
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||
#define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh
|
||||
#else
|
||||
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: raudio - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Desired audio fileformats to be supported for loading
|
||||
#define SUPPORT_FILEFORMAT_WAV 1
|
||||
#define SUPPORT_FILEFORMAT_OGG 1
|
||||
#define SUPPORT_FILEFORMAT_MP3 1
|
||||
#define SUPPORT_FILEFORMAT_QOA 1
|
||||
//#define SUPPORT_FILEFORMAT_FLAC 1
|
||||
#define SUPPORT_FILEFORMAT_XM 1
|
||||
#define SUPPORT_FILEFORMAT_MOD 1
|
||||
|
||||
// raudio: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit)
|
||||
#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
|
||||
#define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default)
|
||||
|
||||
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: utils - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Standard file io library (stdio.h) included
|
||||
#define SUPPORT_STANDARD_FILEIO 1
|
||||
// Show TRACELOG() output messages
|
||||
// NOTE: By default LOG_DEBUG traces not shown
|
||||
#define SUPPORT_TRACELOG 1
|
||||
//#define SUPPORT_TRACELOG_DEBUG 1
|
||||
|
||||
// utils: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
|
||||
|
||||
#endif // CONFIG_H
|
9897
raylib/external/RGFW.h
vendored
Normal file
9897
raylib/external/RGFW.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7081
raylib/external/cgltf.h
vendored
Normal file
7081
raylib/external/cgltf.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
183
raylib/external/dirent.h
vendored
Normal file
183
raylib/external/dirent.h
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
/****************************************************************************
|
||||
|
||||
Declaration of POSIX directory browsing functions and types for Win32.
|
||||
|
||||
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
|
||||
History: Created March 1997. Updated June 2003.
|
||||
Reviewed by Ramon Santamaria for raylib on January 2020.
|
||||
|
||||
Copyright Kevlin Henney, 1997, 2003. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided
|
||||
that this copyright and permissions notice appear in all copies and
|
||||
derivatives.
|
||||
|
||||
This software is supplied "as is" without express or implied warranty.
|
||||
|
||||
But that said, if there are any problems please get in touch.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DIRENT_H
|
||||
#define DIRENT_H
|
||||
|
||||
// Allow custom memory allocators
|
||||
#ifndef DIRENT_MALLOC
|
||||
#define DIRENT_MALLOC(sz) malloc(sz)
|
||||
#endif
|
||||
#ifndef DIRENT_FREE
|
||||
#define DIRENT_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Fordward declaration of DIR, implementation below
|
||||
typedef struct DIR DIR;
|
||||
|
||||
struct dirent {
|
||||
char *d_name;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
DIR *opendir(const char *name);
|
||||
int closedir(DIR *dir);
|
||||
struct dirent *readdir(DIR *dir);
|
||||
void rewinddir(DIR *dir);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // DIRENT_H
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
Implementation of POSIX directory browsing functions and types for Win32.
|
||||
|
||||
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
|
||||
History: Created March 1997. Updated June 2003.
|
||||
Reviewed by Ramon Santamaria for raylib on January 2020.
|
||||
|
||||
Copyright Kevlin Henney, 1997, 2003. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided
|
||||
that this copyright and permissions notice appear in all copies and
|
||||
derivatives.
|
||||
|
||||
This software is supplied "as is" without express or implied warranty.
|
||||
|
||||
But that said, if there are any problems please get in touch.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <io.h> // _findfirst and _findnext set errno iff they return -1
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef ptrdiff_t handle_type; // C99's intptr_t not sufficiently portable
|
||||
|
||||
struct DIR {
|
||||
handle_type handle; // -1 for failed rewind
|
||||
struct _finddata_t info;
|
||||
struct dirent result; // d_name null iff first time
|
||||
char *name; // null-terminated char string
|
||||
};
|
||||
|
||||
DIR *opendir(const char *name)
|
||||
{
|
||||
DIR *dir = 0;
|
||||
|
||||
if (name && name[0])
|
||||
{
|
||||
size_t base_length = strlen(name);
|
||||
|
||||
// Search pattern must end with suitable wildcard
|
||||
const char *all = strchr("/\\", name[base_length - 1]) ? "*" : "/*";
|
||||
|
||||
if ((dir = (DIR *)DIRENT_MALLOC(sizeof *dir)) != 0 &&
|
||||
(dir->name = (char *)DIRENT_MALLOC(base_length + strlen(all) + 1)) != 0)
|
||||
{
|
||||
strcat(strcpy(dir->name, name), all);
|
||||
|
||||
if ((dir->handle = (handle_type) _findfirst(dir->name, &dir->info)) != -1)
|
||||
{
|
||||
dir->result.d_name = 0;
|
||||
}
|
||||
else // rollback
|
||||
{
|
||||
DIRENT_FREE(dir->name);
|
||||
DIRENT_FREE(dir);
|
||||
dir = 0;
|
||||
}
|
||||
}
|
||||
else // rollback
|
||||
{
|
||||
DIRENT_FREE(dir);
|
||||
dir = 0;
|
||||
errno = ENOMEM;
|
||||
}
|
||||
}
|
||||
else errno = EINVAL;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
int closedir(DIR *dir)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (dir)
|
||||
{
|
||||
if (dir->handle != -1) result = _findclose(dir->handle);
|
||||
|
||||
DIRENT_FREE(dir->name);
|
||||
DIRENT_FREE(dir);
|
||||
}
|
||||
|
||||
// NOTE: All errors ampped to EBADF
|
||||
if (result == -1) errno = EBADF;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *dir)
|
||||
{
|
||||
struct dirent *result = 0;
|
||||
|
||||
if (dir && dir->handle != -1)
|
||||
{
|
||||
if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
|
||||
{
|
||||
result = &dir->result;
|
||||
result->d_name = dir->info.name;
|
||||
}
|
||||
}
|
||||
else errno = EBADF;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void rewinddir(DIR *dir)
|
||||
{
|
||||
if (dir && dir->handle != -1)
|
||||
{
|
||||
_findclose(dir->handle);
|
||||
dir->handle = (handle_type) _findfirst(dir->name, &dir->info);
|
||||
dir->result.d_name = 0;
|
||||
}
|
||||
else errno = EBADF;
|
||||
}
|
12536
raylib/external/dr_flac.h
vendored
Normal file
12536
raylib/external/dr_flac.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4837
raylib/external/dr_mp3.h
vendored
Normal file
4837
raylib/external/dr_mp3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8815
raylib/external/dr_wav.h
vendored
Normal file
8815
raylib/external/dr_wav.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8682
raylib/external/glad.h
vendored
Normal file
8682
raylib/external/glad.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4774
raylib/external/glad_gles2.h
vendored
Normal file
4774
raylib/external/glad_gles2.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
230
raylib/external/glfw/deps/getopt.c
vendored
Normal file
230
raylib/external/glfw/deps/getopt.c
vendored
Normal file
@ -0,0 +1,230 @@
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
const int no_argument = 0;
|
||||
const int required_argument = 1;
|
||||
const int optional_argument = 2;
|
||||
|
||||
char* optarg;
|
||||
int optopt;
|
||||
/* The variable optind [...] shall be initialized to 1 by the system. */
|
||||
int optind = 1;
|
||||
int opterr;
|
||||
|
||||
static char* optcursor = NULL;
|
||||
|
||||
/* Implemented based on [1] and [2] for optional arguments.
|
||||
optopt is handled FreeBSD-style, per [3].
|
||||
Other GNU and FreeBSD extensions are purely accidental.
|
||||
|
||||
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
|
||||
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
|
||||
*/
|
||||
int getopt(int argc, char* const argv[], const char* optstring) {
|
||||
int optchar = -1;
|
||||
const char* optdecl = NULL;
|
||||
|
||||
optarg = NULL;
|
||||
opterr = 0;
|
||||
optopt = 0;
|
||||
|
||||
/* Unspecified, but we need it to avoid overrunning the argv bounds. */
|
||||
if (optind >= argc)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
|
||||
shall return -1 without changing optind. */
|
||||
if (argv[optind] == NULL)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called *argv[optind] is not the character '-',
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (*argv[optind] != '-')
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "-",
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (strcmp(argv[optind], "-") == 0)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "--",
|
||||
getopt() shall return -1 after incrementing optind. */
|
||||
if (strcmp(argv[optind], "--") == 0) {
|
||||
++optind;
|
||||
goto no_more_optchars;
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *optcursor == '\0')
|
||||
optcursor = argv[optind] + 1;
|
||||
|
||||
optchar = *optcursor;
|
||||
|
||||
/* FreeBSD: The variable optopt saves the last known option character
|
||||
returned by getopt(). */
|
||||
optopt = optchar;
|
||||
|
||||
/* The getopt() function shall return the next option character (if one is
|
||||
found) from argv that matches a character in optstring, if there is
|
||||
one that matches. */
|
||||
optdecl = strchr(optstring, optchar);
|
||||
if (optdecl) {
|
||||
/* [I]f a character is followed by a colon, the option takes an
|
||||
argument. */
|
||||
if (optdecl[1] == ':') {
|
||||
optarg = ++optcursor;
|
||||
if (*optarg == '\0') {
|
||||
/* GNU extension: Two colons mean an option takes an
|
||||
optional arg; if there is text in the current argv-element
|
||||
(i.e., in the same word as the option name itself, for example,
|
||||
"-oarg"), then it is returned in optarg, otherwise optarg is set
|
||||
to zero. */
|
||||
if (optdecl[2] != ':') {
|
||||
/* If the option was the last character in the string pointed to by
|
||||
an element of argv, then optarg shall contain the next element
|
||||
of argv, and optind shall be incremented by 2. If the resulting
|
||||
value of optind is greater than argc, this indicates a missing
|
||||
option-argument, and getopt() shall return an error indication.
|
||||
|
||||
Otherwise, optarg shall point to the string following the
|
||||
option character in that element of argv, and optind shall be
|
||||
incremented by 1.
|
||||
*/
|
||||
if (++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
} else {
|
||||
/* If it detects a missing option-argument, it shall return the
|
||||
colon character ( ':' ) if the first character of optstring
|
||||
was a colon, or a question-mark character ( '?' ) otherwise.
|
||||
*/
|
||||
optarg = NULL;
|
||||
optchar = (optstring[0] == ':') ? ':' : '?';
|
||||
}
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
optcursor = NULL;
|
||||
}
|
||||
} else {
|
||||
/* If getopt() encounters an option character that is not contained in
|
||||
optstring, it shall return the question-mark ( '?' ) character. */
|
||||
optchar = '?';
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *++optcursor == '\0')
|
||||
++optind;
|
||||
|
||||
return optchar;
|
||||
|
||||
no_more_optchars:
|
||||
optcursor = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Implementation based on [1].
|
||||
|
||||
[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
*/
|
||||
int getopt_long(int argc, char* const argv[], const char* optstring,
|
||||
const struct option* longopts, int* longindex) {
|
||||
const struct option* o = longopts;
|
||||
const struct option* match = NULL;
|
||||
int num_matches = 0;
|
||||
size_t argument_name_length = 0;
|
||||
const char* current_argument = NULL;
|
||||
int retval = -1;
|
||||
|
||||
optarg = NULL;
|
||||
optopt = 0;
|
||||
|
||||
if (optind >= argc)
|
||||
return -1;
|
||||
|
||||
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
|
||||
return getopt(argc, argv, optstring);
|
||||
|
||||
/* It's an option; starts with -- and is longer than two chars. */
|
||||
current_argument = argv[optind] + 2;
|
||||
argument_name_length = strcspn(current_argument, "=");
|
||||
for (; o->name; ++o) {
|
||||
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
|
||||
match = o;
|
||||
++num_matches;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_matches == 1) {
|
||||
/* If longindex is not NULL, it points to a variable which is set to the
|
||||
index of the long option relative to longopts. */
|
||||
if (longindex)
|
||||
*longindex = (int) (match - longopts);
|
||||
|
||||
/* If flag is NULL, then getopt_long() shall return val.
|
||||
Otherwise, getopt_long() returns 0, and flag shall point to a variable
|
||||
which shall be set to val if the option is found, but left unchanged if
|
||||
the option is not found. */
|
||||
if (match->flag)
|
||||
*(match->flag) = match->val;
|
||||
|
||||
retval = match->flag ? 0 : match->val;
|
||||
|
||||
if (match->has_arg != no_argument) {
|
||||
optarg = strchr(argv[optind], '=');
|
||||
if (optarg != NULL)
|
||||
++optarg;
|
||||
|
||||
if (match->has_arg == required_argument) {
|
||||
/* Only scan the next argv for required arguments. Behavior is not
|
||||
specified, but has been observed with Ubuntu and Mac OSX. */
|
||||
if (optarg == NULL && ++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
}
|
||||
|
||||
if (optarg == NULL)
|
||||
retval = ':';
|
||||
}
|
||||
} else if (strchr(argv[optind], '=')) {
|
||||
/* An argument was provided to a non-argument option.
|
||||
I haven't seen this specified explicitly, but both GNU and BSD-based
|
||||
implementations show this behavior.
|
||||
*/
|
||||
retval = '?';
|
||||
}
|
||||
} else {
|
||||
/* Unknown option or ambiguous match. */
|
||||
retval = '?';
|
||||
}
|
||||
|
||||
++optind;
|
||||
return retval;
|
||||
}
|
57
raylib/external/glfw/deps/getopt.h
vendored
Normal file
57
raylib/external/glfw/deps/getopt.h
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GETOPT_PORT_H
|
||||
#define INCLUDED_GETOPT_PORT_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const int no_argument;
|
||||
extern const int required_argument;
|
||||
extern const int optional_argument;
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
struct option {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
int getopt(int argc, char* const argv[], const char* optstring);
|
||||
|
||||
int getopt_long(int argc, char* const argv[],
|
||||
const char* optstring, const struct option* longopts, int* longindex);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // INCLUDED_GETOPT_PORT_H
|
5996
raylib/external/glfw/deps/glad/gl.h
vendored
Normal file
5996
raylib/external/glfw/deps/glad/gl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1805
raylib/external/glfw/deps/glad/gles2.h
vendored
Normal file
1805
raylib/external/glfw/deps/glad/gles2.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6330
raylib/external/glfw/deps/glad/vulkan.h
vendored
Normal file
6330
raylib/external/glfw/deps/glad/vulkan.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
117
raylib/external/glfw/deps/mingw/_mingw_dxhelper.h
vendored
Normal file
117
raylib/external/glfw/deps/mingw/_mingw_dxhelper.h
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
|
||||
#define NONAMELESSUNION 1
|
||||
#endif
|
||||
#if defined(NONAMELESSSTRUCT) && \
|
||||
!defined(NONAMELESSUNION)
|
||||
#define NONAMELESSUNION 1
|
||||
#endif
|
||||
#if defined(NONAMELESSUNION) && \
|
||||
!defined(NONAMELESSSTRUCT)
|
||||
#define NONAMELESSSTRUCT 1
|
||||
#endif
|
||||
#if !defined(__GNU_EXTENSION)
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define __GNU_EXTENSION __extension__
|
||||
#else
|
||||
#define __GNU_EXTENSION
|
||||
#endif
|
||||
#endif /* __extension__ */
|
||||
|
||||
#ifndef __ANONYMOUS_DEFINED
|
||||
#define __ANONYMOUS_DEFINED
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#define _ANONYMOUS_STRUCT __extension__
|
||||
#else
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#endif
|
||||
#ifndef NONAMELESSUNION
|
||||
#define _UNION_NAME(x)
|
||||
#define _STRUCT_NAME(x)
|
||||
#else /* NONAMELESSUNION */
|
||||
#define _UNION_NAME(x) x
|
||||
#define _STRUCT_NAME(x) x
|
||||
#endif
|
||||
#endif /* __ANONYMOUS_DEFINED */
|
||||
|
||||
#ifndef DUMMYUNIONNAME
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYUNIONNAME u
|
||||
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
|
||||
# define DUMMYUNIONNAME2 u2
|
||||
# define DUMMYUNIONNAME3 u3
|
||||
# define DUMMYUNIONNAME4 u4
|
||||
# define DUMMYUNIONNAME5 u5
|
||||
# define DUMMYUNIONNAME6 u6
|
||||
# define DUMMYUNIONNAME7 u7
|
||||
# define DUMMYUNIONNAME8 u8
|
||||
# define DUMMYUNIONNAME9 u9
|
||||
# else /* NONAMELESSUNION */
|
||||
# define DUMMYUNIONNAME
|
||||
# define DUMMYUNIONNAME1 /* Wine uses this variant */
|
||||
# define DUMMYUNIONNAME2
|
||||
# define DUMMYUNIONNAME3
|
||||
# define DUMMYUNIONNAME4
|
||||
# define DUMMYUNIONNAME5
|
||||
# define DUMMYUNIONNAME6
|
||||
# define DUMMYUNIONNAME7
|
||||
# define DUMMYUNIONNAME8
|
||||
# define DUMMYUNIONNAME9
|
||||
# endif
|
||||
#endif /* DUMMYUNIONNAME */
|
||||
|
||||
#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
|
||||
# else
|
||||
# define DUMMYUNIONNAME1 /* Wine uses this variant */
|
||||
# endif
|
||||
#endif /* DUMMYUNIONNAME1 */
|
||||
|
||||
#ifndef DUMMYSTRUCTNAME
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYSTRUCTNAME s
|
||||
# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
|
||||
# define DUMMYSTRUCTNAME2 s2
|
||||
# define DUMMYSTRUCTNAME3 s3
|
||||
# define DUMMYSTRUCTNAME4 s4
|
||||
# define DUMMYSTRUCTNAME5 s5
|
||||
# else
|
||||
# define DUMMYSTRUCTNAME
|
||||
# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
|
||||
# define DUMMYSTRUCTNAME2
|
||||
# define DUMMYSTRUCTNAME3
|
||||
# define DUMMYSTRUCTNAME4
|
||||
# define DUMMYSTRUCTNAME5
|
||||
# endif
|
||||
#endif /* DUMMYSTRUCTNAME */
|
||||
|
||||
/* These are for compatibility with the Wine source tree */
|
||||
|
||||
#ifndef WINELIB_NAME_AW
|
||||
# ifdef __MINGW_NAME_AW
|
||||
# define WINELIB_NAME_AW __MINGW_NAME_AW
|
||||
# else
|
||||
# ifdef UNICODE
|
||||
# define WINELIB_NAME_AW(func) func##W
|
||||
# else
|
||||
# define WINELIB_NAME_AW(func) func##A
|
||||
# endif
|
||||
# endif
|
||||
#endif /* WINELIB_NAME_AW */
|
||||
|
||||
#ifndef DECL_WINELIB_TYPE_AW
|
||||
# ifdef __MINGW_TYPEDEF_AW
|
||||
# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
|
||||
# else
|
||||
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
|
||||
# endif
|
||||
#endif /* DECL_WINELIB_TYPE_AW */
|
||||
|
2467
raylib/external/glfw/deps/mingw/dinput.h
vendored
Normal file
2467
raylib/external/glfw/deps/mingw/dinput.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
239
raylib/external/glfw/deps/mingw/xinput.h
vendored
Normal file
239
raylib/external/glfw/deps/mingw/xinput.h
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* The Wine project - Xinput Joystick Library
|
||||
* Copyright 2008 Andrew Fenn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_XINPUT_H
|
||||
#define __WINE_XINPUT_H
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
/*
|
||||
* Bitmasks for the joysticks buttons, determines what has
|
||||
* been pressed on the joystick, these need to be mapped
|
||||
* to whatever device you're using instead of an xbox 360
|
||||
* joystick
|
||||
*/
|
||||
|
||||
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
|
||||
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
|
||||
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
|
||||
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
|
||||
#define XINPUT_GAMEPAD_START 0x0010
|
||||
#define XINPUT_GAMEPAD_BACK 0x0020
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
|
||||
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
|
||||
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
|
||||
#define XINPUT_GAMEPAD_A 0x1000
|
||||
#define XINPUT_GAMEPAD_B 0x2000
|
||||
#define XINPUT_GAMEPAD_X 0x4000
|
||||
#define XINPUT_GAMEPAD_Y 0x8000
|
||||
|
||||
/*
|
||||
* Defines the flags used to determine if the user is pushing
|
||||
* down on a button, not holding a button, etc
|
||||
*/
|
||||
|
||||
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
|
||||
#define XINPUT_KEYSTROKE_KEYUP 0x0002
|
||||
#define XINPUT_KEYSTROKE_REPEAT 0x0004
|
||||
|
||||
/*
|
||||
* Defines the codes which are returned by XInputGetKeystroke
|
||||
*/
|
||||
|
||||
#define VK_PAD_A 0x5800
|
||||
#define VK_PAD_B 0x5801
|
||||
#define VK_PAD_X 0x5802
|
||||
#define VK_PAD_Y 0x5803
|
||||
#define VK_PAD_RSHOULDER 0x5804
|
||||
#define VK_PAD_LSHOULDER 0x5805
|
||||
#define VK_PAD_LTRIGGER 0x5806
|
||||
#define VK_PAD_RTRIGGER 0x5807
|
||||
#define VK_PAD_DPAD_UP 0x5810
|
||||
#define VK_PAD_DPAD_DOWN 0x5811
|
||||
#define VK_PAD_DPAD_LEFT 0x5812
|
||||
#define VK_PAD_DPAD_RIGHT 0x5813
|
||||
#define VK_PAD_START 0x5814
|
||||
#define VK_PAD_BACK 0x5815
|
||||
#define VK_PAD_LTHUMB_PRESS 0x5816
|
||||
#define VK_PAD_RTHUMB_PRESS 0x5817
|
||||
#define VK_PAD_LTHUMB_UP 0x5820
|
||||
#define VK_PAD_LTHUMB_DOWN 0x5821
|
||||
#define VK_PAD_LTHUMB_RIGHT 0x5822
|
||||
#define VK_PAD_LTHUMB_LEFT 0x5823
|
||||
#define VK_PAD_LTHUMB_UPLEFT 0x5824
|
||||
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
|
||||
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
|
||||
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
|
||||
#define VK_PAD_RTHUMB_UP 0x5830
|
||||
#define VK_PAD_RTHUMB_DOWN 0x5831
|
||||
#define VK_PAD_RTHUMB_RIGHT 0x5832
|
||||
#define VK_PAD_RTHUMB_LEFT 0x5833
|
||||
#define VK_PAD_RTHUMB_UPLEFT 0x5834
|
||||
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
|
||||
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
|
||||
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
|
||||
|
||||
/*
|
||||
* Deadzones are for analogue joystick controls on the joypad
|
||||
* which determine when input should be assumed to be in the
|
||||
* middle of the pad. This is a threshold to stop a joypad
|
||||
* controlling the game when the player isn't touching the
|
||||
* controls.
|
||||
*/
|
||||
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
|
||||
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
|
||||
|
||||
|
||||
/*
|
||||
* Defines what type of abilities the type of joystick has
|
||||
* DEVTYPE_GAMEPAD is available for all joysticks, however
|
||||
* there may be more specific identifiers for other joysticks
|
||||
* which are being used.
|
||||
*/
|
||||
|
||||
#define XINPUT_DEVTYPE_GAMEPAD 0x01
|
||||
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
|
||||
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
|
||||
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
|
||||
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
|
||||
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
|
||||
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
|
||||
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
|
||||
|
||||
/*
|
||||
* These are used with the XInputGetCapabilities function to
|
||||
* determine the abilities to the joystick which has been
|
||||
* plugged in.
|
||||
*/
|
||||
|
||||
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
|
||||
#define XINPUT_FLAG_GAMEPAD 0x00000001
|
||||
|
||||
/*
|
||||
* Defines the status of the battery if one is used in the
|
||||
* attached joystick. The first two define if the joystick
|
||||
* supports a battery. Disconnected means that the joystick
|
||||
* isn't connected. Wired shows that the joystick is a wired
|
||||
* joystick.
|
||||
*/
|
||||
|
||||
#define BATTERY_DEVTYPE_GAMEPAD 0x00
|
||||
#define BATTERY_DEVTYPE_HEADSET 0x01
|
||||
#define BATTERY_TYPE_DISCONNECTED 0x00
|
||||
#define BATTERY_TYPE_WIRED 0x01
|
||||
#define BATTERY_TYPE_ALKALINE 0x02
|
||||
#define BATTERY_TYPE_NIMH 0x03
|
||||
#define BATTERY_TYPE_UNKNOWN 0xFF
|
||||
#define BATTERY_LEVEL_EMPTY 0x00
|
||||
#define BATTERY_LEVEL_LOW 0x01
|
||||
#define BATTERY_LEVEL_MEDIUM 0x02
|
||||
#define BATTERY_LEVEL_FULL 0x03
|
||||
|
||||
/*
|
||||
* How many joysticks can be used with this library. Games that
|
||||
* use the xinput library will not go over this number.
|
||||
*/
|
||||
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#define XUSER_INDEX_ANY 0x000000FF
|
||||
|
||||
/*
|
||||
* Defines the structure of an xbox 360 joystick.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_GAMEPAD {
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||
|
||||
typedef struct _XINPUT_STATE {
|
||||
DWORD dwPacketNumber;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
} XINPUT_STATE, *PXINPUT_STATE;
|
||||
|
||||
/*
|
||||
* Defines the structure of how much vibration is set on both the
|
||||
* right and left motors in a joystick. If you're not using a 360
|
||||
* joystick you will have to map these to your device.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_VIBRATION {
|
||||
WORD wLeftMotorSpeed;
|
||||
WORD wRightMotorSpeed;
|
||||
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||
|
||||
/*
|
||||
* Defines the structure for what kind of abilities the joystick has
|
||||
* such abilities are things such as if the joystick has the ability
|
||||
* to send and receive audio, if the joystick is in fact a driving
|
||||
* wheel or perhaps if the joystick is some kind of dance pad or
|
||||
* guitar.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_CAPABILITIES {
|
||||
BYTE Type;
|
||||
BYTE SubType;
|
||||
WORD Flags;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
XINPUT_VIBRATION Vibration;
|
||||
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
|
||||
|
||||
/*
|
||||
* Defines the structure for a joystick input event which is
|
||||
* retrieved using the function XInputGetKeystroke
|
||||
*/
|
||||
typedef struct _XINPUT_KEYSTROKE {
|
||||
WORD VirtualKey;
|
||||
WCHAR Unicode;
|
||||
WORD Flags;
|
||||
BYTE UserIndex;
|
||||
BYTE HidCode;
|
||||
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
|
||||
|
||||
typedef struct _XINPUT_BATTERY_INFORMATION
|
||||
{
|
||||
BYTE BatteryType;
|
||||
BYTE BatteryLevel;
|
||||
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void WINAPI XInputEnable(WINBOOL);
|
||||
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
|
||||
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
|
||||
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
|
||||
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
|
||||
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_XINPUT_H */
|
102
raylib/external/glfw/deps/wayland/fractional-scale-v1.xml
vendored
Normal file
102
raylib/external/glfw/deps/wayland/fractional-scale-v1.xml
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="fractional_scale_v1">
|
||||
<copyright>
|
||||
Copyright © 2022 Kenny Levinsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Protocol for requesting fractional surface scales">
|
||||
This protocol allows a compositor to suggest for surfaces to render at
|
||||
fractional scales.
|
||||
|
||||
A client can submit scaled content by utilizing wp_viewport. This is done by
|
||||
creating a wp_viewport object for the surface and setting the destination
|
||||
rectangle to the surface size before the scale factor is applied.
|
||||
|
||||
The buffer size is calculated by multiplying the surface size by the
|
||||
intended scale.
|
||||
|
||||
The wl_surface buffer scale should remain set to 1.
|
||||
|
||||
If a surface has a surface-local size of 100 px by 50 px and wishes to
|
||||
submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should
|
||||
be used and the wp_viewport destination rectangle should be 100 px by 50 px.
|
||||
|
||||
For toplevel surfaces, the size is rounded halfway away from zero. The
|
||||
rounding algorithm for subsurface position and size is not defined.
|
||||
</description>
|
||||
|
||||
<interface name="wp_fractional_scale_manager_v1" version="1">
|
||||
<description summary="fractional surface scale information">
|
||||
A global interface for requesting surfaces to use fractional scales.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="unbind the fractional surface scale interface">
|
||||
Informs the server that the client will not be using this protocol
|
||||
object anymore. This does not affect any other objects,
|
||||
wp_fractional_scale_v1 objects included.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="fractional_scale_exists" value="0"
|
||||
summary="the surface already has a fractional_scale object associated"/>
|
||||
</enum>
|
||||
|
||||
<request name="get_fractional_scale">
|
||||
<description summary="extend surface interface for scale information">
|
||||
Create an add-on object for the the wl_surface to let the compositor
|
||||
request fractional scales. If the given wl_surface already has a
|
||||
wp_fractional_scale_v1 object associated, the fractional_scale_exists
|
||||
protocol error is raised.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="wp_fractional_scale_v1"
|
||||
summary="the new surface scale info interface id"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="wp_fractional_scale_v1" version="1">
|
||||
<description summary="fractional scale interface to a wl_surface">
|
||||
An additional interface to a wl_surface object which allows the compositor
|
||||
to inform the client of the preferred scale.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="remove surface scale information for surface">
|
||||
Destroy the fractional scale object. When this object is destroyed,
|
||||
preferred_scale events will no longer be sent.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="preferred_scale">
|
||||
<description summary="notify of new preferred scale">
|
||||
Notification of a new preferred scale for this surface that the
|
||||
compositor suggests that the client should use.
|
||||
|
||||
The sent scale is the numerator of a fraction with a denominator of 120.
|
||||
</description>
|
||||
<arg name="scale" type="uint" summary="the new preferred scale"/>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
83
raylib/external/glfw/deps/wayland/idle-inhibit-unstable-v1.xml
vendored
Normal file
83
raylib/external/glfw/deps/wayland/idle-inhibit-unstable-v1.xml
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="idle_inhibit_unstable_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2015 Samsung Electronics Co., Ltd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwp_idle_inhibit_manager_v1" version="1">
|
||||
<description summary="control behavior when display idles">
|
||||
This interface permits inhibiting the idle behavior such as screen
|
||||
blanking, locking, and screensaving. The client binds the idle manager
|
||||
globally, then creates idle-inhibitor objects for each surface.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible changes
|
||||
may be added together with the corresponding interface version bump.
|
||||
Backward incompatible changes are done by bumping the version number in
|
||||
the protocol and interface names and resetting the interface version.
|
||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
version number in the protocol and interface names are removed and the
|
||||
interface version number is reset.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the idle inhibitor object">
|
||||
Destroy the inhibit manager.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="create_inhibitor">
|
||||
<description summary="create a new inhibitor object">
|
||||
Create a new inhibitor object associated with the given surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwp_idle_inhibitor_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the surface that inhibits the idle behavior"/>
|
||||
</request>
|
||||
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_idle_inhibitor_v1" version="1">
|
||||
<description summary="context object for inhibiting idle behavior">
|
||||
An idle inhibitor prevents the output that the associated surface is
|
||||
visible on from being set to a state where it is not visually usable due
|
||||
to lack of user interaction (e.g. blanked, dimmed, locked, set to power
|
||||
save, etc.) Any screensaver processes are also blocked from displaying.
|
||||
|
||||
If the surface is destroyed, unmapped, becomes occluded, loses
|
||||
visibility, or otherwise becomes not visually relevant for the user, the
|
||||
idle inhibitor will not be honored by the compositor; if the surface
|
||||
subsequently regains visibility the inhibitor takes effect once again.
|
||||
Likewise, the inhibitor isn't honored if the system was already idled at
|
||||
the time the inhibitor was established, although if the system later
|
||||
de-idles and re-idles the inhibitor will take effect.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the idle inhibitor object">
|
||||
Remove the inhibitor effect from the associated wl_surface.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
339
raylib/external/glfw/deps/wayland/pointer-constraints-unstable-v1.xml
vendored
Normal file
339
raylib/external/glfw/deps/wayland/pointer-constraints-unstable-v1.xml
vendored
Normal file
@ -0,0 +1,339 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="pointer_constraints_unstable_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2014 Jonas Ådahl
|
||||
Copyright © 2015 Red Hat Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="protocol for constraining pointer motions">
|
||||
This protocol specifies a set of interfaces used for adding constraints to
|
||||
the motion of a pointer. Possible constraints include confining pointer
|
||||
motions to a given region, or locking it to its current position.
|
||||
|
||||
In order to constrain the pointer, a client must first bind the global
|
||||
interface "wp_pointer_constraints" which, if a compositor supports pointer
|
||||
constraints, is exposed by the registry. Using the bound global object, the
|
||||
client uses the request that corresponds to the type of constraint it wants
|
||||
to make. See wp_pointer_constraints for more details.
|
||||
|
||||
Warning! The protocol described in this file is experimental and backward
|
||||
incompatible changes may be made. Backward compatible changes may be added
|
||||
together with the corresponding interface version bump. Backward
|
||||
incompatible changes are done by bumping the version number in the protocol
|
||||
and interface names and resetting the interface version. Once the protocol
|
||||
is to be declared stable, the 'z' prefix and the version number in the
|
||||
protocol and interface names are removed and the interface version number is
|
||||
reset.
|
||||
</description>
|
||||
|
||||
<interface name="zwp_pointer_constraints_v1" version="1">
|
||||
<description summary="constrain the movement of a pointer">
|
||||
The global interface exposing pointer constraining functionality. It
|
||||
exposes two requests: lock_pointer for locking the pointer to its
|
||||
position, and confine_pointer for locking the pointer to a region.
|
||||
|
||||
The lock_pointer and confine_pointer requests create the objects
|
||||
wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
||||
use these objects to interact with the lock.
|
||||
|
||||
For any surface, only one lock or confinement may be active across all
|
||||
wl_pointer objects of the same seat. If a lock or confinement is requested
|
||||
when another lock or confinement is active or requested on the same surface
|
||||
and with any of the wl_pointer objects of the same seat, an
|
||||
'already_constrained' error will be raised.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<description summary="wp_pointer_constraints error values">
|
||||
These errors can be emitted in response to wp_pointer_constraints
|
||||
requests.
|
||||
</description>
|
||||
<entry name="already_constrained" value="1"
|
||||
summary="pointer constraint already requested on that surface"/>
|
||||
</enum>
|
||||
|
||||
<enum name="lifetime">
|
||||
<description summary="constraint lifetime">
|
||||
These values represent different lifetime semantics. They are passed
|
||||
as arguments to the factory requests to specify how the constraint
|
||||
lifetimes should be managed.
|
||||
</description>
|
||||
<entry name="oneshot" value="1">
|
||||
<description summary="the pointer constraint is defunct once deactivated">
|
||||
A oneshot pointer constraint will never reactivate once it has been
|
||||
deactivated. See the corresponding deactivation event
|
||||
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
|
||||
details.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="persistent" value="2">
|
||||
<description summary="the pointer constraint may reactivate">
|
||||
A persistent pointer constraint may again reactivate once it has
|
||||
been deactivated. See the corresponding deactivation event
|
||||
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
|
||||
details.
|
||||
</description>
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the pointer constraints manager object">
|
||||
Used by the client to notify the server that it will no longer use this
|
||||
pointer constraints object.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="lock_pointer">
|
||||
<description summary="lock pointer to a position">
|
||||
The lock_pointer request lets the client request to disable movements of
|
||||
the virtual pointer (i.e. the cursor), effectively locking the pointer
|
||||
to a position. This request may not take effect immediately; in the
|
||||
future, when the compositor deems implementation-specific constraints
|
||||
are satisfied, the pointer lock will be activated and the compositor
|
||||
sends a locked event.
|
||||
|
||||
The protocol provides no guarantee that the constraints are ever
|
||||
satisfied, and does not require the compositor to send an error if the
|
||||
constraints cannot ever be satisfied. It is thus possible to request a
|
||||
lock that will never activate.
|
||||
|
||||
There may not be another pointer constraint of any kind requested or
|
||||
active on the surface for any of the wl_pointer objects of the seat of
|
||||
the passed pointer when requesting a lock. If there is, an error will be
|
||||
raised. See general pointer lock documentation for more details.
|
||||
|
||||
The intersection of the region passed with this request and the input
|
||||
region of the surface is used to determine where the pointer must be
|
||||
in order for the lock to activate. It is up to the compositor whether to
|
||||
warp the pointer or require some kind of user interaction for the lock
|
||||
to activate. If the region is null the surface input region is used.
|
||||
|
||||
A surface may receive pointer focus without the lock being activated.
|
||||
|
||||
The request creates a new object wp_locked_pointer which is used to
|
||||
interact with the lock as well as receive updates about its state. See
|
||||
the the description of wp_locked_pointer for further information.
|
||||
|
||||
Note that while a pointer is locked, the wl_pointer objects of the
|
||||
corresponding seat will not emit any wl_pointer.motion events, but
|
||||
relative motion events will still be emitted via wp_relative_pointer
|
||||
objects of the same seat. wl_pointer.axis and wl_pointer.button events
|
||||
are unaffected.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwp_locked_pointer_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="surface to lock pointer to"/>
|
||||
<arg name="pointer" type="object" interface="wl_pointer"
|
||||
summary="the pointer that should be locked"/>
|
||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||
summary="region of surface"/>
|
||||
<arg name="lifetime" type="uint" enum="lifetime" summary="lock lifetime"/>
|
||||
</request>
|
||||
|
||||
<request name="confine_pointer">
|
||||
<description summary="confine pointer to a region">
|
||||
The confine_pointer request lets the client request to confine the
|
||||
pointer cursor to a given region. This request may not take effect
|
||||
immediately; in the future, when the compositor deems implementation-
|
||||
specific constraints are satisfied, the pointer confinement will be
|
||||
activated and the compositor sends a confined event.
|
||||
|
||||
The intersection of the region passed with this request and the input
|
||||
region of the surface is used to determine where the pointer must be
|
||||
in order for the confinement to activate. It is up to the compositor
|
||||
whether to warp the pointer or require some kind of user interaction for
|
||||
the confinement to activate. If the region is null the surface input
|
||||
region is used.
|
||||
|
||||
The request will create a new object wp_confined_pointer which is used
|
||||
to interact with the confinement as well as receive updates about its
|
||||
state. See the the description of wp_confined_pointer for further
|
||||
information.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwp_confined_pointer_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="surface to lock pointer to"/>
|
||||
<arg name="pointer" type="object" interface="wl_pointer"
|
||||
summary="the pointer that should be confined"/>
|
||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||
summary="region of surface"/>
|
||||
<arg name="lifetime" type="uint" enum="lifetime" summary="confinement lifetime"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_locked_pointer_v1" version="1">
|
||||
<description summary="receive relative pointer motion events">
|
||||
The wp_locked_pointer interface represents a locked pointer state.
|
||||
|
||||
While the lock of this object is active, the wl_pointer objects of the
|
||||
associated seat will not emit any wl_pointer.motion events.
|
||||
|
||||
This object will send the event 'locked' when the lock is activated.
|
||||
Whenever the lock is activated, it is guaranteed that the locked surface
|
||||
will already have received pointer focus and that the pointer will be
|
||||
within the region passed to the request creating this object.
|
||||
|
||||
To unlock the pointer, send the destroy request. This will also destroy
|
||||
the wp_locked_pointer object.
|
||||
|
||||
If the compositor decides to unlock the pointer the unlocked event is
|
||||
sent. See wp_locked_pointer.unlock for details.
|
||||
|
||||
When unlocking, the compositor may warp the cursor position to the set
|
||||
cursor position hint. If it does, it will not result in any relative
|
||||
motion events emitted via wp_relative_pointer.
|
||||
|
||||
If the surface the lock was requested on is destroyed and the lock is not
|
||||
yet activated, the wp_locked_pointer object is now defunct and must be
|
||||
destroyed.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the locked pointer object">
|
||||
Destroy the locked pointer object. If applicable, the compositor will
|
||||
unlock the pointer.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_cursor_position_hint">
|
||||
<description summary="set the pointer cursor position hint">
|
||||
Set the cursor position hint relative to the top left corner of the
|
||||
surface.
|
||||
|
||||
If the client is drawing its own cursor, it should update the position
|
||||
hint to the position of its own cursor. A compositor may use this
|
||||
information to warp the pointer upon unlock in order to avoid pointer
|
||||
jumps.
|
||||
|
||||
The cursor position hint is double buffered. The new hint will only take
|
||||
effect when the associated surface gets it pending state applied. See
|
||||
wl_surface.commit for details.
|
||||
</description>
|
||||
<arg name="surface_x" type="fixed"
|
||||
summary="surface-local x coordinate"/>
|
||||
<arg name="surface_y" type="fixed"
|
||||
summary="surface-local y coordinate"/>
|
||||
</request>
|
||||
|
||||
<request name="set_region">
|
||||
<description summary="set a new lock region">
|
||||
Set a new region used to lock the pointer.
|
||||
|
||||
The new lock region is double-buffered. The new lock region will
|
||||
only take effect when the associated surface gets its pending state
|
||||
applied. See wl_surface.commit for details.
|
||||
|
||||
For details about the lock region, see wp_locked_pointer.
|
||||
</description>
|
||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||
summary="region of surface"/>
|
||||
</request>
|
||||
|
||||
<event name="locked">
|
||||
<description summary="lock activation event">
|
||||
Notification that the pointer lock of the seat's pointer is activated.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="unlocked">
|
||||
<description summary="lock deactivation event">
|
||||
Notification that the pointer lock of the seat's pointer is no longer
|
||||
active. If this is a oneshot pointer lock (see
|
||||
wp_pointer_constraints.lifetime) this object is now defunct and should
|
||||
be destroyed. If this is a persistent pointer lock (see
|
||||
wp_pointer_constraints.lifetime) this pointer lock may again
|
||||
reactivate in the future.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_confined_pointer_v1" version="1">
|
||||
<description summary="confined pointer object">
|
||||
The wp_confined_pointer interface represents a confined pointer state.
|
||||
|
||||
This object will send the event 'confined' when the confinement is
|
||||
activated. Whenever the confinement is activated, it is guaranteed that
|
||||
the surface the pointer is confined to will already have received pointer
|
||||
focus and that the pointer will be within the region passed to the request
|
||||
creating this object. It is up to the compositor to decide whether this
|
||||
requires some user interaction and if the pointer will warp to within the
|
||||
passed region if outside.
|
||||
|
||||
To unconfine the pointer, send the destroy request. This will also destroy
|
||||
the wp_confined_pointer object.
|
||||
|
||||
If the compositor decides to unconfine the pointer the unconfined event is
|
||||
sent. The wp_confined_pointer object is at this point defunct and should
|
||||
be destroyed.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the confined pointer object">
|
||||
Destroy the confined pointer object. If applicable, the compositor will
|
||||
unconfine the pointer.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_region">
|
||||
<description summary="set a new confine region">
|
||||
Set a new region used to confine the pointer.
|
||||
|
||||
The new confine region is double-buffered. The new confine region will
|
||||
only take effect when the associated surface gets its pending state
|
||||
applied. See wl_surface.commit for details.
|
||||
|
||||
If the confinement is active when the new confinement region is applied
|
||||
and the pointer ends up outside of newly applied region, the pointer may
|
||||
warped to a position within the new confinement region. If warped, a
|
||||
wl_pointer.motion event will be emitted, but no
|
||||
wp_relative_pointer.relative_motion event.
|
||||
|
||||
The compositor may also, instead of using the new region, unconfine the
|
||||
pointer.
|
||||
|
||||
For details about the confine region, see wp_confined_pointer.
|
||||
</description>
|
||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||
summary="region of surface"/>
|
||||
</request>
|
||||
|
||||
<event name="confined">
|
||||
<description summary="pointer confined">
|
||||
Notification that the pointer confinement of the seat's pointer is
|
||||
activated.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="unconfined">
|
||||
<description summary="pointer unconfined">
|
||||
Notification that the pointer confinement of the seat's pointer is no
|
||||
longer active. If this is a oneshot pointer confinement (see
|
||||
wp_pointer_constraints.lifetime) this object is now defunct and should
|
||||
be destroyed. If this is a persistent pointer confinement (see
|
||||
wp_pointer_constraints.lifetime) this pointer confinement may again
|
||||
reactivate in the future.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
136
raylib/external/glfw/deps/wayland/relative-pointer-unstable-v1.xml
vendored
Normal file
136
raylib/external/glfw/deps/wayland/relative-pointer-unstable-v1.xml
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="relative_pointer_unstable_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2014 Jonas Ådahl
|
||||
Copyright © 2015 Red Hat Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="protocol for relative pointer motion events">
|
||||
This protocol specifies a set of interfaces used for making clients able to
|
||||
receive relative pointer events not obstructed by barriers (such as the
|
||||
monitor edge or other pointer barriers).
|
||||
|
||||
To start receiving relative pointer events, a client must first bind the
|
||||
global interface "wp_relative_pointer_manager" which, if a compositor
|
||||
supports relative pointer motion events, is exposed by the registry. After
|
||||
having created the relative pointer manager proxy object, the client uses
|
||||
it to create the actual relative pointer object using the
|
||||
"get_relative_pointer" request given a wl_pointer. The relative pointer
|
||||
motion events will then, when applicable, be transmitted via the proxy of
|
||||
the newly created relative pointer object. See the documentation of the
|
||||
relative pointer interface for more details.
|
||||
|
||||
Warning! The protocol described in this file is experimental and backward
|
||||
incompatible changes may be made. Backward compatible changes may be added
|
||||
together with the corresponding interface version bump. Backward
|
||||
incompatible changes are done by bumping the version number in the protocol
|
||||
and interface names and resetting the interface version. Once the protocol
|
||||
is to be declared stable, the 'z' prefix and the version number in the
|
||||
protocol and interface names are removed and the interface version number is
|
||||
reset.
|
||||
</description>
|
||||
|
||||
<interface name="zwp_relative_pointer_manager_v1" version="1">
|
||||
<description summary="get relative pointer objects">
|
||||
A global interface used for getting the relative pointer object for a
|
||||
given pointer.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the relative pointer manager object">
|
||||
Used by the client to notify the server that it will no longer use this
|
||||
relative pointer manager object.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_relative_pointer">
|
||||
<description summary="get a relative pointer object">
|
||||
Create a relative pointer interface given a wl_pointer object. See the
|
||||
wp_relative_pointer interface for more details.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwp_relative_pointer_v1"/>
|
||||
<arg name="pointer" type="object" interface="wl_pointer"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_relative_pointer_v1" version="1">
|
||||
<description summary="relative pointer object">
|
||||
A wp_relative_pointer object is an extension to the wl_pointer interface
|
||||
used for emitting relative pointer events. It shares the same focus as
|
||||
wl_pointer objects of the same seat and will only emit events when it has
|
||||
focus.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="release the relative pointer object"/>
|
||||
</request>
|
||||
|
||||
<event name="relative_motion">
|
||||
<description summary="relative pointer motion">
|
||||
Relative x/y pointer motion from the pointer of the seat associated with
|
||||
this object.
|
||||
|
||||
A relative motion is in the same dimension as regular wl_pointer motion
|
||||
events, except they do not represent an absolute position. For example,
|
||||
moving a pointer from (x, y) to (x', y') would have the equivalent
|
||||
relative motion (x' - x, y' - y). If a pointer motion caused the
|
||||
absolute pointer position to be clipped by for example the edge of the
|
||||
monitor, the relative motion is unaffected by the clipping and will
|
||||
represent the unclipped motion.
|
||||
|
||||
This event also contains non-accelerated motion deltas. The
|
||||
non-accelerated delta is, when applicable, the regular pointer motion
|
||||
delta as it was before having applied motion acceleration and other
|
||||
transformations such as normalization.
|
||||
|
||||
Note that the non-accelerated delta does not represent 'raw' events as
|
||||
they were read from some device. Pointer motion acceleration is device-
|
||||
and configuration-specific and non-accelerated deltas and accelerated
|
||||
deltas may have the same value on some devices.
|
||||
|
||||
Relative motions are not coupled to wl_pointer.motion events, and can be
|
||||
sent in combination with such events, but also independently. There may
|
||||
also be scenarios where wl_pointer.motion is sent, but there is no
|
||||
relative motion. The order of an absolute and relative motion event
|
||||
originating from the same physical motion is not guaranteed.
|
||||
|
||||
If the client needs button events or focus state, it can receive them
|
||||
from a wl_pointer object of the same seat that the wp_relative_pointer
|
||||
object is associated with.
|
||||
</description>
|
||||
<arg name="utime_hi" type="uint"
|
||||
summary="high 32 bits of a 64 bit timestamp with microsecond granularity"/>
|
||||
<arg name="utime_lo" type="uint"
|
||||
summary="low 32 bits of a 64 bit timestamp with microsecond granularity"/>
|
||||
<arg name="dx" type="fixed"
|
||||
summary="the x component of the motion vector"/>
|
||||
<arg name="dy" type="fixed"
|
||||
summary="the y component of the motion vector"/>
|
||||
<arg name="dx_unaccel" type="fixed"
|
||||
summary="the x component of the unaccelerated motion vector"/>
|
||||
<arg name="dy_unaccel" type="fixed"
|
||||
summary="the y component of the unaccelerated motion vector"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
180
raylib/external/glfw/deps/wayland/viewporter.xml
vendored
Normal file
180
raylib/external/glfw/deps/wayland/viewporter.xml
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="viewporter">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2013-2016 Collabora, Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="wp_viewporter" version="1">
|
||||
<description summary="surface cropping and scaling">
|
||||
The global interface exposing surface cropping and scaling
|
||||
capabilities is used to instantiate an interface extension for a
|
||||
wl_surface object. This extended interface will then allow
|
||||
cropping and scaling the surface contents, effectively
|
||||
disconnecting the direct relationship between the buffer and the
|
||||
surface size.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="unbind from the cropping and scaling interface">
|
||||
Informs the server that the client will not be using this
|
||||
protocol object anymore. This does not affect any other objects,
|
||||
wp_viewport objects included.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="viewport_exists" value="0"
|
||||
summary="the surface already has a viewport object associated"/>
|
||||
</enum>
|
||||
|
||||
<request name="get_viewport">
|
||||
<description summary="extend surface interface for crop and scale">
|
||||
Instantiate an interface extension for the given wl_surface to
|
||||
crop and scale its content. If the given wl_surface already has
|
||||
a wp_viewport object associated, the viewport_exists
|
||||
protocol error is raised.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="wp_viewport"
|
||||
summary="the new viewport interface id"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="wp_viewport" version="1">
|
||||
<description summary="crop and scale interface to a wl_surface">
|
||||
An additional interface to a wl_surface object, which allows the
|
||||
client to specify the cropping and scaling of the surface
|
||||
contents.
|
||||
|
||||
This interface works with two concepts: the source rectangle (src_x,
|
||||
src_y, src_width, src_height), and the destination size (dst_width,
|
||||
dst_height). The contents of the source rectangle are scaled to the
|
||||
destination size, and content outside the source rectangle is ignored.
|
||||
This state is double-buffered, and is applied on the next
|
||||
wl_surface.commit.
|
||||
|
||||
The two parts of crop and scale state are independent: the source
|
||||
rectangle, and the destination size. Initially both are unset, that
|
||||
is, no scaling is applied. The whole of the current wl_buffer is
|
||||
used as the source, and the surface size is as defined in
|
||||
wl_surface.attach.
|
||||
|
||||
If the destination size is set, it causes the surface size to become
|
||||
dst_width, dst_height. The source (rectangle) is scaled to exactly
|
||||
this size. This overrides whatever the attached wl_buffer size is,
|
||||
unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
|
||||
has no content and therefore no size. Otherwise, the size is always
|
||||
at least 1x1 in surface local coordinates.
|
||||
|
||||
If the source rectangle is set, it defines what area of the wl_buffer is
|
||||
taken as the source. If the source rectangle is set and the destination
|
||||
size is not set, then src_width and src_height must be integers, and the
|
||||
surface size becomes the source rectangle size. This results in cropping
|
||||
without scaling. If src_width or src_height are not integers and
|
||||
destination size is not set, the bad_size protocol error is raised when
|
||||
the surface state is applied.
|
||||
|
||||
The coordinate transformations from buffer pixel coordinates up to
|
||||
the surface-local coordinates happen in the following order:
|
||||
1. buffer_transform (wl_surface.set_buffer_transform)
|
||||
2. buffer_scale (wl_surface.set_buffer_scale)
|
||||
3. crop and scale (wp_viewport.set*)
|
||||
This means, that the source rectangle coordinates of crop and scale
|
||||
are given in the coordinates after the buffer transform and scale,
|
||||
i.e. in the coordinates that would be the surface-local coordinates
|
||||
if the crop and scale was not applied.
|
||||
|
||||
If src_x or src_y are negative, the bad_value protocol error is raised.
|
||||
Otherwise, if the source rectangle is partially or completely outside of
|
||||
the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
|
||||
when the surface state is applied. A NULL wl_buffer does not raise the
|
||||
out_of_buffer error.
|
||||
|
||||
If the wl_surface associated with the wp_viewport is destroyed,
|
||||
all wp_viewport requests except 'destroy' raise the protocol error
|
||||
no_surface.
|
||||
|
||||
If the wp_viewport object is destroyed, the crop and scale
|
||||
state is removed from the wl_surface. The change will be applied
|
||||
on the next wl_surface.commit.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="remove scaling and cropping from the surface">
|
||||
The associated wl_surface's crop and scale state is removed.
|
||||
The change is applied on the next wl_surface.commit.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="bad_value" value="0"
|
||||
summary="negative or zero values in width or height"/>
|
||||
<entry name="bad_size" value="1"
|
||||
summary="destination size is not integer"/>
|
||||
<entry name="out_of_buffer" value="2"
|
||||
summary="source rectangle extends outside of the content area"/>
|
||||
<entry name="no_surface" value="3"
|
||||
summary="the wl_surface was destroyed"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_source">
|
||||
<description summary="set the source rectangle for cropping">
|
||||
Set the source rectangle of the associated wl_surface. See
|
||||
wp_viewport for the description, and relation to the wl_buffer
|
||||
size.
|
||||
|
||||
If all of x, y, width and height are -1.0, the source rectangle is
|
||||
unset instead. Any other set of values where width or height are zero
|
||||
or negative, or x or y are negative, raise the bad_value protocol
|
||||
error.
|
||||
|
||||
The crop and scale state is double-buffered state, and will be
|
||||
applied on the next wl_surface.commit.
|
||||
</description>
|
||||
<arg name="x" type="fixed" summary="source rectangle x"/>
|
||||
<arg name="y" type="fixed" summary="source rectangle y"/>
|
||||
<arg name="width" type="fixed" summary="source rectangle width"/>
|
||||
<arg name="height" type="fixed" summary="source rectangle height"/>
|
||||
</request>
|
||||
|
||||
<request name="set_destination">
|
||||
<description summary="set the surface size for scaling">
|
||||
Set the destination size of the associated wl_surface. See
|
||||
wp_viewport for the description, and relation to the wl_buffer
|
||||
size.
|
||||
|
||||
If width is -1 and height is -1, the destination size is unset
|
||||
instead. Any other pair of values for width and height that
|
||||
contains zero or negative values raises the bad_value protocol
|
||||
error.
|
||||
|
||||
The crop and scale state is double-buffered state, and will be
|
||||
applied on the next wl_surface.commit.
|
||||
</description>
|
||||
<arg name="width" type="int" summary="surface width"/>
|
||||
<arg name="height" type="int" summary="surface height"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
3151
raylib/external/glfw/deps/wayland/wayland.xml
vendored
Normal file
3151
raylib/external/glfw/deps/wayland/wayland.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
200
raylib/external/glfw/deps/wayland/xdg-activation-v1.xml
vendored
Normal file
200
raylib/external/glfw/deps/wayland/xdg-activation-v1.xml
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_activation_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
Copyright © 2020 Carlos Garnacho <carlosg@gnome.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Protocol for requesting activation of surfaces">
|
||||
The way for a client to pass focus to another toplevel is as follows.
|
||||
|
||||
The client that intends to activate another toplevel uses the
|
||||
xdg_activation_v1.get_activation_token request to get an activation token.
|
||||
This token is then forwarded to the client, which is supposed to activate
|
||||
one of its surfaces, through a separate band of communication.
|
||||
|
||||
One established way of doing this is through the XDG_ACTIVATION_TOKEN
|
||||
environment variable of a newly launched child process. The child process
|
||||
should unset the environment variable again right after reading it out in
|
||||
order to avoid propagating it to other child processes.
|
||||
|
||||
Another established way exists for Applications implementing the D-Bus
|
||||
interface org.freedesktop.Application, which should get their token under
|
||||
activation-token on their platform_data.
|
||||
|
||||
In general activation tokens may be transferred across clients through
|
||||
means not described in this protocol.
|
||||
|
||||
The client to be activated will then pass the token
|
||||
it received to the xdg_activation_v1.activate request. The compositor can
|
||||
then use this token to decide how to react to the activation request.
|
||||
|
||||
The token the activating client gets may be ineffective either already at
|
||||
the time it receives it, for example if it was not focused, for focus
|
||||
stealing prevention. The activating client will have no way to discover
|
||||
the validity of the token, and may still forward it to the to be activated
|
||||
client.
|
||||
|
||||
The created activation token may optionally get information attached to it
|
||||
that can be used by the compositor to identify the application that we
|
||||
intend to activate. This can for example be used to display a visual hint
|
||||
about what application is being started.
|
||||
|
||||
Warning! The protocol described in this file is currently in the testing
|
||||
phase. Backward compatible changes may be added together with the
|
||||
corresponding interface version bump. Backward incompatible changes can
|
||||
only be done by creating a new major version of the extension.
|
||||
</description>
|
||||
|
||||
<interface name="xdg_activation_v1" version="1">
|
||||
<description summary="interface for activating surfaces">
|
||||
A global interface used for informing the compositor about applications
|
||||
being activated or started, or for applications to request to be
|
||||
activated.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_activation object">
|
||||
Notify the compositor that the xdg_activation object will no longer be
|
||||
used.
|
||||
|
||||
The child objects created via this interface are unaffected and should
|
||||
be destroyed separately.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_activation_token">
|
||||
<description summary="requests a token">
|
||||
Creates an xdg_activation_token_v1 object that will provide
|
||||
the initiating client with a unique token for this activation. This
|
||||
token should be offered to the clients to be activated.
|
||||
</description>
|
||||
|
||||
<arg name="id" type="new_id" interface="xdg_activation_token_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="activate">
|
||||
<description summary="notify new interaction being available">
|
||||
Requests surface activation. It's up to the compositor to display
|
||||
this information as desired, for example by placing the surface above
|
||||
the rest.
|
||||
|
||||
The compositor may know who requested this by checking the activation
|
||||
token and might decide not to follow through with the activation if it's
|
||||
considered unwanted.
|
||||
|
||||
Compositors can ignore unknown activation tokens when an invalid
|
||||
token is passed.
|
||||
</description>
|
||||
<arg name="token" type="string" summary="the activation token of the initiating client"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the wl_surface to activate"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_activation_token_v1" version="1">
|
||||
<description summary="an exported activation handle">
|
||||
An object for setting up a token and receiving a token handle that can
|
||||
be passed as an activation token to another client.
|
||||
|
||||
The object is created using the xdg_activation_v1.get_activation_token
|
||||
request. This object should then be populated with the app_id, surface
|
||||
and serial information and committed. The compositor shall then issue a
|
||||
done event with the token. In case the request's parameters are invalid,
|
||||
the compositor will provide an invalid token.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_used" value="0"
|
||||
summary="The token has already been used previously"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_serial">
|
||||
<description summary="specifies the seat and serial of the activating event">
|
||||
Provides information about the seat and serial event that requested the
|
||||
token.
|
||||
|
||||
The serial can come from an input or focus event. For instance, if a
|
||||
click triggers the launch of a third-party client, the launcher client
|
||||
should send a set_serial request with the serial and seat from the
|
||||
wl_pointer.button event.
|
||||
|
||||
Some compositors might refuse to activate toplevels when the token
|
||||
doesn't have a valid and recent enough event serial.
|
||||
|
||||
Must be sent before commit. This information is optional.
|
||||
</description>
|
||||
<arg name="serial" type="uint"
|
||||
summary="the serial of the event that triggered the activation"/>
|
||||
<arg name="seat" type="object" interface="wl_seat"
|
||||
summary="the wl_seat of the event"/>
|
||||
</request>
|
||||
|
||||
<request name="set_app_id">
|
||||
<description summary="specifies the application being activated">
|
||||
The requesting client can specify an app_id to associate the token
|
||||
being created with it.
|
||||
|
||||
Must be sent before commit. This information is optional.
|
||||
</description>
|
||||
<arg name="app_id" type="string"
|
||||
summary="the application id of the client being activated."/>
|
||||
</request>
|
||||
|
||||
<request name="set_surface">
|
||||
<description summary="specifies the surface requesting activation">
|
||||
This request sets the surface requesting the activation. Note, this is
|
||||
different from the surface that will be activated.
|
||||
|
||||
Some compositors might refuse to activate toplevels when the token
|
||||
doesn't have a requesting surface.
|
||||
|
||||
Must be sent before commit. This information is optional.
|
||||
</description>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the requesting surface"/>
|
||||
</request>
|
||||
|
||||
<request name="commit">
|
||||
<description summary="issues the token request">
|
||||
Requests an activation token based on the different parameters that
|
||||
have been offered through set_serial, set_surface and set_app_id.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="done">
|
||||
<description summary="the exported activation token">
|
||||
The 'done' event contains the unique token of this activation request
|
||||
and notifies that the provider is done.
|
||||
</description>
|
||||
<arg name="token" type="string" summary="the exported activation token"/>
|
||||
</event>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_activation_token_v1 object">
|
||||
Notify the compositor that the xdg_activation_token_v1 object will no
|
||||
longer be used. The received token stays valid.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
156
raylib/external/glfw/deps/wayland/xdg-decoration-unstable-v1.xml
vendored
Normal file
156
raylib/external/glfw/deps/wayland/xdg-decoration-unstable-v1.xml
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_decoration_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2018 Simon Ser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zxdg_decoration_manager_v1" version="1">
|
||||
<description summary="window decoration manager">
|
||||
This interface allows a compositor to announce support for server-side
|
||||
decorations.
|
||||
|
||||
A window decoration is a set of window controls as deemed appropriate by
|
||||
the party managing them, such as user interface components used to move,
|
||||
resize and change a window's state.
|
||||
|
||||
A client can use this protocol to request being decorated by a supporting
|
||||
compositor.
|
||||
|
||||
If compositor and client do not negotiate the use of a server-side
|
||||
decoration using this protocol, clients continue to self-decorate as they
|
||||
see fit.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible changes
|
||||
may be added together with the corresponding interface version bump.
|
||||
Backward incompatible changes are done by bumping the version number in
|
||||
the protocol and interface names and resetting the interface version.
|
||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
version number in the protocol and interface names are removed and the
|
||||
interface version number is reset.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the decoration manager object">
|
||||
Destroy the decoration manager. This doesn't destroy objects created
|
||||
with the manager.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_toplevel_decoration">
|
||||
<description summary="create a new toplevel decoration object">
|
||||
Create a new decoration object associated with the given toplevel.
|
||||
|
||||
Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
|
||||
buffer attached or committed is a client error, and any attempts by a
|
||||
client to attach or manipulate a buffer prior to the first
|
||||
xdg_toplevel_decoration.configure event must also be treated as
|
||||
errors.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zxdg_toplevel_decoration_v1"/>
|
||||
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zxdg_toplevel_decoration_v1" version="1">
|
||||
<description summary="decoration object for a toplevel surface">
|
||||
The decoration object allows the compositor to toggle server-side window
|
||||
decorations for a toplevel surface. The client can request to switch to
|
||||
another mode.
|
||||
|
||||
The xdg_toplevel_decoration object must be destroyed before its
|
||||
xdg_toplevel.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="unconfigured_buffer" value="0"
|
||||
summary="xdg_toplevel has a buffer attached before configure"/>
|
||||
<entry name="already_constructed" value="1"
|
||||
summary="xdg_toplevel already has a decoration object"/>
|
||||
<entry name="orphaned" value="2"
|
||||
summary="xdg_toplevel destroyed before the decoration object"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the decoration object">
|
||||
Switch back to a mode without any server-side decorations at the next
|
||||
commit.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="mode">
|
||||
<description summary="window decoration modes">
|
||||
These values describe window decoration modes.
|
||||
</description>
|
||||
<entry name="client_side" value="1"
|
||||
summary="no server-side window decoration"/>
|
||||
<entry name="server_side" value="2"
|
||||
summary="server-side window decoration"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_mode">
|
||||
<description summary="set the decoration mode">
|
||||
Set the toplevel surface decoration mode. This informs the compositor
|
||||
that the client prefers the provided decoration mode.
|
||||
|
||||
After requesting a decoration mode, the compositor will respond by
|
||||
emitting an xdg_surface.configure event. The client should then update
|
||||
its content, drawing it without decorations if the received mode is
|
||||
server-side decorations. The client must also acknowledge the configure
|
||||
when committing the new content (see xdg_surface.ack_configure).
|
||||
|
||||
The compositor can decide not to use the client's mode and enforce a
|
||||
different mode instead.
|
||||
|
||||
Clients whose decoration mode depend on the xdg_toplevel state may send
|
||||
a set_mode request in response to an xdg_surface.configure event and wait
|
||||
for the next xdg_surface.configure event to prevent unwanted state.
|
||||
Such clients are responsible for preventing configure loops and must
|
||||
make sure not to send multiple successive set_mode requests with the
|
||||
same decoration mode.
|
||||
</description>
|
||||
<arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
|
||||
</request>
|
||||
|
||||
<request name="unset_mode">
|
||||
<description summary="unset the decoration mode">
|
||||
Unset the toplevel surface decoration mode. This informs the compositor
|
||||
that the client doesn't prefer a particular decoration mode.
|
||||
|
||||
This request has the same semantics as set_mode.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
The configure event asks the client to change its decoration mode. The
|
||||
configured state should not be applied immediately. Clients must send an
|
||||
ack_configure in response to this event. See xdg_surface.configure and
|
||||
xdg_surface.ack_configure for details.
|
||||
|
||||
A configure event can be sent at any time. The specified mode must be
|
||||
obeyed by the client.
|
||||
</description>
|
||||
<arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
1370
raylib/external/glfw/deps/wayland/xdg-shell.xml
vendored
Normal file
1370
raylib/external/glfw/deps/wayland/xdg-shell.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6547
raylib/external/glfw/include/GLFW/glfw3.h
vendored
Normal file
6547
raylib/external/glfw/include/GLFW/glfw3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
663
raylib/external/glfw/include/GLFW/glfw3native.h
vendored
Normal file
663
raylib/external/glfw/include/GLFW/glfw3native.h
vendored
Normal file
@ -0,0 +1,663 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.4 - 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>
|
||||
#endif
|
||||
|
||||
#if 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
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
|
||||
* default it also acts as an OpenGL header
|
||||
* However, glx.h will include gl.h, which will define it unconditionally
|
||||
*/
|
||||
#if defined(GLFW_GLAPIENTRY_DEFINED)
|
||||
#undef GLAPIENTRY
|
||||
#undef GLFW_GLAPIENTRY_DEFINED
|
||||
#endif
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
|
||||
* default it also acts as an OpenGL header
|
||||
* However, osmesa.h will include gl.h, which will define it unconditionally
|
||||
*/
|
||||
#if defined(GLFW_GLAPIENTRY_DEFINED)
|
||||
#undef GLAPIENTRY
|
||||
#undef GLFW_GLAPIENTRY_DEFINED
|
||||
#endif
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
|
||||
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* 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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/*! @brief Returns the `NSView` of the specified window.
|
||||
*
|
||||
* @return The `NSView` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaView(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_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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, @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE 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, @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE 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_NOT_INITIALIZED, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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_NOT_INITIALIZED, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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 and @ref
|
||||
* GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @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_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @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_ */
|
||||
|
696
raylib/external/glfw/src/cocoa_init.m
vendored
Normal file
696
raylib/external/glfw/src/cocoa_init.m
vendored
Normal file
@ -0,0 +1,696 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2024 M374LX <wilsalx@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 "internal.h"
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
|
||||
#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)
|
||||
{
|
||||
NSString* appName = nil;
|
||||
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
|
||||
NSString* nameKeys[] =
|
||||
{
|
||||
@"CFBundleDisplayName",
|
||||
@"CFBundleName",
|
||||
@"CFBundleExecutable",
|
||||
};
|
||||
|
||||
// Try to figure out what the calling application is called
|
||||
|
||||
for (size_t 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 createKeyTablesCocoa(void)
|
||||
{
|
||||
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_PRINT_SCREEN;
|
||||
_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 (int 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 updateUnicodeData(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 updateUnicodeData();
|
||||
}
|
||||
|
||||
@interface GLFWHelper : NSObject
|
||||
@end
|
||||
|
||||
@implementation GLFWHelper
|
||||
|
||||
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
|
||||
{
|
||||
updateUnicodeData();
|
||||
}
|
||||
|
||||
- (void)doNothing:(id)object
|
||||
{
|
||||
}
|
||||
|
||||
@end // GLFWHelper
|
||||
|
||||
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
|
||||
@end
|
||||
|
||||
@implementation GLFWApplicationDelegate
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||
_glfwInputWindowCloseRequest(window);
|
||||
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
||||
{
|
||||
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||
{
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
[window->context.nsgl.object update];
|
||||
}
|
||||
|
||||
_glfwPollMonitorsCocoa();
|
||||
}
|
||||
|
||||
- (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
|
||||
{
|
||||
_glfwPostEmptyEventCocoa();
|
||||
[NSApp stop:nil];
|
||||
}
|
||||
|
||||
- (void)applicationDidHide:(NSNotification *)notification
|
||||
{
|
||||
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||
_glfwRestoreVideoModeCocoa(_glfw.monitors[i]);
|
||||
}
|
||||
|
||||
@end // GLFWApplicationDelegate
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* _glfwLoadLocalVulkanLoaderCocoa(void)
|
||||
{
|
||||
CFBundleRef bundle = CFBundleGetMainBundle();
|
||||
if (!bundle)
|
||||
return NULL;
|
||||
|
||||
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
|
||||
if (!frameworksUrl)
|
||||
return NULL;
|
||||
|
||||
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
|
||||
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
|
||||
if (!loaderUrl)
|
||||
{
|
||||
CFRelease(frameworksUrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char path[PATH_MAX];
|
||||
void* handle = NULL;
|
||||
|
||||
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
|
||||
handle = _glfwPlatformLoadModule(path);
|
||||
|
||||
CFRelease(loaderUrl);
|
||||
CFRelease(frameworksUrl);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
||||
{
|
||||
const _GLFWplatform cocoa =
|
||||
{
|
||||
.platformID = GLFW_PLATFORM_COCOA,
|
||||
.init = _glfwInitCocoa,
|
||||
.terminate = _glfwTerminateCocoa,
|
||||
.getCursorPos = _glfwGetCursorPosCocoa,
|
||||
.setCursorPos = _glfwSetCursorPosCocoa,
|
||||
.setCursorMode = _glfwSetCursorModeCocoa,
|
||||
.setRawMouseMotion = _glfwSetRawMouseMotionCocoa,
|
||||
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedCocoa,
|
||||
.createCursor = _glfwCreateCursorCocoa,
|
||||
.createStandardCursor = _glfwCreateStandardCursorCocoa,
|
||||
.destroyCursor = _glfwDestroyCursorCocoa,
|
||||
.setCursor = _glfwSetCursorCocoa,
|
||||
.getScancodeName = _glfwGetScancodeNameCocoa,
|
||||
.getKeyScancode = _glfwGetKeyScancodeCocoa,
|
||||
.setClipboardString = _glfwSetClipboardStringCocoa,
|
||||
.getClipboardString = _glfwGetClipboardStringCocoa,
|
||||
.initJoysticks = _glfwInitJoysticksCocoa,
|
||||
.terminateJoysticks = _glfwTerminateJoysticksCocoa,
|
||||
.pollJoystick = _glfwPollJoystickCocoa,
|
||||
.getMappingName = _glfwGetMappingNameCocoa,
|
||||
.updateGamepadGUID = _glfwUpdateGamepadGUIDCocoa,
|
||||
.freeMonitor = _glfwFreeMonitorCocoa,
|
||||
.getMonitorPos = _glfwGetMonitorPosCocoa,
|
||||
.getMonitorContentScale = _glfwGetMonitorContentScaleCocoa,
|
||||
.getMonitorWorkarea = _glfwGetMonitorWorkareaCocoa,
|
||||
.getVideoModes = _glfwGetVideoModesCocoa,
|
||||
.getVideoMode = _glfwGetVideoModeCocoa,
|
||||
.getGammaRamp = _glfwGetGammaRampCocoa,
|
||||
.setGammaRamp = _glfwSetGammaRampCocoa,
|
||||
.createWindow = _glfwCreateWindowCocoa,
|
||||
.destroyWindow = _glfwDestroyWindowCocoa,
|
||||
.setWindowTitle = _glfwSetWindowTitleCocoa,
|
||||
.setWindowIcon = _glfwSetWindowIconCocoa,
|
||||
.getWindowPos = _glfwGetWindowPosCocoa,
|
||||
.setWindowPos = _glfwSetWindowPosCocoa,
|
||||
.getWindowSize = _glfwGetWindowSizeCocoa,
|
||||
.setWindowSize = _glfwSetWindowSizeCocoa,
|
||||
.setWindowSizeLimits = _glfwSetWindowSizeLimitsCocoa,
|
||||
.setWindowAspectRatio = _glfwSetWindowAspectRatioCocoa,
|
||||
.getFramebufferSize = _glfwGetFramebufferSizeCocoa,
|
||||
.getWindowFrameSize = _glfwGetWindowFrameSizeCocoa,
|
||||
.getWindowContentScale = _glfwGetWindowContentScaleCocoa,
|
||||
.iconifyWindow = _glfwIconifyWindowCocoa,
|
||||
.restoreWindow = _glfwRestoreWindowCocoa,
|
||||
.maximizeWindow = _glfwMaximizeWindowCocoa,
|
||||
.showWindow = _glfwShowWindowCocoa,
|
||||
.hideWindow = _glfwHideWindowCocoa,
|
||||
.requestWindowAttention = _glfwRequestWindowAttentionCocoa,
|
||||
.focusWindow = _glfwFocusWindowCocoa,
|
||||
.setWindowMonitor = _glfwSetWindowMonitorCocoa,
|
||||
.windowFocused = _glfwWindowFocusedCocoa,
|
||||
.windowIconified = _glfwWindowIconifiedCocoa,
|
||||
.windowVisible = _glfwWindowVisibleCocoa,
|
||||
.windowMaximized = _glfwWindowMaximizedCocoa,
|
||||
.windowHovered = _glfwWindowHoveredCocoa,
|
||||
.framebufferTransparent = _glfwFramebufferTransparentCocoa,
|
||||
.getWindowOpacity = _glfwGetWindowOpacityCocoa,
|
||||
.setWindowResizable = _glfwSetWindowResizableCocoa,
|
||||
.setWindowDecorated = _glfwSetWindowDecoratedCocoa,
|
||||
.setWindowFloating = _glfwSetWindowFloatingCocoa,
|
||||
.setWindowOpacity = _glfwSetWindowOpacityCocoa,
|
||||
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughCocoa,
|
||||
.pollEvents = _glfwPollEventsCocoa,
|
||||
.waitEvents = _glfwWaitEventsCocoa,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutCocoa,
|
||||
.postEmptyEvent = _glfwPostEmptyEventCocoa,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformCocoa,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayCocoa,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowCocoa,
|
||||
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsCocoa,
|
||||
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportCocoa,
|
||||
.createWindowSurface = _glfwCreateWindowSurfaceCocoa
|
||||
};
|
||||
|
||||
*platform = cocoa;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
int _glfwInitCocoa(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
_glfw.ns.helper = [[GLFWHelper alloc] init];
|
||||
|
||||
[NSThread detachNewThreadSelector:@selector(doNothing:)
|
||||
toTarget:_glfw.ns.helper
|
||||
withObject:nil];
|
||||
|
||||
[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];
|
||||
|
||||
createKeyTablesCocoa();
|
||||
|
||||
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
if (!_glfw.ns.eventSource)
|
||||
return GLFW_FALSE;
|
||||
|
||||
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
|
||||
|
||||
if (!initializeTIS())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwPollMonitorsCocoa();
|
||||
|
||||
if (![[NSRunningApplication currentApplication] isFinishedLaunching])
|
||||
[NSApp run];
|
||||
|
||||
// In case we are unbundled, make us a proper UI application
|
||||
if (_glfw.hints.init.ns.menubar)
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
||||
return GLFW_TRUE;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
void _glfwTerminateCocoa(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];
|
||||
|
||||
_glfw_free(_glfw.ns.clipboardString);
|
||||
|
||||
_glfwTerminateNSGL();
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateOSMesa();
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
#endif // _GLFW_COCOA
|
||||
|
49
raylib/external/glfw/src/cocoa_joystick.h
vendored
Normal file
49
raylib/external/glfw/src/cocoa_joystick.h
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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/IOHIDKeys.h>
|
||||
|
||||
#define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns;
|
||||
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
|
||||
|
||||
// Cocoa-specific per-joystick data
|
||||
//
|
||||
typedef struct _GLFWjoystickNS
|
||||
{
|
||||
IOHIDDeviceRef device;
|
||||
CFMutableArrayRef axes;
|
||||
CFMutableArrayRef buttons;
|
||||
CFMutableArrayRef hats;
|
||||
} _GLFWjoystickNS;
|
||||
|
||||
GLFWbool _glfwInitJoysticksCocoa(void);
|
||||
void _glfwTerminateJoysticksCocoa(void);
|
||||
GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode);
|
||||
const char* _glfwGetMappingNameCocoa(void);
|
||||
void _glfwUpdateGamepadGUIDCocoa(char* guid);
|
||||
|
485
raylib/external/glfw/src/cocoa_joystick.m
vendored
Normal file
485
raylib/external/glfw/src/cocoa_joystick.m
vendored
Normal file
@ -0,0 +1,485 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
|
||||
#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)
|
||||
{
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
|
||||
for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||
CFRelease(js->ns.axes);
|
||||
|
||||
for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
||||
CFRelease(js->ns.buttons);
|
||||
|
||||
for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
_glfw_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];
|
||||
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;
|
||||
}
|
||||
|
||||
CFArrayRef elements =
|
||||
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
|
||||
// It is reportedly possible for this to fail on macOS 13 Ventura
|
||||
// if the application does not have input monitoring permissions
|
||||
if (!elements)
|
||||
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]);
|
||||
}
|
||||
|
||||
for (CFIndex 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 = _glfw_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)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
|
||||
{
|
||||
closeJoystick(&_glfw.joysticks[jid]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitJoysticksCocoa(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 GLFW_FALSE;
|
||||
}
|
||||
|
||||
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);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwTerminateJoysticksCocoa(void)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].connected)
|
||||
closeJoystick(&_glfw.joysticks[jid]);
|
||||
}
|
||||
|
||||
if (_glfw.ns.hidManager)
|
||||
{
|
||||
CFRelease(_glfw.ns.hidManager);
|
||||
_glfw.ns.hidManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
if (mode & _GLFW_POLL_AXES)
|
||||
{
|
||||
for (CFIndex 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)
|
||||
{
|
||||
for (CFIndex 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 (CFIndex 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;
|
||||
}
|
||||
|
||||
const char* _glfwGetMappingNameCocoa(void)
|
||||
{
|
||||
return "Mac OS X";
|
||||
}
|
||||
|
||||
void _glfwUpdateGamepadGUIDCocoa(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);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _GLFW_COCOA
|
||||
|
644
raylib/external/glfw/src/cocoa_monitor.m
vendored
Normal file
644
raylib/external/glfw/src/cocoa_monitor.m
vendored
Normal file
@ -0,0 +1,644 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2024 M374LX <wilsalx@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 "internal.h"
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
|
||||
#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 = _glfw_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 _glfwPollMonitorsCocoa(void)
|
||||
{
|
||||
uint32_t displayCount;
|
||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||
CGDirectDisplayID* displays = _glfw_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 = _glfw_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;
|
||||
|
||||
_glfw_free(name);
|
||||
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
|
||||
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
|
||||
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
|
||||
CGDisplayModeRelease(mode);
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
}
|
||||
|
||||
_glfw_free(disconnected);
|
||||
_glfw_free(displays);
|
||||
}
|
||||
|
||||
// Change the current video mode
|
||||
//
|
||||
void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
GLFWvidmode current;
|
||||
_glfwGetVideoModeCocoa(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 _glfwRestoreVideoModeCocoa(_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 _glfwFreeMonitorCocoa(_GLFWmonitor* monitor)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwGetMonitorPosCocoa(_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 _glfwGetMonitorContentScaleCocoa(_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 _glfwGetMonitorWorkareaCocoa(_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 = _glfwTransformYCocoa(frameRect.origin.y + frameRect.size.height - 1);
|
||||
if (width)
|
||||
*width = frameRect.size.width;
|
||||
if (height)
|
||||
*height = frameRect.size.height;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
*count = 0;
|
||||
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
const CFIndex found = CFArrayGetCount(modes);
|
||||
GLFWvidmode* result = _glfw_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
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||
if (!native)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to query display mode");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
*mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
|
||||
CGDisplayModeRelease(native);
|
||||
return GLFW_TRUE;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||
CGGammaValue* values = _glfw_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);
|
||||
}
|
||||
|
||||
_glfw_free(values);
|
||||
return GLFW_TRUE;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
CGGammaValue* values = _glfw_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);
|
||||
|
||||
_glfw_free(values);
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized");
|
||||
return kCGNullDirectDisplay;
|
||||
}
|
||||
|
||||
return monitor->ns.displayID;
|
||||
}
|
||||
|
||||
#endif // _GLFW_COCOA
|
||||
|
302
raylib/external/glfw/src/cocoa_platform.h
vendored
Normal file
302
raylib/external/glfw/src/cocoa_platform.h
vendored
Normal file
@ -0,0 +1,302 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <IOKit/hid/IOHIDLib.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 < 101400
|
||||
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
||||
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||
#endif
|
||||
|
||||
#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*);
|
||||
|
||||
#define GLFW_COCOA_WINDOW_STATE _GLFWwindowNS ns;
|
||||
#define GLFW_COCOA_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns;
|
||||
#define GLFW_COCOA_MONITOR_STATE _GLFWmonitorNS ns;
|
||||
#define GLFW_COCOA_CURSOR_STATE _GLFWcursorNS ns;
|
||||
|
||||
#define GLFW_NSGL_CONTEXT_STATE _GLFWcontextNSGL nsgl;
|
||||
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
// NSGL-specific per-context data
|
||||
//
|
||||
typedef struct _GLFWcontextNSGL
|
||||
{
|
||||
id pixelFormat;
|
||||
id object;
|
||||
} _GLFWcontextNSGL;
|
||||
|
||||
// NSGL-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryNSGL
|
||||
{
|
||||
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
|
||||
CFBundleRef framework;
|
||||
} _GLFWlibraryNSGL;
|
||||
|
||||
// Cocoa-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowNS
|
||||
{
|
||||
id object;
|
||||
id delegate;
|
||||
id view;
|
||||
id layer;
|
||||
|
||||
GLFWbool maximized;
|
||||
GLFWbool occluded;
|
||||
GLFWbool scaleFramebuffer;
|
||||
|
||||
// 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 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;
|
||||
|
||||
|
||||
GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform);
|
||||
int _glfwInitCocoa(void);
|
||||
void _glfwTerminateCocoa(void);
|
||||
|
||||
GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height);
|
||||
void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
|
||||
void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom);
|
||||
void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
|
||||
void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window, float* xscale, float* yscale);
|
||||
void _glfwIconifyWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwRestoreWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwMaximizeWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwShowWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwHideWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window);
|
||||
void _glfwFocusWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
|
||||
GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window);
|
||||
GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window);
|
||||
void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled);
|
||||
float _glfwGetWindowOpacityCocoa(_GLFWwindow* window);
|
||||
void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity);
|
||||
void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled);
|
||||
|
||||
void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled);
|
||||
GLFWbool _glfwRawMouseMotionSupportedCocoa(void);
|
||||
|
||||
void _glfwPollEventsCocoa(void);
|
||||
void _glfwWaitEventsCocoa(void);
|
||||
void _glfwWaitEventsTimeoutCocoa(double timeout);
|
||||
void _glfwPostEmptyEventCocoa(void);
|
||||
|
||||
void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos);
|
||||
void _glfwSetCursorPosCocoa(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode);
|
||||
const char* _glfwGetScancodeNameCocoa(int scancode);
|
||||
int _glfwGetKeyScancodeCocoa(int key);
|
||||
GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
||||
GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape);
|
||||
void _glfwDestroyCursorCocoa(_GLFWcursor* cursor);
|
||||
void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||
void _glfwSetClipboardStringCocoa(const char* string);
|
||||
const char* _glfwGetClipboardStringCocoa(void);
|
||||
|
||||
EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs);
|
||||
EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void);
|
||||
EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window);
|
||||
|
||||
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions);
|
||||
GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
|
||||
VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
||||
|
||||
void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor);
|
||||
void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||
void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, float* xscale, float* yscale);
|
||||
void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
|
||||
GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count);
|
||||
GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||
GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
void _glfwPollMonitorsCocoa(void);
|
||||
void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
|
||||
|
||||
float _glfwTransformYCocoa(float y);
|
||||
|
||||
void* _glfwLoadLocalVulkanLoaderCocoa(void);
|
||||
|
||||
GLFWbool _glfwInitNSGL(void);
|
||||
void _glfwTerminateNSGL(void);
|
||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||
|
57
raylib/external/glfw/src/cocoa_time.c
vendored
Normal file
57
raylib/external/glfw/src/cocoa_time.c
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_COCOA_TIMER)
|
||||
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformInitTimer(void)
|
||||
{
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
|
||||
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
return _glfw.timer.ns.frequency;
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_COCOA_TIMER
|
||||
|
35
raylib/external/glfw/src/cocoa_time.h
vendored
Normal file
35
raylib/external/glfw/src/cocoa_time.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2021 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define GLFW_COCOA_LIBRARY_TIMER_STATE _GLFWtimerNS ns;
|
||||
|
||||
// Cocoa-specific global timer data
|
||||
//
|
||||
typedef struct _GLFWtimerNS
|
||||
{
|
||||
uint64_t frequency;
|
||||
} _GLFWtimerNS;
|
||||
|
2072
raylib/external/glfw/src/cocoa_window.m
vendored
Normal file
2072
raylib/external/glfw/src/cocoa_window.m
vendored
Normal file
File diff suppressed because it is too large
Load Diff
765
raylib/external/glfw/src/context.c
vendored
Normal file
765
raylib/external/glfw/src/context.c
vendored
Normal file
@ -0,0 +1,765 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#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->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->share)
|
||||
{
|
||||
if (ctxconfig->client == GLFW_NO_API ||
|
||||
ctxconfig->share->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->source != ctxconfig->share->context.source)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Context creation APIs do not match between contexts");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if ((ctxconfig->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);
|
||||
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
|
||||
return GLFW_FALSE;
|
||||
|
||||
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);
|
||||
}
|
||||
|
911
raylib/external/glfw/src/egl_context.c
vendored
Normal file
911
raylib/external/glfw/src/egl_context.c
vendored
Normal file
@ -0,0 +1,911 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#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* fbconfig,
|
||||
EGLConfig* result)
|
||||
{
|
||||
EGLConfig* nativeConfigs;
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, nativeCount, usableCount, apiBit;
|
||||
GLFWbool wrongApiAvailable = GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (ctxconfig->major == 1)
|
||||
apiBit = EGL_OPENGL_ES_BIT;
|
||||
else
|
||||
apiBit = EGL_OPENGL_ES2_BIT;
|
||||
}
|
||||
else
|
||||
apiBit = EGL_OPENGL_BIT;
|
||||
|
||||
if (fbconfig->stereo)
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
|
||||
if (!nativeCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
|
||||
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
|
||||
|
||||
usableConfigs = _glfw_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)
|
||||
if (_glfw.platform.platformID == GLFW_PLATFORM_X11)
|
||||
{
|
||||
XVisualInfo vi = {0};
|
||||
|
||||
// Only consider EGLConfigs with associated Visuals
|
||||
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
|
||||
if (!vi.visualid)
|
||||
continue;
|
||||
|
||||
if (fbconfig->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 (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
|
||||
{
|
||||
wrongApiAvailable = GLFW_TRUE;
|
||||
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);
|
||||
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
|
||||
{
|
||||
// NOTE: The wl_surface opaque region is no guarantee that its buffer
|
||||
// is presented as opaque, if it also has an alpha channel
|
||||
// HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
|
||||
// with an alpha channel to ensure the buffer is opaque
|
||||
if (!_glfw.egl.EXT_present_opaque)
|
||||
{
|
||||
if (!fbconfig->transparent && u->alphaBits > 0)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif // _GLFW_WAYLAND
|
||||
|
||||
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
|
||||
u->doublebuffer = fbconfig->doublebuffer;
|
||||
|
||||
u->handle = (uintptr_t) n;
|
||||
usableCount++;
|
||||
}
|
||||
|
||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
||||
if (closest)
|
||||
*result = (EGLConfig) closest->handle;
|
||||
else
|
||||
{
|
||||
if (wrongApiAvailable)
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (ctxconfig->major == 1)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to find support for OpenGL ES 1.x");
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to find support for OpenGL ES 2 or later");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to find support for OpenGL");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
}
|
||||
}
|
||||
|
||||
_glfw_free(nativeConfigs);
|
||||
_glfw_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)
|
||||
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
|
||||
{
|
||||
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
|
||||
if (!window->wl.visible)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
|
||||
}
|
||||
|
||||
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);
|
||||
assert(window != NULL);
|
||||
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
GLFWglproc proc = (GLFWglproc)
|
||||
_glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
}
|
||||
|
||||
return eglGetProcAddress(procname);
|
||||
}
|
||||
|
||||
static void destroyContextEGL(_GLFWwindow* window)
|
||||
{
|
||||
// NOTE: Do not unload libGL.so.1 while the X11 display is still open,
|
||||
// as it will make XCloseDisplay segfault
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
|
||||
window->context.client != GLFW_OPENGL_API)
|
||||
{
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
_glfwPlatformFreeModule(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;
|
||||
EGLint* attribs = NULL;
|
||||
const char* extensions;
|
||||
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 = _glfwPlatformLoadModule(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)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigs");
|
||||
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetDisplay");
|
||||
_glfw.egl.GetError = (PFN_eglGetError)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetError");
|
||||
_glfw.egl.Initialize = (PFN_eglInitialize)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglInitialize");
|
||||
_glfw.egl.Terminate = (PFN_eglTerminate)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglTerminate");
|
||||
_glfw.egl.BindAPI = (PFN_eglBindAPI)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglBindAPI");
|
||||
_glfw.egl.CreateContext = (PFN_eglCreateContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateContext");
|
||||
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroySurface");
|
||||
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
|
||||
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
|
||||
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
|
||||
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapBuffers");
|
||||
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapInterval");
|
||||
_glfw.egl.QueryString = (PFN_eglQueryString)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString");
|
||||
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
|
||||
_glfwPlatformGetModuleSymbol(_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;
|
||||
}
|
||||
|
||||
extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
if (extensions && eglGetError() == EGL_SUCCESS)
|
||||
_glfw.egl.EXT_client_extensions = GLFW_TRUE;
|
||||
|
||||
if (_glfw.egl.EXT_client_extensions)
|
||||
{
|
||||
_glfw.egl.EXT_platform_base =
|
||||
_glfwStringInExtensionString("EGL_EXT_platform_base", extensions);
|
||||
_glfw.egl.EXT_platform_x11 =
|
||||
_glfwStringInExtensionString("EGL_EXT_platform_x11", extensions);
|
||||
_glfw.egl.EXT_platform_wayland =
|
||||
_glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions);
|
||||
_glfw.egl.ANGLE_platform_angle =
|
||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions);
|
||||
_glfw.egl.ANGLE_platform_angle_opengl =
|
||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions);
|
||||
_glfw.egl.ANGLE_platform_angle_d3d =
|
||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions);
|
||||
_glfw.egl.ANGLE_platform_angle_vulkan =
|
||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
|
||||
_glfw.egl.ANGLE_platform_angle_metal =
|
||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
|
||||
}
|
||||
|
||||
if (_glfw.egl.EXT_platform_base)
|
||||
{
|
||||
_glfw.egl.GetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
|
||||
eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
_glfw.egl.CreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)
|
||||
eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
|
||||
}
|
||||
|
||||
_glfw.egl.platform = _glfw.platform.getEGLPlatform(&attribs);
|
||||
if (_glfw.egl.platform)
|
||||
{
|
||||
_glfw.egl.display =
|
||||
eglGetPlatformDisplayEXT(_glfw.egl.platform,
|
||||
_glfw.platform.getEGLNativeDisplay(),
|
||||
attribs);
|
||||
}
|
||||
else
|
||||
_glfw.egl.display = eglGetDisplay(_glfw.platform.getEGLNativeDisplay());
|
||||
|
||||
_glfw_free(attribs);
|
||||
|
||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
_glfwPlatformFreeModule(_glfw.egl.handle);
|
||||
_glfw.egl.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_ATTRIB(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;
|
||||
EGLNativeWindowType native;
|
||||
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))
|
||||
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)
|
||||
{
|
||||
SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||
EGL_NO_RESET_NOTIFICATION_KHR);
|
||||
}
|
||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||
{
|
||||
SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||
EGL_LOSE_CONTEXT_ON_RESET_KHR);
|
||||
}
|
||||
|
||||
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
||||
}
|
||||
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
{
|
||||
SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
||||
SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
|
||||
}
|
||||
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.egl.KHR_create_context_no_error)
|
||||
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
||||
}
|
||||
|
||||
if (mask)
|
||||
SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
||||
|
||||
if (flags)
|
||||
SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
||||
}
|
||||
|
||||
if (_glfw.egl.KHR_context_flush_control)
|
||||
{
|
||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||
{
|
||||
SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
||||
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
|
||||
}
|
||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||
{
|
||||
SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
||||
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
|
||||
}
|
||||
}
|
||||
|
||||
SET_ATTRIB(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)
|
||||
SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||
}
|
||||
|
||||
if (!fbconfig->doublebuffer)
|
||||
SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
|
||||
|
||||
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
|
||||
{
|
||||
if (_glfw.egl.EXT_present_opaque)
|
||||
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
||||
}
|
||||
|
||||
SET_ATTRIB(EGL_NONE, EGL_NONE);
|
||||
|
||||
native = _glfw.platform.getEGLNativeWindow(window);
|
||||
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
|
||||
// despite reporting EGL_EXT_platform_base
|
||||
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
|
||||
{
|
||||
window->context.egl.surface =
|
||||
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
|
||||
}
|
||||
else
|
||||
{
|
||||
window->context.egl.surface =
|
||||
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
|
||||
}
|
||||
|
||||
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
|
||||
"libOpenGL.so.0",
|
||||
"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 = _glfwPlatformLoadModule(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 SET_ATTRIB
|
||||
|
||||
// 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))
|
||||
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;
|
||||
}
|
||||
|
30
raylib/external/glfw/src/glfw.rc.in
vendored
Normal file
30
raylib/external/glfw/src/glfw.rc.in
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
#include <winver.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
|
||||
PRODUCTVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0
|
||||
{
|
||||
BLOCK "StringFileInfo"
|
||||
{
|
||||
BLOCK "040904B0"
|
||||
{
|
||||
VALUE "CompanyName", "GLFW"
|
||||
VALUE "FileDescription", "GLFW @GLFW_VERSION@ DLL"
|
||||
VALUE "FileVersion", "@GLFW_VERSION@"
|
||||
VALUE "OriginalFilename", "glfw3.dll"
|
||||
VALUE "ProductName", "GLFW"
|
||||
VALUE "ProductVersion", "@GLFW_VERSION@"
|
||||
}
|
||||
}
|
||||
BLOCK "VarFileInfo"
|
||||
{
|
||||
VALUE "Translation", 0x409, 1200
|
||||
}
|
||||
}
|
||||
|
719
raylib/external/glfw/src/glx_context.c
vendored
Normal file
719
raylib/external/glfw/src/glx_context.c
vendored
Normal file
@ -0,0 +1,719 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_GLFW_X11)
|
||||
|
||||
#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 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 = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
for (int 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);
|
||||
_glfw_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);
|
||||
assert(window != NULL);
|
||||
|
||||
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
|
||||
{
|
||||
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
|
||||
return _glfwPlatformGetModuleSymbol(_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)
|
||||
{
|
||||
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
|
||||
"libGLX.so.0",
|
||||
"libGL.so.1",
|
||||
"libGL.so",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
if (_glfw.glx.handle)
|
||||
return GLFW_TRUE;
|
||||
|
||||
for (int i = 0; sonames[i]; i++)
|
||||
{
|
||||
_glfw.glx.handle = _glfwPlatformLoadModule(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 = (PFNGLXGETFBCONFIGSPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigs");
|
||||
_glfw.glx.GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||
_glfw.glx.GetClientString = (PFNGLXGETCLIENTSTRINGPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetClientString");
|
||||
_glfw.glx.QueryExtension = (PFNGLXQUERYEXTENSIONPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtension");
|
||||
_glfw.glx.QueryVersion = (PFNGLXQUERYVERSIONPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryVersion");
|
||||
_glfw.glx.DestroyContext = (PFNGLXDESTROYCONTEXTPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyContext");
|
||||
_glfw.glx.MakeCurrent = (PFNGLXMAKECURRENTPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXMakeCurrent");
|
||||
_glfw.glx.SwapBuffers = (PFNGLXSWAPBUFFERSPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXSwapBuffers");
|
||||
_glfw.glx.QueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtensionsString");
|
||||
_glfw.glx.CreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateNewContext");
|
||||
_glfw.glx.CreateWindow = (PFNGLXCREATEWINDOWPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow");
|
||||
_glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow");
|
||||
_glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
|
||||
_glfwPlatformGetModuleSymbol(_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)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress");
|
||||
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
|
||||
_glfwPlatformGetModuleSymbol(_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 _glfwTerminateX11 for details)
|
||||
|
||||
if (_glfw.glx.handle)
|
||||
{
|
||||
_glfwPlatformFreeModule(_glfw.glx.handle);
|
||||
_glfw.glx.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_ATTRIB(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)
|
||||
{
|
||||
SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
GLX_NO_RESET_NOTIFICATION_ARB);
|
||||
}
|
||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||
{
|
||||
SET_ATTRIB(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)
|
||||
{
|
||||
SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||
}
|
||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||
{
|
||||
SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.glx.ARB_create_context_no_error)
|
||||
SET_ATTRIB(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)
|
||||
{
|
||||
SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||
SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||
}
|
||||
|
||||
if (mask)
|
||||
SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||
|
||||
if (flags)
|
||||
SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags);
|
||||
|
||||
SET_ATTRIB(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 SET_ATTRIB
|
||||
|
||||
// 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 (_glfw.platform.platformID != GLFW_PLATFORM_X11)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return window->context.glx.handle;
|
||||
}
|
||||
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(None);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
|
||||
return None;
|
||||
}
|
||||
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return None;
|
||||
}
|
||||
|
||||
return window->context.glx.window;
|
||||
}
|
||||
|
||||
#endif // _GLFW_X11
|
||||
|
528
raylib/external/glfw/src/init.c
vendored
Normal file
528
raylib/external/glfw/src/init.c
vendored
Normal file
@ -0,0 +1,528 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#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 GLFWallocator _glfwInitAllocator;
|
||||
static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
.hatButtons = GLFW_TRUE,
|
||||
.angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,
|
||||
.platformID = GLFW_ANY_PLATFORM,
|
||||
.vulkanLoader = NULL,
|
||||
.ns =
|
||||
{
|
||||
.menubar = GLFW_TRUE,
|
||||
.chdir = GLFW_TRUE
|
||||
},
|
||||
.x11 =
|
||||
{
|
||||
.xcbVulkanSurface = GLFW_TRUE,
|
||||
},
|
||||
.wl =
|
||||
{
|
||||
.libdecorMode = GLFW_WAYLAND_PREFER_LIBDECOR
|
||||
},
|
||||
};
|
||||
|
||||
// The allocation function used when no custom allocator is set
|
||||
//
|
||||
static void* defaultAllocate(size_t size, void* user)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
// The deallocation function used when no custom allocator is set
|
||||
//
|
||||
static void defaultDeallocate(void* block, void* user)
|
||||
{
|
||||
free(block);
|
||||
}
|
||||
|
||||
// The reallocation function used when no custom allocator is set
|
||||
//
|
||||
static void* defaultReallocate(void* block, size_t size, void* user)
|
||||
{
|
||||
return realloc(block, size);
|
||||
}
|
||||
|
||||
// Terminate the library
|
||||
//
|
||||
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)
|
||||
_glfw.platform.setGammaRamp(monitor, &monitor->originalRamp);
|
||||
_glfwFreeMonitor(monitor);
|
||||
}
|
||||
|
||||
_glfw_free(_glfw.monitors);
|
||||
_glfw.monitors = NULL;
|
||||
_glfw.monitorCount = 0;
|
||||
|
||||
_glfw_free(_glfw.mappings);
|
||||
_glfw.mappings = NULL;
|
||||
_glfw.mappingCount = 0;
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
_glfw.platform.terminateJoysticks();
|
||||
_glfw.platform.terminate();
|
||||
|
||||
_glfw.initialized = GLFW_FALSE;
|
||||
|
||||
while (_glfw.errorListHead)
|
||||
{
|
||||
_GLFWerror* error = _glfw.errorListHead;
|
||||
_glfw.errorListHead = error->next;
|
||||
_glfw_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 = _glfw_calloc(strlen(line) + 1, 1);
|
||||
paths = _glfw_realloc(paths, *count * sizeof(char*));
|
||||
paths[*count - 1] = path;
|
||||
|
||||
while (*line)
|
||||
{
|
||||
if (line[0] == '%' && line[1] && line[2])
|
||||
{
|
||||
const char digits[3] = { line[1], line[2], '\0' };
|
||||
*path = (char) strtol(digits, NULL, 16);
|
||||
line += 2;
|
||||
}
|
||||
else
|
||||
*path = *line;
|
||||
|
||||
path++;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
char* _glfw_strdup(const char* source)
|
||||
{
|
||||
const size_t length = strlen(source);
|
||||
char* result = _glfw_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;
|
||||
}
|
||||
|
||||
void* _glfw_calloc(size_t count, size_t size)
|
||||
{
|
||||
if (count && size)
|
||||
{
|
||||
void* block;
|
||||
|
||||
if (count > SIZE_MAX / size)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block = _glfw.allocator.allocate(count * size, _glfw.allocator.user);
|
||||
if (block)
|
||||
return memset(block, 0, count * size);
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* _glfw_realloc(void* block, size_t size)
|
||||
{
|
||||
if (block && size)
|
||||
{
|
||||
void* resized = _glfw.allocator.reallocate(block, size, _glfw.allocator.user);
|
||||
if (resized)
|
||||
return resized;
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (block)
|
||||
{
|
||||
_glfw_free(block);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return _glfw_calloc(1, size);
|
||||
}
|
||||
|
||||
void _glfw_free(void* block)
|
||||
{
|
||||
if (block)
|
||||
_glfw.allocator.deallocate(block, _glfw.allocator.user);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW event API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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 if (code == GLFW_CURSOR_UNAVAILABLE)
|
||||
strcpy(description, "The specified cursor shape is unavailable");
|
||||
else if (code == GLFW_FEATURE_UNAVAILABLE)
|
||||
strcpy(description, "The requested feature cannot be implemented for this platform");
|
||||
else if (code == GLFW_FEATURE_UNIMPLEMENTED)
|
||||
strcpy(description, "The requested feature has not yet been implemented for this platform");
|
||||
else if (code == GLFW_PLATFORM_UNAVAILABLE)
|
||||
strcpy(description, "The requested platform is unavailable");
|
||||
else
|
||||
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||
}
|
||||
|
||||
if (_glfw.initialized)
|
||||
{
|
||||
error = _glfwPlatformGetTls(&_glfw.errorSlot);
|
||||
if (!error)
|
||||
{
|
||||
error = _glfw_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;
|
||||
|
||||
_glfw.allocator = _glfwInitAllocator;
|
||||
if (!_glfw.allocator.allocate)
|
||||
{
|
||||
_glfw.allocator.allocate = defaultAllocate;
|
||||
_glfw.allocator.reallocate = defaultReallocate;
|
||||
_glfw.allocator.deallocate = defaultDeallocate;
|
||||
}
|
||||
|
||||
if (!_glfwSelectPlatform(_glfw.hints.init.platformID, &_glfw.platform))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfw.platform.init())
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
|
||||
!_glfwPlatformCreateTls(&_glfw.errorSlot) ||
|
||||
!_glfwPlatformCreateTls(&_glfw.contextSlot))
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
|
||||
|
||||
_glfwInitGamepadMappings();
|
||||
|
||||
_glfwPlatformInitTimer();
|
||||
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
||||
|
||||
_glfw.initialized = GLFW_TRUE;
|
||||
|
||||
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_ANGLE_PLATFORM_TYPE:
|
||||
_glfwInitHints.angleType = value;
|
||||
return;
|
||||
case GLFW_PLATFORM:
|
||||
_glfwInitHints.platformID = value;
|
||||
return;
|
||||
case GLFW_COCOA_CHDIR_RESOURCES:
|
||||
_glfwInitHints.ns.chdir = value;
|
||||
return;
|
||||
case GLFW_COCOA_MENUBAR:
|
||||
_glfwInitHints.ns.menubar = value;
|
||||
return;
|
||||
case GLFW_X11_XCB_VULKAN_SURFACE:
|
||||
_glfwInitHints.x11.xcbVulkanSurface = value;
|
||||
return;
|
||||
case GLFW_WAYLAND_LIBDECOR:
|
||||
_glfwInitHints.wl.libdecorMode = value;
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid init hint 0x%08X", hint);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
|
||||
{
|
||||
if (allocator)
|
||||
{
|
||||
if (allocator->allocate && allocator->reallocate && allocator->deallocate)
|
||||
_glfwInitAllocator = *allocator;
|
||||
else
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Missing function in allocator");
|
||||
}
|
||||
else
|
||||
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
|
||||
}
|
||||
|
||||
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
|
||||
{
|
||||
_glfwInitHints.vulkanLoader = loader;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||
{
|
||||
if (major != NULL)
|
||||
*major = GLFW_VERSION_MAJOR;
|
||||
if (minor != NULL)
|
||||
*minor = GLFW_VERSION_MINOR;
|
||||
if (rev != NULL)
|
||||
*rev = GLFW_VERSION_REVISION;
|
||||
}
|
||||
|
||||
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(GLFWerrorfun, _glfwErrorCallback, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
1505
raylib/external/glfw/src/input.c
vendored
Normal file
1505
raylib/external/glfw/src/input.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1009
raylib/external/glfw/src/internal.h
vendored
Normal file
1009
raylib/external/glfw/src/internal.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
436
raylib/external/glfw/src/linux_joystick.c
vendored
Normal file
436
raylib/external/glfw/src/linux_joystick.c
vendored
Normal file
@ -0,0 +1,436 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||
|
||||
#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 | O_CLOEXEC);
|
||||
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_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 //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwDetectJoystickConnectionLinux(void)
|
||||
{
|
||||
if (_glfw.linjs.inotify <= 0)
|
||||
return;
|
||||
|
||||
ssize_t offset = 0;
|
||||
char buffer[16384];
|
||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||
|
||||
while (size > offset)
|
||||
{
|
||||
regmatch_t match;
|
||||
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
||||
|
||||
offset += sizeof(struct inotify_event) + e->len;
|
||||
|
||||
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
|
||||
continue;
|
||||
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
||||
|
||||
if (e->mask & (IN_CREATE | IN_ATTRIB))
|
||||
openJoystickDevice(path);
|
||||
else if (e->mask & IN_DELETE)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
{
|
||||
closeJoystick(_glfw.joysticks + jid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitJoysticksLinux(void)
|
||||
{
|
||||
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
|
||||
|
||||
_glfw.linjs.regexCompiled = (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) == 0);
|
||||
if (!_glfw.linjs.regexCompiled)
|
||||
{
|
||||
_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;
|
||||
}
|
||||
|
||||
void _glfwTerminateJoysticksLinux(void)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->connected)
|
||||
closeJoystick(js);
|
||||
}
|
||||
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
{
|
||||
if (_glfw.linjs.watch > 0)
|
||||
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
|
||||
|
||||
close(_glfw.linjs.inotify);
|
||||
}
|
||||
|
||||
if (_glfw.linjs.regexCompiled)
|
||||
regfree(&_glfw.linjs.regex);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPollJoystickLinux(_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;
|
||||
}
|
||||
|
||||
const char* _glfwGetMappingNameLinux(void)
|
||||
{
|
||||
return "Linux";
|
||||
}
|
||||
|
||||
void _glfwUpdateGamepadGUIDLinux(char* guid)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_LINUX_JOYSTICK
|
||||
|
64
raylib/external/glfw/src/linux_joystick.h
vendored
Normal file
64
raylib/external/glfw/src/linux_joystick.h
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs;
|
||||
#define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
|
||||
|
||||
// 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 regexCompiled;
|
||||
GLFWbool dropped;
|
||||
} _GLFWlibraryLinux;
|
||||
|
||||
void _glfwDetectJoystickConnectionLinux(void);
|
||||
|
||||
GLFWbool _glfwInitJoysticksLinux(void);
|
||||
void _glfwTerminateJoysticksLinux(void);
|
||||
GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode);
|
||||
const char* _glfwGetMappingNameLinux(void);
|
||||
void _glfwUpdateGamepadGUIDLinux(char* guid);
|
||||
|
1002
raylib/external/glfw/src/mappings.h
vendored
Normal file
1002
raylib/external/glfw/src/mappings.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
82
raylib/external/glfw/src/mappings.h.in
vendored
Normal file
82
raylib/external/glfw/src/mappings.h.in
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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_WIN32)
|
||||
@GLFW_WIN32_MAPPINGS@
|
||||
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
|
||||
"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_WIN32
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
@GLFW_COCOA_MAPPINGS@
|
||||
#endif // _GLFW_COCOA
|
||||
|
||||
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||
@GLFW_LINUX_MAPPINGS@
|
||||
#endif // GLFW_BUILD_LINUX_JOYSTICK
|
||||
};
|
||||
|
548
raylib/external/glfw/src/monitor.c
vendored
Normal file
548
raylib/external/glfw/src/monitor.c
vendored
Normal file
@ -0,0 +1,548 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "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 = _glfw.platform.getVideoModes(monitor, &modeCount);
|
||||
if (!modes)
|
||||
return GLFW_FALSE;
|
||||
|
||||
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
|
||||
|
||||
_glfw_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)
|
||||
{
|
||||
assert(monitor != NULL);
|
||||
assert(action == GLFW_CONNECTED || action == GLFW_DISCONNECTED);
|
||||
assert(placement == _GLFW_INSERT_FIRST || placement == _GLFW_INSERT_LAST);
|
||||
|
||||
if (action == GLFW_CONNECTED)
|
||||
{
|
||||
_glfw.monitorCount++;
|
||||
_glfw.monitors =
|
||||
_glfw_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;
|
||||
_glfw.platform.getWindowSize(window, &width, &height);
|
||||
_glfw.platform.setWindowMonitor(window, NULL, 0, 0, width, height, 0);
|
||||
_glfw.platform.getWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
|
||||
_glfw.platform.setWindowPos(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)
|
||||
{
|
||||
assert(monitor != NULL);
|
||||
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 = _glfw_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;
|
||||
|
||||
_glfw.platform.freeMonitor(monitor);
|
||||
|
||||
_glfwFreeGammaArrays(&monitor->originalRamp);
|
||||
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||
|
||||
_glfw_free(monitor->modes);
|
||||
_glfw_free(monitor);
|
||||
}
|
||||
|
||||
// Allocates red, green and blue value arrays of the specified size
|
||||
//
|
||||
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
|
||||
{
|
||||
ramp->red = _glfw_calloc(size, sizeof(unsigned short));
|
||||
ramp->green = _glfw_calloc(size, sizeof(unsigned short));
|
||||
ramp->blue = _glfw_calloc(size, sizeof(unsigned short));
|
||||
ramp->size = size;
|
||||
}
|
||||
|
||||
// Frees the red, green and blue value arrays and clears the struct
|
||||
//
|
||||
void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
|
||||
{
|
||||
_glfw_free(ramp->red);
|
||||
_glfw_free(ramp->green);
|
||||
_glfw_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();
|
||||
|
||||
_glfw.platform.getMonitorPos(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();
|
||||
|
||||
_glfw.platform.getMonitorWorkarea(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();
|
||||
_glfw.platform.getMonitorContentScale(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(GLFWmonitorfun, _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);
|
||||
|
||||
if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode))
|
||||
return NULL;
|
||||
|
||||
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 = _glfw_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 = 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);
|
||||
_glfw_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 (!_glfw.platform.getGammaRamp(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 (!_glfw.platform.getGammaRamp(monitor, &monitor->originalRamp))
|
||||
return;
|
||||
}
|
||||
|
||||
_glfw.platform.setGammaRamp(monitor, ramp);
|
||||
}
|
||||
|
384
raylib/external/glfw/src/nsgl_context.m
vendored
Normal file
384
raylib/external/glfw/src/nsgl_context.m
vendored
Normal file
@ -0,0 +1,384 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
|
||||
#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);
|
||||
assert(window != NULL);
|
||||
|
||||
[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 via NSGL");
|
||||
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->major >= 3 && ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: The compatibility profile is not available on macOS");
|
||||
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 ADD_ATTRIB(a) \
|
||||
{ \
|
||||
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
}
|
||||
#define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); }
|
||||
|
||||
NSOpenGLPixelFormatAttribute attribs[40];
|
||||
int index = 0;
|
||||
|
||||
ADD_ATTRIB(NSOpenGLPFAAccelerated);
|
||||
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
|
||||
|
||||
if (ctxconfig->nsgl.offline)
|
||||
{
|
||||
ADD_ATTRIB(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
|
||||
ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||
if (ctxconfig->major >= 4)
|
||||
{
|
||||
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
||||
}
|
||||
else
|
||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||
if (ctxconfig->major >= 3)
|
||||
{
|
||||
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
||||
}
|
||||
|
||||
if (ctxconfig->major <= 2)
|
||||
{
|
||||
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
||||
SET_ATTRIB(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;
|
||||
|
||||
SET_ATTRIB(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;
|
||||
|
||||
SET_ATTRIB(NSOpenGLPFAColorSize, colorBits);
|
||||
}
|
||||
|
||||
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
||||
SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
||||
|
||||
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
||||
SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
||||
|
||||
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
||||
SET_ATTRIB(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
|
||||
ADD_ATTRIB(NSOpenGLPFAStereo);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fbconfig->doublebuffer)
|
||||
ADD_ATTRIB(NSOpenGLPFADoubleBuffer);
|
||||
|
||||
if (fbconfig->samples != GLFW_DONT_CARE)
|
||||
{
|
||||
if (fbconfig->samples == 0)
|
||||
{
|
||||
SET_ATTRIB(NSOpenGLPFASampleBuffers, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_ATTRIB(NSOpenGLPFASampleBuffers, 1);
|
||||
SET_ATTRIB(NSOpenGLPFASamples, fbconfig->samples);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
||||
// framebuffer, so there's no need (and no way) to request it
|
||||
|
||||
ADD_ATTRIB(0);
|
||||
|
||||
#undef ADD_ATTRIB
|
||||
#undef SET_ATTRIB
|
||||
|
||||
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.scaleFramebuffer];
|
||||
|
||||
[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 (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
|
||||
"NSGL: Platform not initialized");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return nil;
|
||||
}
|
||||
|
||||
return window->context.nsgl.object;
|
||||
}
|
||||
|
||||
#endif // _GLFW_COCOA
|
||||
|
264
raylib/external/glfw/src/null_init.c
vendored
Normal file
264
raylib/external/glfw/src/null_init.c
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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 "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
||||
{
|
||||
const _GLFWplatform null =
|
||||
{
|
||||
.platformID = GLFW_PLATFORM_NULL,
|
||||
.init = _glfwInitNull,
|
||||
.terminate = _glfwTerminateNull,
|
||||
.getCursorPos = _glfwGetCursorPosNull,
|
||||
.setCursorPos = _glfwSetCursorPosNull,
|
||||
.setCursorMode = _glfwSetCursorModeNull,
|
||||
.setRawMouseMotion = _glfwSetRawMouseMotionNull,
|
||||
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedNull,
|
||||
.createCursor = _glfwCreateCursorNull,
|
||||
.createStandardCursor = _glfwCreateStandardCursorNull,
|
||||
.destroyCursor = _glfwDestroyCursorNull,
|
||||
.setCursor = _glfwSetCursorNull,
|
||||
.getScancodeName = _glfwGetScancodeNameNull,
|
||||
.getKeyScancode = _glfwGetKeyScancodeNull,
|
||||
.setClipboardString = _glfwSetClipboardStringNull,
|
||||
.getClipboardString = _glfwGetClipboardStringNull,
|
||||
.initJoysticks = _glfwInitJoysticksNull,
|
||||
.terminateJoysticks = _glfwTerminateJoysticksNull,
|
||||
.pollJoystick = _glfwPollJoystickNull,
|
||||
.getMappingName = _glfwGetMappingNameNull,
|
||||
.updateGamepadGUID = _glfwUpdateGamepadGUIDNull,
|
||||
.freeMonitor = _glfwFreeMonitorNull,
|
||||
.getMonitorPos = _glfwGetMonitorPosNull,
|
||||
.getMonitorContentScale = _glfwGetMonitorContentScaleNull,
|
||||
.getMonitorWorkarea = _glfwGetMonitorWorkareaNull,
|
||||
.getVideoModes = _glfwGetVideoModesNull,
|
||||
.getVideoMode = _glfwGetVideoModeNull,
|
||||
.getGammaRamp = _glfwGetGammaRampNull,
|
||||
.setGammaRamp = _glfwSetGammaRampNull,
|
||||
.createWindow = _glfwCreateWindowNull,
|
||||
.destroyWindow = _glfwDestroyWindowNull,
|
||||
.setWindowTitle = _glfwSetWindowTitleNull,
|
||||
.setWindowIcon = _glfwSetWindowIconNull,
|
||||
.getWindowPos = _glfwGetWindowPosNull,
|
||||
.setWindowPos = _glfwSetWindowPosNull,
|
||||
.getWindowSize = _glfwGetWindowSizeNull,
|
||||
.setWindowSize = _glfwSetWindowSizeNull,
|
||||
.setWindowSizeLimits = _glfwSetWindowSizeLimitsNull,
|
||||
.setWindowAspectRatio = _glfwSetWindowAspectRatioNull,
|
||||
.getFramebufferSize = _glfwGetFramebufferSizeNull,
|
||||
.getWindowFrameSize = _glfwGetWindowFrameSizeNull,
|
||||
.getWindowContentScale = _glfwGetWindowContentScaleNull,
|
||||
.iconifyWindow = _glfwIconifyWindowNull,
|
||||
.restoreWindow = _glfwRestoreWindowNull,
|
||||
.maximizeWindow = _glfwMaximizeWindowNull,
|
||||
.showWindow = _glfwShowWindowNull,
|
||||
.hideWindow = _glfwHideWindowNull,
|
||||
.requestWindowAttention = _glfwRequestWindowAttentionNull,
|
||||
.focusWindow = _glfwFocusWindowNull,
|
||||
.setWindowMonitor = _glfwSetWindowMonitorNull,
|
||||
.windowFocused = _glfwWindowFocusedNull,
|
||||
.windowIconified = _glfwWindowIconifiedNull,
|
||||
.windowVisible = _glfwWindowVisibleNull,
|
||||
.windowMaximized = _glfwWindowMaximizedNull,
|
||||
.windowHovered = _glfwWindowHoveredNull,
|
||||
.framebufferTransparent = _glfwFramebufferTransparentNull,
|
||||
.getWindowOpacity = _glfwGetWindowOpacityNull,
|
||||
.setWindowResizable = _glfwSetWindowResizableNull,
|
||||
.setWindowDecorated = _glfwSetWindowDecoratedNull,
|
||||
.setWindowFloating = _glfwSetWindowFloatingNull,
|
||||
.setWindowOpacity = _glfwSetWindowOpacityNull,
|
||||
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughNull,
|
||||
.pollEvents = _glfwPollEventsNull,
|
||||
.waitEvents = _glfwWaitEventsNull,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutNull,
|
||||
.postEmptyEvent = _glfwPostEmptyEventNull,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformNull,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayNull,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowNull,
|
||||
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsNull,
|
||||
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportNull,
|
||||
.createWindowSurface = _glfwCreateWindowSurfaceNull
|
||||
};
|
||||
|
||||
*platform = null;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
int _glfwInitNull(void)
|
||||
{
|
||||
int scancode;
|
||||
|
||||
memset(_glfw.null.keycodes, -1, sizeof(_glfw.null.keycodes));
|
||||
memset(_glfw.null.scancodes, -1, sizeof(_glfw.null.scancodes));
|
||||
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_SPACE] = GLFW_KEY_SPACE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_COMMA] = GLFW_KEY_COMMA;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_MINUS] = GLFW_KEY_MINUS;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_PERIOD] = GLFW_KEY_PERIOD;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_SLASH] = GLFW_KEY_SLASH;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_0] = GLFW_KEY_0;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_1] = GLFW_KEY_1;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_2] = GLFW_KEY_2;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_3] = GLFW_KEY_3;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_4] = GLFW_KEY_4;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_5] = GLFW_KEY_5;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_6] = GLFW_KEY_6;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_7] = GLFW_KEY_7;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_8] = GLFW_KEY_8;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_9] = GLFW_KEY_9;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_SEMICOLON] = GLFW_KEY_SEMICOLON;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_EQUAL] = GLFW_KEY_EQUAL;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_A] = GLFW_KEY_A;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_B] = GLFW_KEY_B;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_C] = GLFW_KEY_C;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_D] = GLFW_KEY_D;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_E] = GLFW_KEY_E;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F] = GLFW_KEY_F;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_G] = GLFW_KEY_G;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_H] = GLFW_KEY_H;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_I] = GLFW_KEY_I;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_J] = GLFW_KEY_J;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_K] = GLFW_KEY_K;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_L] = GLFW_KEY_L;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_M] = GLFW_KEY_M;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_N] = GLFW_KEY_N;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_O] = GLFW_KEY_O;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_P] = GLFW_KEY_P;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_Q] = GLFW_KEY_Q;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_R] = GLFW_KEY_R;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_S] = GLFW_KEY_S;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_T] = GLFW_KEY_T;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_U] = GLFW_KEY_U;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_V] = GLFW_KEY_V;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_W] = GLFW_KEY_W;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_X] = GLFW_KEY_X;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_Y] = GLFW_KEY_Y;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_Z] = GLFW_KEY_Z;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_BRACKET] = GLFW_KEY_LEFT_BRACKET;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_BACKSLASH] = GLFW_KEY_BACKSLASH;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_BRACKET] = GLFW_KEY_RIGHT_BRACKET;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_GRAVE_ACCENT] = GLFW_KEY_GRAVE_ACCENT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_WORLD_1] = GLFW_KEY_WORLD_1;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_WORLD_2] = GLFW_KEY_WORLD_2;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_ESCAPE] = GLFW_KEY_ESCAPE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_ENTER] = GLFW_KEY_ENTER;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_TAB] = GLFW_KEY_TAB;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_BACKSPACE] = GLFW_KEY_BACKSPACE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_INSERT] = GLFW_KEY_INSERT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_DELETE] = GLFW_KEY_DELETE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT] = GLFW_KEY_RIGHT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_LEFT] = GLFW_KEY_LEFT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_DOWN] = GLFW_KEY_DOWN;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_UP] = GLFW_KEY_UP;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_PAGE_UP] = GLFW_KEY_PAGE_UP;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_PAGE_DOWN] = GLFW_KEY_PAGE_DOWN;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_HOME] = GLFW_KEY_HOME;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_END] = GLFW_KEY_END;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_CAPS_LOCK] = GLFW_KEY_CAPS_LOCK;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_SCROLL_LOCK] = GLFW_KEY_SCROLL_LOCK;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_NUM_LOCK] = GLFW_KEY_NUM_LOCK;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_PRINT_SCREEN] = GLFW_KEY_PRINT_SCREEN;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_PAUSE] = GLFW_KEY_PAUSE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F1] = GLFW_KEY_F1;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F2] = GLFW_KEY_F2;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F3] = GLFW_KEY_F3;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F4] = GLFW_KEY_F4;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F5] = GLFW_KEY_F5;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F6] = GLFW_KEY_F6;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F7] = GLFW_KEY_F7;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F8] = GLFW_KEY_F8;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F9] = GLFW_KEY_F9;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F10] = GLFW_KEY_F10;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F11] = GLFW_KEY_F11;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F12] = GLFW_KEY_F12;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F13] = GLFW_KEY_F13;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F14] = GLFW_KEY_F14;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F15] = GLFW_KEY_F15;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F16] = GLFW_KEY_F16;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F17] = GLFW_KEY_F17;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F18] = GLFW_KEY_F18;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F19] = GLFW_KEY_F19;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F20] = GLFW_KEY_F20;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F21] = GLFW_KEY_F21;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F22] = GLFW_KEY_F22;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F23] = GLFW_KEY_F23;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F24] = GLFW_KEY_F24;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_F25] = GLFW_KEY_F25;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_0] = GLFW_KEY_KP_0;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_1] = GLFW_KEY_KP_1;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_2] = GLFW_KEY_KP_2;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_3] = GLFW_KEY_KP_3;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_4] = GLFW_KEY_KP_4;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_5] = GLFW_KEY_KP_5;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_6] = GLFW_KEY_KP_6;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_7] = GLFW_KEY_KP_7;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_8] = GLFW_KEY_KP_8;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_9] = GLFW_KEY_KP_9;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_DECIMAL] = GLFW_KEY_KP_DECIMAL;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_DIVIDE] = GLFW_KEY_KP_DIVIDE;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_MULTIPLY] = GLFW_KEY_KP_MULTIPLY;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_SUBTRACT] = GLFW_KEY_KP_SUBTRACT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_ADD] = GLFW_KEY_KP_ADD;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_ENTER] = GLFW_KEY_KP_ENTER;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_KP_EQUAL] = GLFW_KEY_KP_EQUAL;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_SHIFT] = GLFW_KEY_LEFT_SHIFT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_CONTROL] = GLFW_KEY_LEFT_CONTROL;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_ALT] = GLFW_KEY_LEFT_ALT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_SUPER] = GLFW_KEY_LEFT_SUPER;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SHIFT] = GLFW_KEY_RIGHT_SHIFT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_CONTROL] = GLFW_KEY_RIGHT_CONTROL;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_ALT] = GLFW_KEY_RIGHT_ALT;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SUPER] = GLFW_KEY_RIGHT_SUPER;
|
||||
_glfw.null.keycodes[GLFW_NULL_SC_MENU] = GLFW_KEY_MENU;
|
||||
|
||||
for (scancode = GLFW_NULL_SC_FIRST; scancode < GLFW_NULL_SC_LAST; scancode++)
|
||||
{
|
||||
if (_glfw.null.keycodes[scancode] > 0)
|
||||
_glfw.null.scancodes[_glfw.null.keycodes[scancode]] = scancode;
|
||||
}
|
||||
|
||||
_glfwPollMonitorsNull();
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwTerminateNull(void)
|
||||
{
|
||||
free(_glfw.null.clipboardString);
|
||||
_glfwTerminateOSMesa();
|
||||
_glfwTerminateEGL();
|
||||
}
|
||||
|
56
raylib/external/glfw/src/null_joystick.c
vendored
Normal file
56
raylib/external/glfw/src/null_joystick.c
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitJoysticksNull(void)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwTerminateJoysticksNull(void)
|
||||
{
|
||||
}
|
||||
|
||||
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
const char* _glfwGetMappingNameNull(void)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void _glfwUpdateGamepadGUIDNull(char* guid)
|
||||
{
|
||||
}
|
||||
|
32
raylib/external/glfw/src/null_joystick.h
vendored
Normal file
32
raylib/external/glfw/src/null_joystick.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
GLFWbool _glfwInitJoysticksNull(void);
|
||||
void _glfwTerminateJoysticksNull(void);
|
||||
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode);
|
||||
const char* _glfwGetMappingNameNull(void);
|
||||
void _glfwUpdateGamepadGUIDNull(char* guid);
|
||||
|
160
raylib/external/glfw/src/null_monitor.c
vendored
Normal file
160
raylib/external/glfw/src/null_monitor.c
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// The the sole (fake) video mode of our (sole) fake monitor
|
||||
//
|
||||
static GLFWvidmode getVideoMode(void)
|
||||
{
|
||||
GLFWvidmode mode;
|
||||
mode.width = 1920;
|
||||
mode.height = 1080;
|
||||
mode.redBits = 8;
|
||||
mode.greenBits = 8;
|
||||
mode.blueBits = 8;
|
||||
mode.refreshRate = 60;
|
||||
return mode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPollMonitorsNull(void)
|
||||
{
|
||||
const float dpi = 141.f;
|
||||
const GLFWvidmode mode = getVideoMode();
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor("Null SuperNoop 0",
|
||||
(int) (mode.width * 25.4f / dpi),
|
||||
(int) (mode.height * 25.4f / dpi));
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwFreeMonitorNull(_GLFWmonitor* monitor)
|
||||
{
|
||||
_glfwFreeGammaArrays(&monitor->null.ramp);
|
||||
}
|
||||
|
||||
void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = 0;
|
||||
if (ypos)
|
||||
*ypos = 0;
|
||||
}
|
||||
|
||||
void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
if (xscale)
|
||||
*xscale = 1.f;
|
||||
if (yscale)
|
||||
*yscale = 1.f;
|
||||
}
|
||||
|
||||
void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
const GLFWvidmode mode = getVideoMode();
|
||||
|
||||
if (xpos)
|
||||
*xpos = 0;
|
||||
if (ypos)
|
||||
*ypos = 10;
|
||||
if (width)
|
||||
*width = mode.width;
|
||||
if (height)
|
||||
*height = mode.height - 10;
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found)
|
||||
{
|
||||
GLFWvidmode* mode = _glfw_calloc(1, sizeof(GLFWvidmode));
|
||||
*mode = getVideoMode();
|
||||
*found = 1;
|
||||
return mode;
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
*mode = getVideoMode();
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
if (!monitor->null.ramp.size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
_glfwAllocGammaArrays(&monitor->null.ramp, 256);
|
||||
|
||||
for (i = 0; i < monitor->null.ramp.size; i++)
|
||||
{
|
||||
const float gamma = 2.2f;
|
||||
float value;
|
||||
value = i / (float) (monitor->null.ramp.size - 1);
|
||||
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||
value = fminf(value, 65535.f);
|
||||
|
||||
monitor->null.ramp.red[i] = (unsigned short) value;
|
||||
monitor->null.ramp.green[i] = (unsigned short) value;
|
||||
monitor->null.ramp.blue[i] = (unsigned short) value;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwAllocGammaArrays(ramp, monitor->null.ramp.size);
|
||||
memcpy(ramp->red, monitor->null.ramp.red, sizeof(short) * ramp->size);
|
||||
memcpy(ramp->green, monitor->null.ramp.green, sizeof(short) * ramp->size);
|
||||
memcpy(ramp->blue, monitor->null.ramp.blue, sizeof(short) * ramp->size);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
if (monitor->null.ramp.size != ramp->size)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Null: Gamma ramp size must match current ramp size");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(monitor->null.ramp.red, ramp->red, sizeof(short) * ramp->size);
|
||||
memcpy(monitor->null.ramp.green, ramp->green, sizeof(short) * ramp->size);
|
||||
memcpy(monitor->null.ramp.blue, ramp->blue, sizeof(short) * ramp->size);
|
||||
}
|
||||
|
271
raylib/external/glfw/src/null_platform.h
vendored
Normal file
271
raylib/external/glfw/src/null_platform.h
vendored
Normal file
@ -0,0 +1,271 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - 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 GLFW_NULL_WINDOW_STATE _GLFWwindowNull null;
|
||||
#define GLFW_NULL_LIBRARY_WINDOW_STATE _GLFWlibraryNull null;
|
||||
#define GLFW_NULL_MONITOR_STATE _GLFWmonitorNull null;
|
||||
|
||||
#define GLFW_NULL_CONTEXT_STATE
|
||||
#define GLFW_NULL_CURSOR_STATE
|
||||
#define GLFW_NULL_LIBRARY_CONTEXT_STATE
|
||||
|
||||
#define GLFW_NULL_SC_FIRST GLFW_NULL_SC_SPACE
|
||||
#define GLFW_NULL_SC_SPACE 1
|
||||
#define GLFW_NULL_SC_APOSTROPHE 2
|
||||
#define GLFW_NULL_SC_COMMA 3
|
||||
#define GLFW_NULL_SC_MINUS 4
|
||||
#define GLFW_NULL_SC_PERIOD 5
|
||||
#define GLFW_NULL_SC_SLASH 6
|
||||
#define GLFW_NULL_SC_0 7
|
||||
#define GLFW_NULL_SC_1 8
|
||||
#define GLFW_NULL_SC_2 9
|
||||
#define GLFW_NULL_SC_3 10
|
||||
#define GLFW_NULL_SC_4 11
|
||||
#define GLFW_NULL_SC_5 12
|
||||
#define GLFW_NULL_SC_6 13
|
||||
#define GLFW_NULL_SC_7 14
|
||||
#define GLFW_NULL_SC_8 15
|
||||
#define GLFW_NULL_SC_9 16
|
||||
#define GLFW_NULL_SC_SEMICOLON 17
|
||||
#define GLFW_NULL_SC_EQUAL 18
|
||||
#define GLFW_NULL_SC_LEFT_BRACKET 19
|
||||
#define GLFW_NULL_SC_BACKSLASH 20
|
||||
#define GLFW_NULL_SC_RIGHT_BRACKET 21
|
||||
#define GLFW_NULL_SC_GRAVE_ACCENT 22
|
||||
#define GLFW_NULL_SC_WORLD_1 23
|
||||
#define GLFW_NULL_SC_WORLD_2 24
|
||||
#define GLFW_NULL_SC_ESCAPE 25
|
||||
#define GLFW_NULL_SC_ENTER 26
|
||||
#define GLFW_NULL_SC_TAB 27
|
||||
#define GLFW_NULL_SC_BACKSPACE 28
|
||||
#define GLFW_NULL_SC_INSERT 29
|
||||
#define GLFW_NULL_SC_DELETE 30
|
||||
#define GLFW_NULL_SC_RIGHT 31
|
||||
#define GLFW_NULL_SC_LEFT 32
|
||||
#define GLFW_NULL_SC_DOWN 33
|
||||
#define GLFW_NULL_SC_UP 34
|
||||
#define GLFW_NULL_SC_PAGE_UP 35
|
||||
#define GLFW_NULL_SC_PAGE_DOWN 36
|
||||
#define GLFW_NULL_SC_HOME 37
|
||||
#define GLFW_NULL_SC_END 38
|
||||
#define GLFW_NULL_SC_CAPS_LOCK 39
|
||||
#define GLFW_NULL_SC_SCROLL_LOCK 40
|
||||
#define GLFW_NULL_SC_NUM_LOCK 41
|
||||
#define GLFW_NULL_SC_PRINT_SCREEN 42
|
||||
#define GLFW_NULL_SC_PAUSE 43
|
||||
#define GLFW_NULL_SC_A 44
|
||||
#define GLFW_NULL_SC_B 45
|
||||
#define GLFW_NULL_SC_C 46
|
||||
#define GLFW_NULL_SC_D 47
|
||||
#define GLFW_NULL_SC_E 48
|
||||
#define GLFW_NULL_SC_F 49
|
||||
#define GLFW_NULL_SC_G 50
|
||||
#define GLFW_NULL_SC_H 51
|
||||
#define GLFW_NULL_SC_I 52
|
||||
#define GLFW_NULL_SC_J 53
|
||||
#define GLFW_NULL_SC_K 54
|
||||
#define GLFW_NULL_SC_L 55
|
||||
#define GLFW_NULL_SC_M 56
|
||||
#define GLFW_NULL_SC_N 57
|
||||
#define GLFW_NULL_SC_O 58
|
||||
#define GLFW_NULL_SC_P 59
|
||||
#define GLFW_NULL_SC_Q 60
|
||||
#define GLFW_NULL_SC_R 61
|
||||
#define GLFW_NULL_SC_S 62
|
||||
#define GLFW_NULL_SC_T 63
|
||||
#define GLFW_NULL_SC_U 64
|
||||
#define GLFW_NULL_SC_V 65
|
||||
#define GLFW_NULL_SC_W 66
|
||||
#define GLFW_NULL_SC_X 67
|
||||
#define GLFW_NULL_SC_Y 68
|
||||
#define GLFW_NULL_SC_Z 69
|
||||
#define GLFW_NULL_SC_F1 70
|
||||
#define GLFW_NULL_SC_F2 71
|
||||
#define GLFW_NULL_SC_F3 72
|
||||
#define GLFW_NULL_SC_F4 73
|
||||
#define GLFW_NULL_SC_F5 74
|
||||
#define GLFW_NULL_SC_F6 75
|
||||
#define GLFW_NULL_SC_F7 76
|
||||
#define GLFW_NULL_SC_F8 77
|
||||
#define GLFW_NULL_SC_F9 78
|
||||
#define GLFW_NULL_SC_F10 79
|
||||
#define GLFW_NULL_SC_F11 80
|
||||
#define GLFW_NULL_SC_F12 81
|
||||
#define GLFW_NULL_SC_F13 82
|
||||
#define GLFW_NULL_SC_F14 83
|
||||
#define GLFW_NULL_SC_F15 84
|
||||
#define GLFW_NULL_SC_F16 85
|
||||
#define GLFW_NULL_SC_F17 86
|
||||
#define GLFW_NULL_SC_F18 87
|
||||
#define GLFW_NULL_SC_F19 88
|
||||
#define GLFW_NULL_SC_F20 89
|
||||
#define GLFW_NULL_SC_F21 90
|
||||
#define GLFW_NULL_SC_F22 91
|
||||
#define GLFW_NULL_SC_F23 92
|
||||
#define GLFW_NULL_SC_F24 93
|
||||
#define GLFW_NULL_SC_F25 94
|
||||
#define GLFW_NULL_SC_KP_0 95
|
||||
#define GLFW_NULL_SC_KP_1 96
|
||||
#define GLFW_NULL_SC_KP_2 97
|
||||
#define GLFW_NULL_SC_KP_3 98
|
||||
#define GLFW_NULL_SC_KP_4 99
|
||||
#define GLFW_NULL_SC_KP_5 100
|
||||
#define GLFW_NULL_SC_KP_6 101
|
||||
#define GLFW_NULL_SC_KP_7 102
|
||||
#define GLFW_NULL_SC_KP_8 103
|
||||
#define GLFW_NULL_SC_KP_9 104
|
||||
#define GLFW_NULL_SC_KP_DECIMAL 105
|
||||
#define GLFW_NULL_SC_KP_DIVIDE 106
|
||||
#define GLFW_NULL_SC_KP_MULTIPLY 107
|
||||
#define GLFW_NULL_SC_KP_SUBTRACT 108
|
||||
#define GLFW_NULL_SC_KP_ADD 109
|
||||
#define GLFW_NULL_SC_KP_ENTER 110
|
||||
#define GLFW_NULL_SC_KP_EQUAL 111
|
||||
#define GLFW_NULL_SC_LEFT_SHIFT 112
|
||||
#define GLFW_NULL_SC_LEFT_CONTROL 113
|
||||
#define GLFW_NULL_SC_LEFT_ALT 114
|
||||
#define GLFW_NULL_SC_LEFT_SUPER 115
|
||||
#define GLFW_NULL_SC_RIGHT_SHIFT 116
|
||||
#define GLFW_NULL_SC_RIGHT_CONTROL 117
|
||||
#define GLFW_NULL_SC_RIGHT_ALT 118
|
||||
#define GLFW_NULL_SC_RIGHT_SUPER 119
|
||||
#define GLFW_NULL_SC_MENU 120
|
||||
#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU
|
||||
|
||||
// Null-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowNull
|
||||
{
|
||||
int xpos;
|
||||
int ypos;
|
||||
int width;
|
||||
int height;
|
||||
GLFWbool visible;
|
||||
GLFWbool iconified;
|
||||
GLFWbool maximized;
|
||||
GLFWbool resizable;
|
||||
GLFWbool decorated;
|
||||
GLFWbool floating;
|
||||
GLFWbool transparent;
|
||||
float opacity;
|
||||
} _GLFWwindowNull;
|
||||
|
||||
// Null-specific per-monitor data
|
||||
//
|
||||
typedef struct _GLFWmonitorNull
|
||||
{
|
||||
GLFWgammaramp ramp;
|
||||
} _GLFWmonitorNull;
|
||||
|
||||
// Null-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryNull
|
||||
{
|
||||
int xcursor;
|
||||
int ycursor;
|
||||
char* clipboardString;
|
||||
_GLFWwindow* focusedWindow;
|
||||
uint16_t keycodes[GLFW_NULL_SC_LAST + 1];
|
||||
uint8_t scancodes[GLFW_KEY_LAST + 1];
|
||||
} _GLFWlibraryNull;
|
||||
|
||||
void _glfwPollMonitorsNull(void);
|
||||
|
||||
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform);
|
||||
int _glfwInitNull(void);
|
||||
void _glfwTerminateNull(void);
|
||||
|
||||
void _glfwFreeMonitorNull(_GLFWmonitor* monitor);
|
||||
void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||
void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor, float* xscale, float* yscale);
|
||||
void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
|
||||
GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found);
|
||||
GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||
GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyWindowNull(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
|
||||
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height);
|
||||
void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
|
||||
void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d);
|
||||
void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwGetWindowFrameSizeNull(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
|
||||
void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale);
|
||||
void _glfwIconifyWindowNull(_GLFWwindow* window);
|
||||
void _glfwRestoreWindowNull(_GLFWwindow* window);
|
||||
void _glfwMaximizeWindowNull(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window);
|
||||
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window);
|
||||
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled);
|
||||
float _glfwGetWindowOpacityNull(_GLFWwindow* window);
|
||||
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity);
|
||||
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled);
|
||||
GLFWbool _glfwRawMouseMotionSupportedNull(void);
|
||||
void _glfwShowWindowNull(_GLFWwindow* window);
|
||||
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
|
||||
void _glfwHideWindowNull(_GLFWwindow* window);
|
||||
void _glfwFocusWindowNull(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window);
|
||||
void _glfwPollEventsNull(void);
|
||||
void _glfwWaitEventsNull(void);
|
||||
void _glfwWaitEventsTimeoutNull(double timeout);
|
||||
void _glfwPostEmptyEventNull(void);
|
||||
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos);
|
||||
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y);
|
||||
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode);
|
||||
GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
||||
GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape);
|
||||
void _glfwDestroyCursorNull(_GLFWcursor* cursor);
|
||||
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||
void _glfwSetClipboardStringNull(const char* string);
|
||||
const char* _glfwGetClipboardStringNull(void);
|
||||
const char* _glfwGetScancodeNameNull(int scancode);
|
||||
int _glfwGetKeyScancodeNull(int key);
|
||||
|
||||
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
|
||||
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
|
||||
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
|
||||
|
||||
void _glfwGetRequiredInstanceExtensionsNull(char** extensions);
|
||||
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
|
||||
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
||||
|
||||
void _glfwPollMonitorsNull(void);
|
||||
|
720
raylib/external/glfw/src/null_window.c
vendored
Normal file
720
raylib/external/glfw/src/null_window.c
vendored
Normal file
@ -0,0 +1,720 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2024 M374LX <wilsalx@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 "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
|
||||
{
|
||||
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
|
||||
{
|
||||
const float ratio = (float) window->numer / (float) window->denom;
|
||||
*height = (int) (*width / ratio);
|
||||
}
|
||||
|
||||
if (window->minwidth != GLFW_DONT_CARE)
|
||||
*width = _glfw_max(*width, window->minwidth);
|
||||
else if (window->maxwidth != GLFW_DONT_CARE)
|
||||
*width = _glfw_min(*width, window->maxwidth);
|
||||
|
||||
if (window->minheight != GLFW_DONT_CARE)
|
||||
*height = _glfw_min(*height, window->minheight);
|
||||
else if (window->maxheight != GLFW_DONT_CARE)
|
||||
*height = _glfw_max(*height, window->maxheight);
|
||||
}
|
||||
|
||||
static void fitToMonitor(_GLFWwindow* window)
|
||||
{
|
||||
GLFWvidmode mode;
|
||||
_glfwGetVideoModeNull(window->monitor, &mode);
|
||||
_glfwGetMonitorPosNull(window->monitor,
|
||||
&window->null.xpos,
|
||||
&window->null.ypos);
|
||||
window->null.width = mode.width;
|
||||
window->null.height = mode.height;
|
||||
}
|
||||
|
||||
static void acquireMonitorNull(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputMonitorWindow(window->monitor, window);
|
||||
}
|
||||
|
||||
static void releaseMonitorNull(_GLFWwindow* window)
|
||||
{
|
||||
if (window->monitor->window != window)
|
||||
return;
|
||||
|
||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
||||
}
|
||||
|
||||
static int createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
if (window->monitor)
|
||||
fitToMonitor(window);
|
||||
else
|
||||
{
|
||||
if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION)
|
||||
{
|
||||
window->null.xpos = 17;
|
||||
window->null.ypos = 17;
|
||||
}
|
||||
else
|
||||
{
|
||||
window->null.xpos = wndconfig->xpos;
|
||||
window->null.ypos = wndconfig->ypos;
|
||||
}
|
||||
|
||||
window->null.width = wndconfig->width;
|
||||
window->null.height = wndconfig->height;
|
||||
}
|
||||
|
||||
window->null.visible = wndconfig->visible;
|
||||
window->null.decorated = wndconfig->decorated;
|
||||
window->null.maximized = wndconfig->maximized;
|
||||
window->null.floating = wndconfig->floating;
|
||||
window->null.transparent = fbconfig->transparent;
|
||||
window->null.opacity = 1.f;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API ||
|
||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitOSMesa())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwRefreshContextAttribs(window, ctxconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (wndconfig->mousePassthrough)
|
||||
_glfwSetWindowMousePassthroughNull(window, GLFW_TRUE);
|
||||
|
||||
if (window->monitor)
|
||||
{
|
||||
_glfwShowWindowNull(window);
|
||||
_glfwFocusWindowNull(window);
|
||||
acquireMonitorNull(window);
|
||||
|
||||
if (wndconfig->centerCursor)
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wndconfig->visible)
|
||||
{
|
||||
_glfwShowWindowNull(window);
|
||||
if (wndconfig->focused)
|
||||
_glfwFocusWindowNull(window);
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwDestroyWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
if (window->monitor)
|
||||
releaseMonitorNull(window);
|
||||
|
||||
if (_glfw.null.focusedWindow == window)
|
||||
_glfw.null.focusedWindow = NULL;
|
||||
|
||||
if (window->context.destroy)
|
||||
window->context.destroy(window);
|
||||
}
|
||||
|
||||
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwSetWindowMonitorNull(_GLFWwindow* window,
|
||||
_GLFWmonitor* monitor,
|
||||
int xpos, int ypos,
|
||||
int width, int height,
|
||||
int refreshRate)
|
||||
{
|
||||
if (window->monitor == monitor)
|
||||
{
|
||||
if (!monitor)
|
||||
{
|
||||
_glfwSetWindowPosNull(window, xpos, ypos);
|
||||
_glfwSetWindowSizeNull(window, width, height);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
releaseMonitorNull(window);
|
||||
|
||||
_glfwInputWindowMonitor(window, monitor);
|
||||
|
||||
if (window->monitor)
|
||||
{
|
||||
window->null.visible = GLFW_TRUE;
|
||||
acquireMonitorNull(window);
|
||||
fitToMonitor(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwSetWindowPosNull(window, xpos, ypos);
|
||||
_glfwSetWindowSizeNull(window, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = window->null.xpos;
|
||||
if (ypos)
|
||||
*ypos = window->null.ypos;
|
||||
}
|
||||
|
||||
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos)
|
||||
{
|
||||
if (window->monitor)
|
||||
return;
|
||||
|
||||
if (window->null.xpos != xpos || window->null.ypos != ypos)
|
||||
{
|
||||
window->null.xpos = xpos;
|
||||
window->null.ypos = ypos;
|
||||
_glfwInputWindowPos(window, xpos, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height)
|
||||
{
|
||||
if (width)
|
||||
*width = window->null.width;
|
||||
if (height)
|
||||
*height = window->null.height;
|
||||
}
|
||||
|
||||
void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
if (window->monitor)
|
||||
return;
|
||||
|
||||
if (window->null.width != width || window->null.height != height)
|
||||
{
|
||||
window->null.width = width;
|
||||
window->null.height = height;
|
||||
_glfwInputFramebufferSize(window, width, height);
|
||||
_glfwInputWindowDamage(window);
|
||||
_glfwInputWindowSize(window, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window,
|
||||
int minwidth, int minheight,
|
||||
int maxwidth, int maxheight)
|
||||
{
|
||||
int width = window->null.width;
|
||||
int height = window->null.height;
|
||||
applySizeLimits(window, &width, &height);
|
||||
_glfwSetWindowSizeNull(window, width, height);
|
||||
}
|
||||
|
||||
void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d)
|
||||
{
|
||||
int width = window->null.width;
|
||||
int height = window->null.height;
|
||||
applySizeLimits(window, &width, &height);
|
||||
_glfwSetWindowSizeNull(window, width, height);
|
||||
}
|
||||
|
||||
void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height)
|
||||
{
|
||||
if (width)
|
||||
*width = window->null.width;
|
||||
if (height)
|
||||
*height = window->null.height;
|
||||
}
|
||||
|
||||
void _glfwGetWindowFrameSizeNull(_GLFWwindow* window,
|
||||
int* left, int* top,
|
||||
int* right, int* bottom)
|
||||
{
|
||||
if (window->null.decorated && !window->monitor)
|
||||
{
|
||||
if (left)
|
||||
*left = 1;
|
||||
if (top)
|
||||
*top = 10;
|
||||
if (right)
|
||||
*right = 1;
|
||||
if (bottom)
|
||||
*bottom = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left)
|
||||
*left = 0;
|
||||
if (top)
|
||||
*top = 0;
|
||||
if (right)
|
||||
*right = 0;
|
||||
if (bottom)
|
||||
*bottom = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale)
|
||||
{
|
||||
if (xscale)
|
||||
*xscale = 1.f;
|
||||
if (yscale)
|
||||
*yscale = 1.f;
|
||||
}
|
||||
|
||||
void _glfwIconifyWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.null.focusedWindow == window)
|
||||
{
|
||||
_glfw.null.focusedWindow = NULL;
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
}
|
||||
|
||||
if (!window->null.iconified)
|
||||
{
|
||||
window->null.iconified = GLFW_TRUE;
|
||||
_glfwInputWindowIconify(window, GLFW_TRUE);
|
||||
|
||||
if (window->monitor)
|
||||
releaseMonitorNull(window);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwRestoreWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
if (window->null.iconified)
|
||||
{
|
||||
window->null.iconified = GLFW_FALSE;
|
||||
_glfwInputWindowIconify(window, GLFW_FALSE);
|
||||
|
||||
if (window->monitor)
|
||||
acquireMonitorNull(window);
|
||||
}
|
||||
else if (window->null.maximized)
|
||||
{
|
||||
window->null.maximized = GLFW_FALSE;
|
||||
_glfwInputWindowMaximize(window, GLFW_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwMaximizeWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->null.maximized)
|
||||
{
|
||||
window->null.maximized = GLFW_TRUE;
|
||||
_glfwInputWindowMaximize(window, GLFW_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window)
|
||||
{
|
||||
return window->null.maximized;
|
||||
}
|
||||
|
||||
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window)
|
||||
{
|
||||
return _glfw.null.xcursor >= window->null.xpos &&
|
||||
_glfw.null.ycursor >= window->null.ypos &&
|
||||
_glfw.null.xcursor <= window->null.xpos + window->null.width - 1 &&
|
||||
_glfw.null.ycursor <= window->null.ypos + window->null.height - 1;
|
||||
}
|
||||
|
||||
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window)
|
||||
{
|
||||
return window->null.transparent;
|
||||
}
|
||||
|
||||
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
window->null.resizable = enabled;
|
||||
}
|
||||
|
||||
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
window->null.decorated = enabled;
|
||||
}
|
||||
|
||||
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
window->null.floating = enabled;
|
||||
}
|
||||
|
||||
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
float _glfwGetWindowOpacityNull(_GLFWwindow* window)
|
||||
{
|
||||
return window->null.opacity;
|
||||
}
|
||||
|
||||
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
window->null.opacity = opacity;
|
||||
}
|
||||
|
||||
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
GLFWbool _glfwRawMouseMotionSupportedNull(void)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwShowWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
window->null.visible = GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwRequestWindowAttentionNull(_GLFWwindow* window)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwHideWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.null.focusedWindow == window)
|
||||
{
|
||||
_glfw.null.focusedWindow = NULL;
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
}
|
||||
|
||||
window->null.visible = GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwFocusWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
_GLFWwindow* previous;
|
||||
|
||||
if (_glfw.null.focusedWindow == window)
|
||||
return;
|
||||
|
||||
if (!window->null.visible)
|
||||
return;
|
||||
|
||||
previous = _glfw.null.focusedWindow;
|
||||
_glfw.null.focusedWindow = window;
|
||||
|
||||
if (previous)
|
||||
{
|
||||
_glfwInputWindowFocus(previous, GLFW_FALSE);
|
||||
if (previous->monitor && previous->autoIconify)
|
||||
_glfwIconifyWindowNull(previous);
|
||||
}
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
}
|
||||
|
||||
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window)
|
||||
{
|
||||
return _glfw.null.focusedWindow == window;
|
||||
}
|
||||
|
||||
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window)
|
||||
{
|
||||
return window->null.iconified;
|
||||
}
|
||||
|
||||
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window)
|
||||
{
|
||||
return window->null.visible;
|
||||
}
|
||||
|
||||
void _glfwPollEventsNull(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwWaitEventsNull(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwWaitEventsTimeoutNull(double timeout)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPostEmptyEventNull(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = _glfw.null.xcursor - window->null.xpos;
|
||||
if (ypos)
|
||||
*ypos = _glfw.null.ycursor - window->null.ypos;
|
||||
}
|
||||
|
||||
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
_glfw.null.xcursor = window->null.xpos + (int) x;
|
||||
_glfw.null.ycursor = window->null.ypos + (int) y;
|
||||
}
|
||||
|
||||
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode)
|
||||
{
|
||||
}
|
||||
|
||||
GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor,
|
||||
const GLFWimage* image,
|
||||
int xhot, int yhot)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwDestroyCursorNull(_GLFWcursor* cursor)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwSetClipboardStringNull(const char* string)
|
||||
{
|
||||
char* copy = _glfw_strdup(string);
|
||||
_glfw_free(_glfw.null.clipboardString);
|
||||
_glfw.null.clipboardString = copy;
|
||||
}
|
||||
|
||||
const char* _glfwGetClipboardStringNull(void)
|
||||
{
|
||||
return _glfw.null.clipboardString;
|
||||
}
|
||||
|
||||
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* _glfwGetScancodeNameNull(int scancode)
|
||||
{
|
||||
if (scancode < GLFW_NULL_SC_FIRST || scancode > GLFW_NULL_SC_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (scancode)
|
||||
{
|
||||
case GLFW_NULL_SC_APOSTROPHE:
|
||||
return "'";
|
||||
case GLFW_NULL_SC_COMMA:
|
||||
return ",";
|
||||
case GLFW_NULL_SC_MINUS:
|
||||
case GLFW_NULL_SC_KP_SUBTRACT:
|
||||
return "-";
|
||||
case GLFW_NULL_SC_PERIOD:
|
||||
case GLFW_NULL_SC_KP_DECIMAL:
|
||||
return ".";
|
||||
case GLFW_NULL_SC_SLASH:
|
||||
case GLFW_NULL_SC_KP_DIVIDE:
|
||||
return "/";
|
||||
case GLFW_NULL_SC_SEMICOLON:
|
||||
return ";";
|
||||
case GLFW_NULL_SC_EQUAL:
|
||||
case GLFW_NULL_SC_KP_EQUAL:
|
||||
return "=";
|
||||
case GLFW_NULL_SC_LEFT_BRACKET:
|
||||
return "[";
|
||||
case GLFW_NULL_SC_RIGHT_BRACKET:
|
||||
return "]";
|
||||
case GLFW_NULL_SC_KP_MULTIPLY:
|
||||
return "*";
|
||||
case GLFW_NULL_SC_KP_ADD:
|
||||
return "+";
|
||||
case GLFW_NULL_SC_BACKSLASH:
|
||||
case GLFW_NULL_SC_WORLD_1:
|
||||
case GLFW_NULL_SC_WORLD_2:
|
||||
return "\\";
|
||||
case GLFW_NULL_SC_0:
|
||||
case GLFW_NULL_SC_KP_0:
|
||||
return "0";
|
||||
case GLFW_NULL_SC_1:
|
||||
case GLFW_NULL_SC_KP_1:
|
||||
return "1";
|
||||
case GLFW_NULL_SC_2:
|
||||
case GLFW_NULL_SC_KP_2:
|
||||
return "2";
|
||||
case GLFW_NULL_SC_3:
|
||||
case GLFW_NULL_SC_KP_3:
|
||||
return "3";
|
||||
case GLFW_NULL_SC_4:
|
||||
case GLFW_NULL_SC_KP_4:
|
||||
return "4";
|
||||
case GLFW_NULL_SC_5:
|
||||
case GLFW_NULL_SC_KP_5:
|
||||
return "5";
|
||||
case GLFW_NULL_SC_6:
|
||||
case GLFW_NULL_SC_KP_6:
|
||||
return "6";
|
||||
case GLFW_NULL_SC_7:
|
||||
case GLFW_NULL_SC_KP_7:
|
||||
return "7";
|
||||
case GLFW_NULL_SC_8:
|
||||
case GLFW_NULL_SC_KP_8:
|
||||
return "8";
|
||||
case GLFW_NULL_SC_9:
|
||||
case GLFW_NULL_SC_KP_9:
|
||||
return "9";
|
||||
case GLFW_NULL_SC_A:
|
||||
return "a";
|
||||
case GLFW_NULL_SC_B:
|
||||
return "b";
|
||||
case GLFW_NULL_SC_C:
|
||||
return "c";
|
||||
case GLFW_NULL_SC_D:
|
||||
return "d";
|
||||
case GLFW_NULL_SC_E:
|
||||
return "e";
|
||||
case GLFW_NULL_SC_F:
|
||||
return "f";
|
||||
case GLFW_NULL_SC_G:
|
||||
return "g";
|
||||
case GLFW_NULL_SC_H:
|
||||
return "h";
|
||||
case GLFW_NULL_SC_I:
|
||||
return "i";
|
||||
case GLFW_NULL_SC_J:
|
||||
return "j";
|
||||
case GLFW_NULL_SC_K:
|
||||
return "k";
|
||||
case GLFW_NULL_SC_L:
|
||||
return "l";
|
||||
case GLFW_NULL_SC_M:
|
||||
return "m";
|
||||
case GLFW_NULL_SC_N:
|
||||
return "n";
|
||||
case GLFW_NULL_SC_O:
|
||||
return "o";
|
||||
case GLFW_NULL_SC_P:
|
||||
return "p";
|
||||
case GLFW_NULL_SC_Q:
|
||||
return "q";
|
||||
case GLFW_NULL_SC_R:
|
||||
return "r";
|
||||
case GLFW_NULL_SC_S:
|
||||
return "s";
|
||||
case GLFW_NULL_SC_T:
|
||||
return "t";
|
||||
case GLFW_NULL_SC_U:
|
||||
return "u";
|
||||
case GLFW_NULL_SC_V:
|
||||
return "v";
|
||||
case GLFW_NULL_SC_W:
|
||||
return "w";
|
||||
case GLFW_NULL_SC_X:
|
||||
return "x";
|
||||
case GLFW_NULL_SC_Y:
|
||||
return "y";
|
||||
case GLFW_NULL_SC_Z:
|
||||
return "z";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _glfwGetKeyScancodeNull(int key)
|
||||
{
|
||||
return _glfw.null.scancodes[key];
|
||||
}
|
||||
|
||||
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
|
||||
{
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance,
|
||||
VkPhysicalDevice device,
|
||||
uint32_t queuefamily)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
|
||||
_GLFWwindow* window,
|
||||
const VkAllocationCallbacks* allocator,
|
||||
VkSurfaceKHR* surface)
|
||||
{
|
||||
// This seems like the most appropriate error to return here
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
|
383
raylib/external/glfw/src/osmesa_context.c
vendored
Normal file
383
raylib/external/glfw/src/osmesa_context.c
vendored
Normal file
@ -0,0 +1,383 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 OSMesa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
int width, height;
|
||||
_glfw.platform.getFramebufferSize(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))
|
||||
{
|
||||
_glfw_free(window->context.osmesa.buffer);
|
||||
|
||||
// Allocate the new buffer (width * height * 8-bit RGBA)
|
||||
window->context.osmesa.buffer = _glfw_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)
|
||||
{
|
||||
_glfw_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 = _glfwPlatformLoadModule(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)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt");
|
||||
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
||||
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext");
|
||||
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent");
|
||||
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
||||
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
||||
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
|
||||
_glfwPlatformGetModuleSymbol(_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)
|
||||
{
|
||||
_glfwPlatformFreeModule(_glfw.osmesa.handle);
|
||||
_glfw.osmesa.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_ATTRIB(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];
|
||||
|
||||
SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
|
||||
SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
|
||||
SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
|
||||
SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
|
||||
|
||||
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||
{
|
||||
SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
|
||||
}
|
||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||
{
|
||||
SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
|
||||
}
|
||||
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
{
|
||||
SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
|
||||
SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
|
||||
}
|
||||
|
||||
if (ctxconfig->forward)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: Forward-compatible contexts not supported");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
SET_ATTRIB(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 SET_ATTRIB
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// 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;
|
||||
}
|
||||
|
204
raylib/external/glfw/src/platform.c
vendored
Normal file
204
raylib/external/glfw/src/platform.c
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2024 M374LX <wilsalx@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 "internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// These construct a string literal from individual numeric constants
|
||||
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
||||
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const struct
|
||||
{
|
||||
int ID;
|
||||
GLFWbool (*connect)(int,_GLFWplatform*);
|
||||
} supportedPlatforms[] =
|
||||
{
|
||||
#if defined(_GLFW_WIN32)
|
||||
{ GLFW_PLATFORM_WIN32, _glfwConnectWin32 },
|
||||
#endif
|
||||
#if defined(_GLFW_COCOA)
|
||||
{ GLFW_PLATFORM_COCOA, _glfwConnectCocoa },
|
||||
#endif
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
{ GLFW_PLATFORM_WAYLAND, _glfwConnectWayland },
|
||||
#endif
|
||||
#if defined(_GLFW_X11)
|
||||
{ GLFW_PLATFORM_X11, _glfwConnectX11 },
|
||||
#endif
|
||||
};
|
||||
|
||||
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
|
||||
{
|
||||
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
|
||||
size_t i;
|
||||
|
||||
if (desiredID != GLFW_ANY_PLATFORM &&
|
||||
desiredID != GLFW_PLATFORM_WIN32 &&
|
||||
desiredID != GLFW_PLATFORM_COCOA &&
|
||||
desiredID != GLFW_PLATFORM_WAYLAND &&
|
||||
desiredID != GLFW_PLATFORM_X11 &&
|
||||
desiredID != GLFW_PLATFORM_NULL)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
#if defined(_GLFW_WAYLAND) && defined(_GLFW_X11)
|
||||
if (desiredID == GLFW_ANY_PLATFORM)
|
||||
{
|
||||
const char* const session = getenv("XDG_SESSION_TYPE");
|
||||
if (session)
|
||||
{
|
||||
// Only follow XDG_SESSION_TYPE if it is set correctly and the
|
||||
// environment looks plausble; otherwise fall back to detection
|
||||
if (strcmp(session, "wayland") == 0 && getenv("WAYLAND_DISPLAY"))
|
||||
desiredID = GLFW_PLATFORM_WAYLAND;
|
||||
else if (strcmp(session, "x11") == 0 && getenv("DISPLAY"))
|
||||
desiredID = GLFW_PLATFORM_X11;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (desiredID == GLFW_ANY_PLATFORM)
|
||||
{
|
||||
// If there is exactly one platform available for auto-selection, let it emit the
|
||||
// error on failure as the platform-specific error description may be more helpful
|
||||
if (count == 1)
|
||||
return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (supportedPlatforms[i].connect(desiredID, platform))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (supportedPlatforms[i].ID == desiredID)
|
||||
return supportedPlatforms[i].connect(desiredID, platform);
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported");
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI int glfwGetPlatform(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
return _glfw.platform.platformID;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwPlatformSupported(int platformID)
|
||||
{
|
||||
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
|
||||
size_t i;
|
||||
|
||||
if (platformID != GLFW_PLATFORM_WIN32 &&
|
||||
platformID != GLFW_PLATFORM_COCOA &&
|
||||
platformID != GLFW_PLATFORM_WAYLAND &&
|
||||
platformID != GLFW_PLATFORM_X11 &&
|
||||
platformID != GLFW_PLATFORM_NULL)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", platformID);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (platformID == GLFW_PLATFORM_NULL)
|
||||
return GLFW_TRUE;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (platformID == supportedPlatforms[i].ID)
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetVersionString(void)
|
||||
{
|
||||
return _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR,
|
||||
GLFW_VERSION_MINOR,
|
||||
GLFW_VERSION_REVISION)
|
||||
#if defined(_GLFW_WIN32)
|
||||
" Win32 WGL"
|
||||
#endif
|
||||
#if defined(_GLFW_COCOA)
|
||||
" Cocoa NSGL"
|
||||
#endif
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
" Wayland"
|
||||
#endif
|
||||
#if defined(_GLFW_X11)
|
||||
" X11 GLX"
|
||||
#endif
|
||||
" Null"
|
||||
" EGL"
|
||||
" OSMesa"
|
||||
#if defined(__MINGW64_VERSION_MAJOR)
|
||||
" MinGW-w64"
|
||||
#elif defined(__MINGW32__)
|
||||
" MinGW"
|
||||
#elif defined(_MSC_VER)
|
||||
" VisualC"
|
||||
#endif
|
||||
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
||||
" hybrid-GPU"
|
||||
#endif
|
||||
#if defined(_POSIX_MONOTONIC_CLOCK)
|
||||
" monotonic"
|
||||
#endif
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
#if defined(_WIN32)
|
||||
" DLL"
|
||||
#elif defined(__APPLE__)
|
||||
" dynamic"
|
||||
#else
|
||||
" shared"
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
212
raylib/external/glfw/src/platform.h
vendored
Normal file
212
raylib/external/glfw/src/platform.h
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_TIMER) || \
|
||||
defined(GLFW_BUILD_WIN32_MODULE) || \
|
||||
defined(GLFW_BUILD_WIN32_THREAD) || \
|
||||
defined(GLFW_BUILD_COCOA_TIMER) || \
|
||||
defined(GLFW_BUILD_POSIX_TIMER) || \
|
||||
defined(GLFW_BUILD_POSIX_MODULE) || \
|
||||
defined(GLFW_BUILD_POSIX_THREAD) || \
|
||||
defined(GLFW_BUILD_POSIX_POLL) || \
|
||||
defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||
#error "You must not define these; define zero or more _GLFW_<platform> macros instead"
|
||||
#endif
|
||||
|
||||
#include "null_platform.h"
|
||||
#define GLFW_EXPOSE_NATIVE_EGL
|
||||
#define GLFW_EXPOSE_NATIVE_OSMESA
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
#include "win32_platform.h"
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#define GLFW_EXPOSE_NATIVE_WGL
|
||||
#else
|
||||
#define GLFW_WIN32_WINDOW_STATE
|
||||
#define GLFW_WIN32_MONITOR_STATE
|
||||
#define GLFW_WIN32_CURSOR_STATE
|
||||
#define GLFW_WIN32_LIBRARY_WINDOW_STATE
|
||||
#define GLFW_WGL_CONTEXT_STATE
|
||||
#define GLFW_WGL_LIBRARY_CONTEXT_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
#include "cocoa_platform.h"
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#define GLFW_EXPOSE_NATIVE_NSGL
|
||||
#else
|
||||
#define GLFW_COCOA_WINDOW_STATE
|
||||
#define GLFW_COCOA_MONITOR_STATE
|
||||
#define GLFW_COCOA_CURSOR_STATE
|
||||
#define GLFW_COCOA_LIBRARY_WINDOW_STATE
|
||||
#define GLFW_NSGL_CONTEXT_STATE
|
||||
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_WAYLAND)
|
||||
#include "wl_platform.h"
|
||||
#define GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
#else
|
||||
#define GLFW_WAYLAND_WINDOW_STATE
|
||||
#define GLFW_WAYLAND_MONITOR_STATE
|
||||
#define GLFW_WAYLAND_CURSOR_STATE
|
||||
#define GLFW_WAYLAND_LIBRARY_WINDOW_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_X11)
|
||||
#include "x11_platform.h"
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#define GLFW_EXPOSE_NATIVE_GLX
|
||||
#else
|
||||
#define GLFW_X11_WINDOW_STATE
|
||||
#define GLFW_X11_MONITOR_STATE
|
||||
#define GLFW_X11_CURSOR_STATE
|
||||
#define GLFW_X11_LIBRARY_WINDOW_STATE
|
||||
#define GLFW_GLX_CONTEXT_STATE
|
||||
#define GLFW_GLX_LIBRARY_CONTEXT_STATE
|
||||
#endif
|
||||
|
||||
#include "null_joystick.h"
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
#include "win32_joystick.h"
|
||||
#else
|
||||
#define GLFW_WIN32_JOYSTICK_STATE
|
||||
#define GLFW_WIN32_LIBRARY_JOYSTICK_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
#include "cocoa_joystick.h"
|
||||
#else
|
||||
#define GLFW_COCOA_JOYSTICK_STATE
|
||||
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
|
||||
#endif
|
||||
|
||||
#if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__)
|
||||
#define GLFW_BUILD_LINUX_JOYSTICK
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||
#include "linux_joystick.h"
|
||||
#else
|
||||
#define GLFW_LINUX_JOYSTICK_STATE
|
||||
#define GLFW_LINUX_LIBRARY_JOYSTICK_STATE
|
||||
#endif
|
||||
|
||||
#define GLFW_PLATFORM_WINDOW_STATE \
|
||||
GLFW_WIN32_WINDOW_STATE \
|
||||
GLFW_COCOA_WINDOW_STATE \
|
||||
GLFW_WAYLAND_WINDOW_STATE \
|
||||
GLFW_X11_WINDOW_STATE \
|
||||
GLFW_NULL_WINDOW_STATE \
|
||||
|
||||
#define GLFW_PLATFORM_MONITOR_STATE \
|
||||
GLFW_WIN32_MONITOR_STATE \
|
||||
GLFW_COCOA_MONITOR_STATE \
|
||||
GLFW_WAYLAND_MONITOR_STATE \
|
||||
GLFW_X11_MONITOR_STATE \
|
||||
GLFW_NULL_MONITOR_STATE \
|
||||
|
||||
#define GLFW_PLATFORM_CURSOR_STATE \
|
||||
GLFW_WIN32_CURSOR_STATE \
|
||||
GLFW_COCOA_CURSOR_STATE \
|
||||
GLFW_WAYLAND_CURSOR_STATE \
|
||||
GLFW_X11_CURSOR_STATE \
|
||||
GLFW_NULL_CURSOR_STATE \
|
||||
|
||||
#define GLFW_PLATFORM_JOYSTICK_STATE \
|
||||
GLFW_WIN32_JOYSTICK_STATE \
|
||||
GLFW_COCOA_JOYSTICK_STATE \
|
||||
GLFW_LINUX_JOYSTICK_STATE
|
||||
|
||||
#define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \
|
||||
GLFW_WIN32_LIBRARY_WINDOW_STATE \
|
||||
GLFW_COCOA_LIBRARY_WINDOW_STATE \
|
||||
GLFW_WAYLAND_LIBRARY_WINDOW_STATE \
|
||||
GLFW_X11_LIBRARY_WINDOW_STATE \
|
||||
GLFW_NULL_LIBRARY_WINDOW_STATE \
|
||||
|
||||
#define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
|
||||
GLFW_WIN32_LIBRARY_JOYSTICK_STATE \
|
||||
GLFW_COCOA_LIBRARY_JOYSTICK_STATE \
|
||||
GLFW_LINUX_LIBRARY_JOYSTICK_STATE
|
||||
|
||||
#define GLFW_PLATFORM_CONTEXT_STATE \
|
||||
GLFW_WGL_CONTEXT_STATE \
|
||||
GLFW_NSGL_CONTEXT_STATE \
|
||||
GLFW_GLX_CONTEXT_STATE
|
||||
|
||||
#define GLFW_PLATFORM_LIBRARY_CONTEXT_STATE \
|
||||
GLFW_WGL_LIBRARY_CONTEXT_STATE \
|
||||
GLFW_NSGL_LIBRARY_CONTEXT_STATE \
|
||||
GLFW_GLX_LIBRARY_CONTEXT_STATE
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define GLFW_BUILD_WIN32_THREAD
|
||||
#else
|
||||
#define GLFW_BUILD_POSIX_THREAD
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_THREAD)
|
||||
#include "win32_thread.h"
|
||||
#define GLFW_PLATFORM_TLS_STATE GLFW_WIN32_TLS_STATE
|
||||
#define GLFW_PLATFORM_MUTEX_STATE GLFW_WIN32_MUTEX_STATE
|
||||
#elif defined(GLFW_BUILD_POSIX_THREAD)
|
||||
#include "posix_thread.h"
|
||||
#define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE
|
||||
#define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define GLFW_BUILD_WIN32_TIMER
|
||||
#elif defined(__APPLE__)
|
||||
#define GLFW_BUILD_COCOA_TIMER
|
||||
#else
|
||||
#define GLFW_BUILD_POSIX_TIMER
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_TIMER)
|
||||
#include "win32_time.h"
|
||||
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE
|
||||
#elif defined(GLFW_BUILD_COCOA_TIMER)
|
||||
#include "cocoa_time.h"
|
||||
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE
|
||||
#elif defined(GLFW_BUILD_POSIX_TIMER)
|
||||
#include "posix_time.h"
|
||||
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define GLFW_BUILD_WIN32_MODULE
|
||||
#else
|
||||
#define GLFW_BUILD_POSIX_MODULE
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_WAYLAND) || defined(_GLFW_X11)
|
||||
#define GLFW_BUILD_POSIX_POLL
|
||||
#endif
|
||||
|
53
raylib/external/glfw/src/posix_module.c
vendored
Normal file
53
raylib/external/glfw/src/posix_module.c
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_POSIX_MODULE)
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* _glfwPlatformLoadModule(const char* path)
|
||||
{
|
||||
return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
|
||||
}
|
||||
|
||||
void _glfwPlatformFreeModule(void* module)
|
||||
{
|
||||
dlclose(module);
|
||||
}
|
||||
|
||||
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
|
||||
{
|
||||
return dlsym(module, name);
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_POSIX_MODULE
|
||||
|
83
raylib/external/glfw/src/posix_poll.c
vendored
Normal file
83
raylib/external/glfw/src/posix_poll.c
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2022 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 _GNU_SOURCE
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_POSIX_POLL)
|
||||
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (timeout)
|
||||
{
|
||||
const uint64_t base = _glfwPlatformGetTimerValue();
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
const time_t seconds = (time_t) *timeout;
|
||||
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||
const struct timespec ts = { seconds, nanoseconds };
|
||||
const int result = ppoll(fds, count, &ts, NULL);
|
||||
#elif defined(__NetBSD__)
|
||||
const time_t seconds = (time_t) *timeout;
|
||||
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||
const struct timespec ts = { seconds, nanoseconds };
|
||||
const int result = pollts(fds, count, &ts, NULL);
|
||||
#else
|
||||
const int milliseconds = (int) (*timeout * 1e3);
|
||||
const int result = poll(fds, count, milliseconds);
|
||||
#endif
|
||||
const int error = errno; // clock_gettime may overwrite our error
|
||||
|
||||
*timeout -= (_glfwPlatformGetTimerValue() - base) /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
else if (result == -1 && error != EINTR && error != EAGAIN)
|
||||
return GLFW_FALSE;
|
||||
else if (*timeout <= 0.0)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int result = poll(fds, count, -1);
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
else if (result == -1 && errno != EINTR && errno != EAGAIN)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_POSIX_POLL
|
||||
|
30
raylib/external/glfw/src/posix_poll.h
vendored
Normal file
30
raylib/external/glfw/src/posix_poll.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2022 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 <poll.h>
|
||||
|
||||
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout);
|
||||
|
107
raylib/external/glfw/src/posix_thread.c
vendored
Normal file
107
raylib/external/glfw/src/posix_thread.c
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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 "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_POSIX_THREAD)
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_POSIX_THREAD
|
||||
|
49
raylib/external/glfw/src/posix_thread.h
vendored
Normal file
49
raylib/external/glfw/src/posix_thread.h
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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_POSIX_TLS_STATE _GLFWtlsPOSIX posix;
|
||||
#define GLFW_POSIX_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;
|
||||
|
65
raylib/external/glfw/src/posix_time.c
vendored
Normal file
65
raylib/external/glfw/src/posix_time.c
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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 "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_POSIX_TIMER)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformInitTimer(void)
|
||||
{
|
||||
_glfw.timer.posix.clock = CLOCK_REALTIME;
|
||||
_glfw.timer.posix.frequency = 1000000000;
|
||||
|
||||
#if defined(_POSIX_MONOTONIC_CLOCK)
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
_glfw.timer.posix.clock = CLOCK_MONOTONIC;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(_glfw.timer.posix.clock, &ts);
|
||||
return (uint64_t) ts.tv_sec * _glfw.timer.posix.frequency + (uint64_t) ts.tv_nsec;
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
return _glfw.timer.posix.frequency;
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_POSIX_TIMER
|
||||
|
41
raylib/external/glfw/src/posix_time.h
vendored
Normal file
41
raylib/external/glfw/src/posix_time.h
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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_POSIX_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix;
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
// POSIX-specific global timer data
|
||||
//
|
||||
typedef struct _GLFWtimerPOSIX
|
||||
{
|
||||
clockid_t clock;
|
||||
uint64_t frequency;
|
||||
} _GLFWtimerPOSIX;
|
||||
|
328
raylib/external/glfw/src/vulkan.c
vendored
Normal file
328
raylib/external/glfw/src/vulkan.c
vendored
Normal file
@ -0,0 +1,328 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#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;
|
||||
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
||||
uint32_t i, count;
|
||||
|
||||
if (_glfw.vk.available)
|
||||
return GLFW_TRUE;
|
||||
|
||||
if (_glfw.hints.init.vulkanLoader)
|
||||
_glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader;
|
||||
else
|
||||
{
|
||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
|
||||
#elif defined(_GLFW_WIN32)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
|
||||
#elif defined(_GLFW_COCOA)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
|
||||
if (!_glfw.vk.handle)
|
||||
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
|
||||
#else
|
||||
_glfw.vk.handle = _glfwPlatformLoadModule("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)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||
if (!_glfw.vk.GetInstanceProcAddr)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
|
||||
if (!vkEnumerateInstanceExtensionProperties)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
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 = _glfw_calloc(count, sizeof(VkExtensionProperties));
|
||||
|
||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
||||
if (err)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Failed to query instance extensions: %s",
|
||||
_glfwGetVulkanResultString(err));
|
||||
|
||||
_glfw_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;
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
|
||||
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
|
||||
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;
|
||||
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;
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
||||
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
||||
}
|
||||
|
||||
_glfw_free(ep);
|
||||
|
||||
_glfw.vk.available = GLFW_TRUE;
|
||||
|
||||
_glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwTerminateVulkan(void)
|
||||
{
|
||||
if (_glfw.vk.handle)
|
||||
_glfwPlatformFreeModule(_glfw.vk.handle);
|
||||
}
|
||||
|
||||
const char* _glfwGetVulkanResultString(VkResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
return "Success";
|
||||
case VK_NOT_READY:
|
||||
return "A fence or query has not yet completed";
|
||||
case VK_TIMEOUT:
|
||||
return "A wait operation has not completed in the specified time";
|
||||
case VK_EVENT_SET:
|
||||
return "An event is signaled";
|
||||
case VK_EVENT_RESET:
|
||||
return "An event is unsignaled";
|
||||
case VK_INCOMPLETE:
|
||||
return "A return array was too small for the result";
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "A host memory allocation has failed";
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "A device memory allocation has failed";
|
||||
case VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "Initialization of an object could not be completed for implementation-specific reasons";
|
||||
case VK_ERROR_DEVICE_LOST:
|
||||
return "The logical or physical device has been lost";
|
||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "Mapping of a memory object has failed";
|
||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "A requested layer is not present or could not be loaded";
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "A requested extension is not supported";
|
||||
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "A requested feature is not supported";
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
|
||||
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "Too many objects of the type have already been created";
|
||||
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "A requested format is not supported on this device";
|
||||
case VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "A surface is no longer available";
|
||||
case VK_SUBOPTIMAL_KHR:
|
||||
return "A swapchain no longer matches the surface properties exactly, but can still be used";
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
|
||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "The display used by a swapchain does not use the same presentable image layout";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
|
||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "A validation layer found an error";
|
||||
default:
|
||||
return "ERROR: UNKNOWN VULKAN ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI int glfwVulkanSupported(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
return _glfwInitVulkan(_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;
|
||||
|
||||
// NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself
|
||||
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
|
||||
return (GLFWvkproc) vkGetInstanceProcAddr;
|
||||
|
||||
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
|
||||
if (!proc)
|
||||
{
|
||||
if (_glfw.vk.handle)
|
||||
proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
|
||||
}
|
||||
|
||||
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 _glfw.platform.getPhysicalDevicePresentationSupport(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 _glfw.platform.createWindowSurface(instance, window, allocator, surface);
|
||||
}
|
||||
|
798
raylib/external/glfw/src/wgl_context.c
vendored
Normal file
798
raylib/external/glfw/src/wgl_context.c
vendored
Normal file
@ -0,0 +1,798 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Return the value corresponding to the specified attribute
|
||||
//
|
||||
static int findPixelFormatAttribValueWGL(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 ADD_ATTRIB(a) \
|
||||
{ \
|
||||
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[attribCount++] = a; \
|
||||
}
|
||||
#define FIND_ATTRIB_VALUE(a) \
|
||||
findPixelFormatAttribValueWGL(attribs, attribCount, values, a)
|
||||
|
||||
// Return a list of available and usable framebuffer configs
|
||||
//
|
||||
static int choosePixelFormatWGL(_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])];
|
||||
|
||||
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
ADD_ATTRIB(WGL_SUPPORT_OPENGL_ARB);
|
||||
ADD_ATTRIB(WGL_DRAW_TO_WINDOW_ARB);
|
||||
ADD_ATTRIB(WGL_PIXEL_TYPE_ARB);
|
||||
ADD_ATTRIB(WGL_ACCELERATION_ARB);
|
||||
ADD_ATTRIB(WGL_RED_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_RED_SHIFT_ARB);
|
||||
ADD_ATTRIB(WGL_GREEN_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_GREEN_SHIFT_ARB);
|
||||
ADD_ATTRIB(WGL_BLUE_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_BLUE_SHIFT_ARB);
|
||||
ADD_ATTRIB(WGL_ALPHA_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_ALPHA_SHIFT_ARB);
|
||||
ADD_ATTRIB(WGL_DEPTH_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_STENCIL_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_ACCUM_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_ACCUM_RED_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_ACCUM_GREEN_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_ACCUM_BLUE_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB);
|
||||
ADD_ATTRIB(WGL_AUX_BUFFERS_ARB);
|
||||
ADD_ATTRIB(WGL_STEREO_ARB);
|
||||
ADD_ATTRIB(WGL_DOUBLE_BUFFER_ARB);
|
||||
|
||||
if (_glfw.wgl.ARB_multisample)
|
||||
ADD_ATTRIB(WGL_SAMPLES_ARB);
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
|
||||
ADD_ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_glfw.wgl.EXT_colorspace)
|
||||
ADD_ATTRIB(WGL_COLORSPACE_EXT);
|
||||
}
|
||||
|
||||
// NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than
|
||||
// DescribePixelFormat, violating the guarantees of the extension spec
|
||||
// HACK: Iterate through the minimum of both counts
|
||||
|
||||
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
|
||||
int extensionCount;
|
||||
|
||||
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||
1, 0, 1, &attrib, &extensionCount))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve pixel format attribute");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nativeCount = _glfw_min(nativeCount, extensionCount);
|
||||
}
|
||||
|
||||
usableConfigs = _glfw_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");
|
||||
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) ||
|
||||
!FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
|
||||
continue;
|
||||
|
||||
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
|
||||
continue;
|
||||
|
||||
if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
|
||||
continue;
|
||||
|
||||
u->redBits = FIND_ATTRIB_VALUE(WGL_RED_BITS_ARB);
|
||||
u->greenBits = FIND_ATTRIB_VALUE(WGL_GREEN_BITS_ARB);
|
||||
u->blueBits = FIND_ATTRIB_VALUE(WGL_BLUE_BITS_ARB);
|
||||
u->alphaBits = FIND_ATTRIB_VALUE(WGL_ALPHA_BITS_ARB);
|
||||
|
||||
u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB);
|
||||
u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB);
|
||||
|
||||
u->accumRedBits = FIND_ATTRIB_VALUE(WGL_ACCUM_RED_BITS_ARB);
|
||||
u->accumGreenBits = FIND_ATTRIB_VALUE(WGL_ACCUM_GREEN_BITS_ARB);
|
||||
u->accumBlueBits = FIND_ATTRIB_VALUE(WGL_ACCUM_BLUE_BITS_ARB);
|
||||
u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
|
||||
|
||||
u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
|
||||
|
||||
if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
|
||||
u->stereo = GLFW_TRUE;
|
||||
|
||||
if (_glfw.wgl.ARB_multisample)
|
||||
u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB);
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
||||
_glfw.wgl.EXT_framebuffer_sRGB)
|
||||
{
|
||||
if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
||||
u->sRGB = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_glfw.wgl.EXT_colorspace)
|
||||
{
|
||||
if (FIND_ATTRIB_VALUE(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");
|
||||
|
||||
_glfw_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");
|
||||
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
||||
if (!closest)
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"WGL: Failed to find a suitable pixel format");
|
||||
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixelFormat = (int) closest->handle;
|
||||
_glfw_free(usableConfigs);
|
||||
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
#undef ADD_ATTRIB
|
||||
#undef FIND_ATTRIB_VALUE
|
||||
|
||||
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)
|
||||
{
|
||||
// HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
|
||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
||||
{
|
||||
BOOL enabled = FALSE;
|
||||
|
||||
if (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);
|
||||
assert(window != NULL);
|
||||
|
||||
window->context.wgl.interval = interval;
|
||||
|
||||
if (!window->monitor)
|
||||
{
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled on Windows
|
||||
// Vista and 7 to avoid interfering with DWM vsync
|
||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
||||
{
|
||||
BOOL enabled = FALSE;
|
||||
|
||||
if (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) _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, procname);
|
||||
}
|
||||
|
||||
static void destroyContextWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.wgl.handle)
|
||||
{
|
||||
wglDeleteContext(window->context.wgl.handle);
|
||||
window->context.wgl.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize WGL
|
||||
//
|
||||
GLFWbool _glfwInitWGL(void)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC prc, rc;
|
||||
HDC pdc, dc;
|
||||
|
||||
if (_glfw.wgl.instance)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfw.wgl.instance = _glfwPlatformLoadModule("opengl32.dll");
|
||||
if (!_glfw.wgl.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to load opengl32.dll");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglCreateContext");
|
||||
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglDeleteContext");
|
||||
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetProcAddress");
|
||||
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentDC");
|
||||
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentContext");
|
||||
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglMakeCurrent");
|
||||
_glfw.wgl.ShareLists = (PFN_wglShareLists)
|
||||
_glfwPlatformGetModuleSymbol(_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)
|
||||
_glfwPlatformFreeModule(_glfw.wgl.instance);
|
||||
}
|
||||
|
||||
#define SET_ATTRIB(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 = choosePixelFormatWGL(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)
|
||||
{
|
||||
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
WGL_NO_RESET_NOTIFICATION_ARB);
|
||||
}
|
||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||
{
|
||||
SET_ATTRIB(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)
|
||||
{
|
||||
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||
}
|
||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||
{
|
||||
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context_no_error)
|
||||
SET_ATTRIB(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)
|
||||
{
|
||||
SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||
SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||
}
|
||||
|
||||
if (flags)
|
||||
SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags);
|
||||
|
||||
if (mask)
|
||||
SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||
|
||||
SET_ATTRIB(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 SET_ATTRIB
|
||||
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
|
||||
"WGL: Platform not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return window->context.wgl.handle;
|
||||
}
|
||||
|
||||
#endif // _GLFW_WIN32
|
||||
|
732
raylib/external/glfw/src/win32_init.c
vendored
Normal file
732
raylib/external/glfw/src/win32_init.c
vendored
Normal file
@ -0,0 +1,732 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 Win32 (modified for raylib) - www.glfw.org; www.raylib.com
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2024 M374LX <wilsalx@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 "internal.h"
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
|
||||
#include <stdlib.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 = _glfwPlatformLoadModule("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)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
|
||||
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
|
||||
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow");
|
||||
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
||||
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
|
||||
|
||||
_glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll");
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
{
|
||||
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
|
||||
_glfwPlatformGetModuleSymbol(_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 = _glfwPlatformLoadModule(names[i]);
|
||||
if (_glfw.win32.xinput.instance)
|
||||
{
|
||||
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetCapabilities");
|
||||
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetState");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_glfw.win32.dwmapi.instance = _glfwPlatformLoadModule("dwmapi.dll");
|
||||
if (_glfw.win32.dwmapi.instance)
|
||||
{
|
||||
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||
}
|
||||
|
||||
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
|
||||
if (_glfw.win32.shcore.instance)
|
||||
{
|
||||
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
||||
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
||||
}
|
||||
|
||||
_glfw.win32.ntdll.instance = _glfwPlatformLoadModule("ntdll.dll");
|
||||
if (_glfw.win32.ntdll.instance)
|
||||
{
|
||||
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Unload used libraries (DLLs)
|
||||
//
|
||||
static void freeLibraries(void)
|
||||
{
|
||||
if (_glfw.win32.xinput.instance)
|
||||
_glfwPlatformFreeModule(_glfw.win32.xinput.instance);
|
||||
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
_glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
|
||||
|
||||
if (_glfw.win32.user32.instance)
|
||||
_glfwPlatformFreeModule(_glfw.win32.user32.instance);
|
||||
|
||||
if (_glfw.win32.dwmapi.instance)
|
||||
_glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
|
||||
|
||||
if (_glfw.win32.shcore.instance)
|
||||
_glfwPlatformFreeModule(_glfw.win32.shcore.instance);
|
||||
|
||||
if (_glfw.win32.ntdll.instance)
|
||||
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
|
||||
}
|
||||
|
||||
// Create key code translation tables
|
||||
//
|
||||
static void createKeyTablesWin32(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;
|
||||
}
|
||||
}
|
||||
|
||||
// Window procedure for the hidden helper window
|
||||
//
|
||||
static LRESULT CALLBACK helperWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_DISPLAYCHANGE:
|
||||
_glfwPollMonitorsWin32();
|
||||
break;
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
{
|
||||
if (!_glfw.joysticksInitialized)
|
||||
break;
|
||||
|
||||
if (wParam == DBT_DEVICEARRIVAL)
|
||||
{
|
||||
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
||||
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
||||
_glfwDetectJoystickConnectionWin32();
|
||||
}
|
||||
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
|
||||
{
|
||||
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
||||
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
||||
_glfwDetectJoystickDisconnectionWin32();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
// Creates a dummy window for behind-the-scenes work
|
||||
//
|
||||
static GLFWbool createHelperWindow(void)
|
||||
{
|
||||
MSG msg;
|
||||
WNDCLASSEXW wc = { sizeof(wc) };
|
||||
|
||||
wc.style = CS_OWNDC;
|
||||
wc.lpfnWndProc = (WNDPROC) helperWindowProc;
|
||||
wc.hInstance = _glfw.win32.instance;
|
||||
wc.lpszClassName = L"GLFW3 Helper";
|
||||
|
||||
_glfw.win32.helperWindowClass = RegisterClassExW(&wc);
|
||||
if (!_glfw.win32.helperWindowClass)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to register helper window class");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.win32.helperWindowHandle =
|
||||
CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
|
||||
MAKEINTATOM(_glfw.win32.helperWindowClass),
|
||||
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 = _glfw_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");
|
||||
_glfw_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 = _glfw_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");
|
||||
_glfw_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;
|
||||
}
|
||||
|
||||
GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
||||
{
|
||||
const _GLFWplatform win32 =
|
||||
{
|
||||
.platformID = GLFW_PLATFORM_WIN32,
|
||||
.init = _glfwInitWin32,
|
||||
.terminate = _glfwTerminateWin32,
|
||||
.getCursorPos = _glfwGetCursorPosWin32,
|
||||
.setCursorPos = _glfwSetCursorPosWin32,
|
||||
.setCursorMode = _glfwSetCursorModeWin32,
|
||||
.setRawMouseMotion = _glfwSetRawMouseMotionWin32,
|
||||
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedWin32,
|
||||
.createCursor = _glfwCreateCursorWin32,
|
||||
.createStandardCursor = _glfwCreateStandardCursorWin32,
|
||||
.destroyCursor = _glfwDestroyCursorWin32,
|
||||
.setCursor = _glfwSetCursorWin32,
|
||||
.getScancodeName = _glfwGetScancodeNameWin32,
|
||||
.getKeyScancode = _glfwGetKeyScancodeWin32,
|
||||
.setClipboardString = _glfwSetClipboardStringWin32,
|
||||
.getClipboardString = _glfwGetClipboardStringWin32,
|
||||
.initJoysticks = _glfwInitJoysticksWin32,
|
||||
.terminateJoysticks = _glfwTerminateJoysticksWin32,
|
||||
.pollJoystick = _glfwPollJoystickWin32,
|
||||
.getMappingName = _glfwGetMappingNameWin32,
|
||||
.updateGamepadGUID = _glfwUpdateGamepadGUIDWin32,
|
||||
.freeMonitor = _glfwFreeMonitorWin32,
|
||||
.getMonitorPos = _glfwGetMonitorPosWin32,
|
||||
.getMonitorContentScale = _glfwGetMonitorContentScaleWin32,
|
||||
.getMonitorWorkarea = _glfwGetMonitorWorkareaWin32,
|
||||
.getVideoModes = _glfwGetVideoModesWin32,
|
||||
.getVideoMode = _glfwGetVideoModeWin32,
|
||||
.getGammaRamp = _glfwGetGammaRampWin32,
|
||||
.setGammaRamp = _glfwSetGammaRampWin32,
|
||||
.createWindow = _glfwCreateWindowWin32,
|
||||
.destroyWindow = _glfwDestroyWindowWin32,
|
||||
.setWindowTitle = _glfwSetWindowTitleWin32,
|
||||
.setWindowIcon = _glfwSetWindowIconWin32,
|
||||
.getWindowPos = _glfwGetWindowPosWin32,
|
||||
.setWindowPos = _glfwSetWindowPosWin32,
|
||||
.getWindowSize = _glfwGetWindowSizeWin32,
|
||||
.setWindowSize = _glfwSetWindowSizeWin32,
|
||||
.setWindowSizeLimits = _glfwSetWindowSizeLimitsWin32,
|
||||
.setWindowAspectRatio = _glfwSetWindowAspectRatioWin32,
|
||||
.getFramebufferSize = _glfwGetFramebufferSizeWin32,
|
||||
.getWindowFrameSize = _glfwGetWindowFrameSizeWin32,
|
||||
.getWindowContentScale = _glfwGetWindowContentScaleWin32,
|
||||
.iconifyWindow = _glfwIconifyWindowWin32,
|
||||
.restoreWindow = _glfwRestoreWindowWin32,
|
||||
.maximizeWindow = _glfwMaximizeWindowWin32,
|
||||
.showWindow = _glfwShowWindowWin32,
|
||||
.hideWindow = _glfwHideWindowWin32,
|
||||
.requestWindowAttention = _glfwRequestWindowAttentionWin32,
|
||||
.focusWindow = _glfwFocusWindowWin32,
|
||||
.setWindowMonitor = _glfwSetWindowMonitorWin32,
|
||||
.windowFocused = _glfwWindowFocusedWin32,
|
||||
.windowIconified = _glfwWindowIconifiedWin32,
|
||||
.windowVisible = _glfwWindowVisibleWin32,
|
||||
.windowMaximized = _glfwWindowMaximizedWin32,
|
||||
.windowHovered = _glfwWindowHoveredWin32,
|
||||
.framebufferTransparent = _glfwFramebufferTransparentWin32,
|
||||
.getWindowOpacity = _glfwGetWindowOpacityWin32,
|
||||
.setWindowResizable = _glfwSetWindowResizableWin32,
|
||||
.setWindowDecorated = _glfwSetWindowDecoratedWin32,
|
||||
.setWindowFloating = _glfwSetWindowFloatingWin32,
|
||||
.setWindowOpacity = _glfwSetWindowOpacityWin32,
|
||||
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughWin32,
|
||||
.pollEvents = _glfwPollEventsWin32,
|
||||
.waitEvents = _glfwWaitEventsWin32,
|
||||
.waitEventsTimeout = _glfwWaitEventsTimeoutWin32,
|
||||
.postEmptyEvent = _glfwPostEmptyEventWin32,
|
||||
.getEGLPlatform = _glfwGetEGLPlatformWin32,
|
||||
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayWin32,
|
||||
.getEGLNativeWindow = _glfwGetEGLNativeWindowWin32,
|
||||
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWin32,
|
||||
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWin32,
|
||||
.createWindowSurface = _glfwCreateWindowSurfaceWin32
|
||||
};
|
||||
|
||||
*platform = win32;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
int _glfwInitWin32(void)
|
||||
{
|
||||
if (!loadLibraries())
|
||||
return GLFW_FALSE;
|
||||
|
||||
createKeyTablesWin32();
|
||||
_glfwUpdateKeyNamesWin32();
|
||||
|
||||
if (_glfwIsWindows10Version1703OrGreaterWin32())
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
else if (IsWindows8Point1OrGreater())
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
else if (IsWindowsVistaOrGreater())
|
||||
SetProcessDPIAware();
|
||||
|
||||
if (!createHelperWindow())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwPollMonitorsWin32();
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwTerminateWin32(void)
|
||||
{
|
||||
if (_glfw.win32.blankCursor)
|
||||
DestroyIcon((HICON) _glfw.win32.blankCursor);
|
||||
|
||||
if (_glfw.win32.deviceNotificationHandle)
|
||||
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
|
||||
|
||||
if (_glfw.win32.helperWindowHandle)
|
||||
DestroyWindow(_glfw.win32.helperWindowHandle);
|
||||
if (_glfw.win32.helperWindowClass)
|
||||
UnregisterClassW(MAKEINTATOM(_glfw.win32.helperWindowClass), _glfw.win32.instance);
|
||||
if (_glfw.win32.mainWindowClass)
|
||||
UnregisterClassW(MAKEINTATOM(_glfw.win32.mainWindowClass), _glfw.win32.instance);
|
||||
|
||||
_glfw_free(_glfw.win32.clipboardString);
|
||||
_glfw_free(_glfw.win32.rawInput);
|
||||
|
||||
_glfwTerminateWGL();
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateOSMesa();
|
||||
|
||||
freeLibraries();
|
||||
}
|
||||
|
||||
#endif // _GLFW_WIN32
|
||||
|
767
raylib/external/glfw/src/win32_joystick.c
vendored
Normal file
767
raylib/external/glfw/src/win32_joystick.c
vendored
Normal file
@ -0,0 +1,767 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
|
||||
#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 = _glfw_calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
||||
{
|
||||
_glfw_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;
|
||||
}
|
||||
}
|
||||
|
||||
_glfw_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);
|
||||
}
|
||||
|
||||
_glfw_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 = _glfw_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);
|
||||
_glfw_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);
|
||||
_glfw_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);
|
||||
_glfw_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 //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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)
|
||||
_glfwPollJoystickWin32(js, _GLFW_POLL_PRESENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _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");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwDetectJoystickConnectionWin32();
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPollJoystickWin32(_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;
|
||||
|
||||
// Treat invalid combinations as neither being pressed
|
||||
// while preserving what data can be preserved
|
||||
if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT))
|
||||
dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT);
|
||||
if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN))
|
||||
dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN);
|
||||
|
||||
_glfwInputJoystickHat(js, 0, dpad);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
const char* _glfwGetMappingNameWin32(void)
|
||||
{
|
||||
return "Windows";
|
||||
}
|
||||
|
||||
void _glfwUpdateGamepadGUIDWin32(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);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _GLFW_WIN32
|
||||
|
51
raylib/external/glfw/src/win32_joystick.h
vendored
Normal file
51
raylib/external/glfw/src/win32_joystick.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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_WIN32_JOYSTICK_STATE _GLFWjoystickWin32 win32;
|
||||
#define GLFW_WIN32_LIBRARY_JOYSTICK_STATE
|
||||
|
||||
// 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 _glfwDetectJoystickConnectionWin32(void);
|
||||
void _glfwDetectJoystickDisconnectionWin32(void);
|
||||
|
51
raylib/external/glfw/src/win32_module.c
vendored
Normal file
51
raylib/external/glfw/src/win32_module.c
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_MODULE)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* _glfwPlatformLoadModule(const char* path)
|
||||
{
|
||||
return LoadLibraryA(path);
|
||||
}
|
||||
|
||||
void _glfwPlatformFreeModule(void* module)
|
||||
{
|
||||
FreeLibrary((HMODULE) module);
|
||||
}
|
||||
|
||||
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
|
||||
{
|
||||
return (GLFWproc) GetProcAddress((HMODULE) module, name);
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_WIN32_MODULE
|
||||
|
569
raylib/external/glfw/src/win32_monitor.c
vendored
Normal file
569
raylib/external/glfw/src/win32_monitor.c
vendored
Normal file
@ -0,0 +1,569 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.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);
|
||||
_glfw_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 = _glfw_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)
|
||||
{
|
||||
_glfw_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)
|
||||
{
|
||||
_glfw_free(disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
}
|
||||
|
||||
_glfw_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);
|
||||
_glfwGetVideoModeWin32(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 _glfwGetHMONITORContentScaleWin32(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 _glfwFreeMonitorWin32(_GLFWmonitor* monitor)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwGetMonitorPosWin32(_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 _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
_glfwGetHMONITORContentScaleWin32(monitor->win32.handle, xscale, yscale);
|
||||
}
|
||||
|
||||
void _glfwGetMonitorWorkareaWin32(_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* _glfwGetVideoModesWin32(_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*) _glfw_realloc(result, size * sizeof(GLFWvidmode));
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
result[*count - 1] = mode;
|
||||
}
|
||||
|
||||
if (!*count)
|
||||
{
|
||||
// HACK: Report the current mode if no valid modes were found
|
||||
result = _glfw_calloc(1, sizeof(GLFWvidmode));
|
||||
_glfwGetVideoModeWin32(monitor, result);
|
||||
*count = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
DEVMODEW dm;
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
|
||||
if (!EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query display settings");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
mode->width = dm.dmPelsWidth;
|
||||
mode->height = dm.dmPelsHeight;
|
||||
mode->refreshRate = dm.dmDisplayFrequency;
|
||||
_glfwSplitBPP(dm.dmBitsPerPel,
|
||||
&mode->redBits,
|
||||
&mode->greenBits,
|
||||
&mode->blueBits);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
GLFWbool _glfwGetGammaRampWin32(_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 _glfwSetGammaRampWin32(_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);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return monitor->win32.publicAdapterName;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return monitor->win32.publicDisplayName;
|
||||
}
|
||||
|
||||
#endif // _GLFW_WIN32
|
||||
|
627
raylib/external/glfw/src/win32_platform.h
vendored
Normal file
627
raylib/external/glfw/src/win32_platform.h
vendored
Normal file
@ -0,0 +1,627 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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 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)
|
||||
|
||||
// Windows 10 Anniversary Update
|
||||
#define _glfwIsWindows10Version1607OrGreaterWin32() \
|
||||
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
||||
// Windows 10 Creators Update
|
||||
#define _glfwIsWindows10Version1703OrGreaterWin32() \
|
||||
_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
|
||||
|
||||
#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
|
||||
|
||||
// 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_
|
||||
|
||||
// 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
|
||||
|
||||
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);
|
||||
|
||||
#define GLFW_WIN32_WINDOW_STATE _GLFWwindowWin32 win32;
|
||||
#define GLFW_WIN32_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32;
|
||||
#define GLFW_WIN32_MONITOR_STATE _GLFWmonitorWin32 win32;
|
||||
#define GLFW_WIN32_CURSOR_STATE _GLFWcursorWin32 win32;
|
||||
|
||||
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
||||
#define GLFW_WGL_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;
|
||||
|
||||
// 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;
|
||||
GLFWbool keymenu;
|
||||
GLFWbool showDefault;
|
||||
|
||||
// Cached size used to filter out duplicate events
|
||||
int width, height;
|
||||
|
||||
// The last received cursor position, regardless of source
|
||||
int lastCursorPosX, lastCursorPosY;
|
||||
// The last received high surrogate when decoding pairs of UTF-16 messages
|
||||
WCHAR highSurrogate;
|
||||
} _GLFWwindowWin32;
|
||||
|
||||
// Win32-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryWin32
|
||||
{
|
||||
HINSTANCE instance;
|
||||
HWND helperWindowHandle;
|
||||
ATOM helperWindowClass;
|
||||
ATOM mainWindowClass;
|
||||
HDEVNOTIFY deviceNotificationHandle;
|
||||
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;
|
||||
// The window the cursor is captured in
|
||||
_GLFWwindow* capturedCursorWindow;
|
||||
RAWINPUT* rawInput;
|
||||
int rawInputSize;
|
||||
UINT mouseTrailSize;
|
||||
// The cursor handle to use to hide the cursor (NULL or a transparent cursor)
|
||||
HCURSOR blankCursor;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform);
|
||||
int _glfwInitWin32(void);
|
||||
void _glfwTerminateWin32(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 _glfwPollMonitorsWin32(void);
|
||||
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
||||
void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
|
||||
|
||||
GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyWindowWin32(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height);
|
||||
void _glfwSetWindowSizeLimitsWin32(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
|
||||
void _glfwSetWindowAspectRatioWin32(_GLFWwindow* window, int numer, int denom);
|
||||
void _glfwGetFramebufferSizeWin32(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
|
||||
void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, float* xscale, float* yscale);
|
||||
void _glfwIconifyWindowWin32(_GLFWwindow* window);
|
||||
void _glfwRestoreWindowWin32(_GLFWwindow* window);
|
||||
void _glfwMaximizeWindowWin32(_GLFWwindow* window);
|
||||
void _glfwShowWindowWin32(_GLFWwindow* window);
|
||||
void _glfwHideWindowWin32(_GLFWwindow* window);
|
||||
void _glfwRequestWindowAttentionWin32(_GLFWwindow* window);
|
||||
void _glfwFocusWindowWin32(_GLFWwindow* window);
|
||||
void _glfwSetWindowMonitorWin32(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
|
||||
GLFWbool _glfwWindowFocusedWin32(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowIconifiedWin32(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowVisibleWin32(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowMaximizedWin32(_GLFWwindow* window);
|
||||
GLFWbool _glfwWindowHoveredWin32(_GLFWwindow* window);
|
||||
GLFWbool _glfwFramebufferTransparentWin32(_GLFWwindow* window);
|
||||
void _glfwSetWindowResizableWin32(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowDecoratedWin32(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwSetWindowMousePassthroughWin32(_GLFWwindow* window, GLFWbool enabled);
|
||||
float _glfwGetWindowOpacityWin32(_GLFWwindow* window);
|
||||
void _glfwSetWindowOpacityWin32(_GLFWwindow* window, float opacity);
|
||||
|
||||
void _glfwSetRawMouseMotionWin32(_GLFWwindow *window, GLFWbool enabled);
|
||||
GLFWbool _glfwRawMouseMotionSupportedWin32(void);
|
||||
|
||||
void _glfwPollEventsWin32(void);
|
||||
void _glfwWaitEventsWin32(void);
|
||||
void _glfwWaitEventsTimeoutWin32(double timeout);
|
||||
void _glfwPostEmptyEventWin32(void);
|
||||
|
||||
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos);
|
||||
void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode);
|
||||
const char* _glfwGetScancodeNameWin32(int scancode);
|
||||
int _glfwGetKeyScancodeWin32(int key);
|
||||
GLFWbool _glfwCreateCursorWin32(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
||||
GLFWbool _glfwCreateStandardCursorWin32(_GLFWcursor* cursor, int shape);
|
||||
void _glfwDestroyCursorWin32(_GLFWcursor* cursor);
|
||||
void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||
void _glfwSetClipboardStringWin32(const char* string);
|
||||
const char* _glfwGetClipboardStringWin32(void);
|
||||
|
||||
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs);
|
||||
EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void);
|
||||
EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window);
|
||||
|
||||
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions);
|
||||
GLFWbool _glfwGetPhysicalDevicePresentationSupportWin32(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
|
||||
VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
||||
|
||||
void _glfwFreeMonitorWin32(_GLFWmonitor* monitor);
|
||||
void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||
void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor, float* xscale, float* yscale);
|
||||
void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
|
||||
GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count);
|
||||
GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||
GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
GLFWbool _glfwInitJoysticksWin32(void);
|
||||
void _glfwTerminateJoysticksWin32(void);
|
||||
GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode);
|
||||
const char* _glfwGetMappingNameWin32(void);
|
||||
void _glfwUpdateGamepadGUIDWin32(char* guid);
|
||||
|
||||
GLFWbool _glfwInitWGL(void);
|
||||
void _glfwTerminateWGL(void);
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
100
raylib/external/glfw/src/win32_thread.c
vendored
Normal file
100
raylib/external/glfw/src/win32_thread.c
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_THREAD)
|
||||
|
||||
#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)
|
||||
{
|
||||
_glfwInputError(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);
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_WIN32_THREAD
|
||||
|
53
raylib/external/glfw/src/win32_thread.h
vendored
Normal file
53
raylib/external/glfw/src/win32_thread.h
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
// 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
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define GLFW_WIN32_TLS_STATE _GLFWtlsWin32 win32;
|
||||
#define GLFW_WIN32_MUTEX_STATE _GLFWmutexWin32 win32;
|
||||
|
||||
// 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;
|
||||
|
54
raylib/external/glfw/src/win32_time.c
vendored
Normal file
54
raylib/external/glfw/src/win32_time.c
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_TIMER)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformInitTimer(void)
|
||||
{
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*) &_glfw.timer.win32.frequency);
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
uint64_t value;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
return _glfw.timer.win32.frequency;
|
||||
}
|
||||
|
||||
#endif // GLFW_BUILD_WIN32_TIMER
|
||||
|
43
raylib/external/glfw/src/win32_time.h
vendored
Normal file
43
raylib/external/glfw/src/win32_time.h
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
// 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
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define GLFW_WIN32_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32;
|
||||
|
||||
// Win32-specific global timer data
|
||||
//
|
||||
typedef struct _GLFWtimerWin32
|
||||
{
|
||||
uint64_t frequency;
|
||||
} _GLFWtimerWin32;
|
||||
|
2594
raylib/external/glfw/src/win32_window.c
vendored
Normal file
2594
raylib/external/glfw/src/win32_window.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1172
raylib/external/glfw/src/window.c
vendored
Normal file
1172
raylib/external/glfw/src/window.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user